内核仍然安排代码在隔离的核心上运行

Mar*_*ark 6 virtualization multithreading multicore kvm linux-kernel

我有一个运行 Linux 内核 4.19.71 和Intel Xeon Platinum 8160CPU 的系统,它有 24 个物理核心,每个核心有 2 个线程,它有 48 个逻辑核心。我正在尝试虚拟化(qemukvm),并且希望将一组核心与操作系统和虚拟机管理程序隔离,以便这些核心只运行应用程序代码。所以我添加了isolcpus=内核指令:

isolcpus=1-23,25-47
Run Code Online (Sandbox Code Playgroud)

但是我仍然看到一些内核线程被安排在我隔离的核心上,例如:

# ps -A -L -o pid,nlwp,tid,c,psr,comm |sort -n -k 5 | grep 27
  148    1   148  0  27 kworker/27:0-mm_percpu_wq
  149    1   149  0  27 kworker/27:0H-events_highpri
  267    1   267  0  27 kworker/27:1-mm_percpu_wq
  799    1   799  0  27 kworker/27:1H-events_highpri
...
#
Run Code Online (Sandbox Code Playgroud)

第 5 列是处理器(核心)id,在本例中为 27,根据isolcpus=上面的说法,它不应受到内核的干扰,但它在那里运行 kworker 线程。

这是否意味着存在异常并且内核仍然可以在隔离的核心上安排任务,或者我遗漏了一些明显的东西?

谢谢。

kap*_*ick 1

我也在研究这个问题,但还没有找到一种方法来阻止这些内核线程在隔离的 CPU 集上进行调度。

RedHat的文档来看,这似乎也不可行。

隔离 CPU
您可以使用 isolcpus 引导参数将一个或多个 CPU 与调度程序隔离。这可以防止调度程序在此 CPU 上调度任何用户空间线程。

isolcpus我一直在使用和的组合,cset shield以防止大多数内核的内务线程在我的独立 CPU 中进行调度。

我使用它perf sched来记录 CPU 上的上下文切换并perf map可视化它们。

在第一个实验中,仅使用了cset shield.

$ grep -e '=>' exp_1.sch
        *A0 445210.783227 secs A0 => kworker/11:1-ev:165
        *.  445210.783275 secs .  => swapper:0
        *B0 445210.783304 secs B0 => kworker/u24:4-e:130904
        *C0 445210.783420 secs C0 => WORKER2:160974
.   *D0  C0 445210.783844 secs D0 => kworker/10:0-ev:1672
*E0  .   C0 445210.784703 secs E0 => WORKER0:160969
*F0  .   C0 445210.789628 secs F0 => kworker/9:1-eve:163
 E0 *G0  .  445210.802886 secs G0 => WORKER1:160973
 E0 *H0  .  445210.811638 secs H0 => ksoftirqd/10:76
 E0 *I0  .  445210.939469 secs I0 => kworker/u24:2-e:158157
*J0  G0  .  445211.527639 secs J0 => ksoftirqd/9:70
 E0  G0 *K0 445212.087622 secs K0 => ksoftirqd/11:82
 E0 *L0  .  445212.347277 secs L0 => kworker/10:1H-k:277
*M0  I0  C0 445213.321971 secs M0 => kworker/u24:1-e:160121
 E0 *N0  .  445214.463593 secs N0 => migration/10:75
*O0  N0  .  445214.463597 secs O0 => migration/9:69
 O0  N0 *P0 445214.463598 secs P0 => migration/11:81
*Q0  G0  M0 445225.372366 secs Q0 => kworker/9:1H-kb:330
Run Code Online (Sandbox Code Playgroud)

在这里,您可能会看到我的工作负载线程 ( WORKER{0,1,2})、与 CPU [9-11] 对应的 kworker 线程 ( kworker/{9,10,11}:),以及其余的ksoftirqd/{9,10,11}:migration/{9,10,11}:kworker/u24“空闲”线程swapper

在第二个实验中,我使用了cset shieldwith isolcpus

$ grep -e '=>' exp_2.sch
*A0            1033.342241 secs A0 => WORKER0:3646
 A0     *B0    1033.342675 secs B0 => kworker/11:1-ev:165
 A0     *.     1033.342694 secs .  => swapper:0
 A0 *C0  .     1033.343470 secs C0 => WORKER1:3647
 A0  C0 *D0    1033.344634 secs D0 => WORKER2:3648
 A0 *E0  D0    1033.346306 secs E0 => kworker/10:1-ev:164
*F0  .   D0    1033.364736 secs F0 => kworker/9:1-eve:163
 A0 *G0  .     1036.433541 secs G0 => migration/10:75
*H0  G0  .     1036.433541 secs H0 => migration/9:69
 A0  G0 *I0    1036.433548 secs I0 => migration/11:81
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您只能看到WORKER{0,1,2}kworker/{9,10,11}migration/{9,10,11}任务swapper