首先,让我介绍一下我想要实现的目标的背景。我知道如何使用启动参数(isolcpu 和 nohz_full;内务子系统设置)隔离特定 CPU。
但根据我的要求,我需要在系统启动后隔离CPU。因此,根据许多文章,我尝试使用cpuset
子系统隔离特定的 CPU,如下所示:
我使用的硬件有 16 个 cpu。 (0-15)。所以,我决定隔离CPU 0。
$ cd /cpusets
$ mkdir housekeeping
$ mkdir isolate
$ echo 1-15 > housekeeping/cpus
$ echo 0 > mems
$ echo 0 > isolated/cpus
$ echo 0 > isolated/mens
$ echo 0 > cpuset.sched_load_balance
$ echo 0 > isolated/sched_load_balance
$ while read P ; do echo $P > housekeeping/tasks ; done < tasks
这将处理器0
与所有其他处理器隔离。但是当我尝试使用taskset
以下命令将进程分配给处理器 0 时:
/******loop.c**********/
int main(){
int i;
for(i=0;;i++);
return 0;
}
$ gcc -o loop.c loop
$ taskset -c 0 ./loop
taskset: failed to set pid 2755250's affinity: Invalid argument
除了将 pid 回显到隔离/任务之外2755250
,是否可以设置新进程与隔离 CPU 的亲和力0
?
我哪里出错了?
答案1
taskset
将会通知sched_setaffinity如果
关联位掩码 mask 不包含当前物理上位于系统上的处理器并根据 cpuset cgroups 或“cpuset”机制可能施加的任何限制允许线程使用cpuset(7) 中描述。
至于为什么使用引导参数时行为不同isolcpus=
,请在内核文档 ( Documentation/admin-guide/kernel-parameters.txt
) 中注意,这可以在运行时被 CPU 亲和力系统调用覆盖
您可以通过 CPU 关联性系统调用或 cpuset 将进程移入或移出“隔离”CPU。
相反,人CPU集会告诉您,如果 sched_setaffinity 的设置发生冲突,则会强制执行 cpuset 放置。
CPUset 与内核中的 sched_setaffinity(2) 调度关联机制以及 mbind(2) 和 set_mempolicy(2) 内存放置机制集成。这些机制都不允许进程使用该进程的 cpuset 不允许的 CPU 或内存节点。如果对进程的 cpuset 放置的更改与这些其他机制发生冲突,则将强制执行 cpuset 放置,即使这意味着覆盖这些其他机制。内核通过默默地将这些其他机制请求的 CPU 和内存节点限制为调用进程的 cpuset 允许的 CPU 和内存节点来完成此覆盖。这可能会导致这些其他调用返回错误,例如,如果此类调用最终请求一组空的 CPU 或内存节点,而该请求仅限于调用进程的 cpuset。
顺便说一句:还请注意(在内核文档中)isolcpus=
引导参数已被弃用。