我尝试阻止来自用户空间的特定隔离核心的中断,
所以我设置CPU亲和性:
cpu_set_t set;
CPU_ZERO(&set);
CPU_SET(2, &set);
assert(sched_setaffinity(getpid(),sizeof(set),&set)==0);
并使用iopl(3)
在用户空间执行特权指令cli/sti
:
iopl(3);
__asm__("cli;");
// busy looping for a while
__asm__("sti;");
有两个现象我无法解释:
1cli
实际上不能停止中断(至少不是所有中断),并且中断,例如LOC(本地定时器中断)不时出现;
我注意到持续的内核补丁阻止cli
在用户空间(参考),但这个结果可以在内核4.19.0中重现。
2 AFAIK,cli
只清除中断标志的CPU上的程序正在运行,但在实践中,我的整个系统卡住了,不响应我的鼠标或键盘。
(2): Linux内核的许多部分依赖于与其他内核的通信,包括RCU依赖于for each core: run_on(core)
之类的东西。(https://lwn.net/Articles/262464/)。当这个内核不响应其他内核发送的请求这个内核上的内核切换到某个任务,或者可能执行TLB关机的IPI时,任何这样做的内核代码都会卡住。
我不知道确切的事情会导致卡住,但我并不觉得奇怪的是,内核的其他部分正在等待一些依赖于从内核上听到的反馈,这阻碍了将键盘/鼠标事件获取到X服务器和用户空间的进程。(或者甚至是文本控制台?这可能会有更多的希望,更少的软件层。
或者一些键盘或鼠标中断总是有可能被分配到这个核心,而被忽略。
对于(1):您是否使能NMI看门狗,或其他NMI源?这可能会使内核在启用(其他?)中断的状态下暂时运行。
我在/etc/sysctl.d/99-local.conf
中使用kernel/nmi_watchdog = 0
来释放一个额外的性能计数器,但默认值是启用的。
(cli
不停止不可屏蔽中断,正如你从名字猜到的。)
除了那个猜测,我不知道为什么你仍然偶尔本地定时器中断;也许更熟悉现代x86中断的人会知道。
-
cli只屏蔽可屏蔽的中断。本地定时器中断不可屏蔽(NMI)。看这个https://www.tutorialspoint.com/microprocessor/microprocessor_8086_interrupts.htm
-
您可以尝试使用无tick - less操作的linux内核(CONFIG_NO_HZ_FULL=y)将本地计时器中断的数量减少到每秒1次。看这个https://docs.kernel.org/timers/no_hz.html