Description of problem: chrt 改变进程调度策略失败 Version-Release number of selected component (if applicable): [root@iZbp14ub0x084rkaiux0krZ test-results]# cat /etc/os-release NAME="Anolis OS" VERSION="23" ID="anolis" VERSION_ID="23" PLATFORM_ID="platform:an23" PRETTY_NAME="Anolis OS 23" ANSI_COLOR="0;31" HOME_URL="https://openanolis.cn/" BUG_REPORT_URL="https://bugzilla.openanolis.cn/" [root@iZbp14ub0x084rkaiux0krZ test-results]# uname -a Linux iZbp14ub0x084rkaiux0krZ 5.10.134-12.1.an23.x86_64 #1 SMP Thu Oct 13 11:38:24 CST 2022 x86_64 GNU/Linux How reproducible: [root@iZbp14ub0x084rkaiux0krZ test-results]# sleep 10000 & [1] 119540 [root@iZbp14ub0x084rkaiux0krZ test-results]# chrt -rr --pid 1 119540 chrt: failed to set pid 119540's policy: Operation not permitted [root@iZbp14ub0x084rkaiux0krZ test-results]# chrt -v -p 119540 pid 119540's current scheduling policy: SCHED_OTHER pid 119540's current scheduling priority: 0 [root@iZbp14ub0x084rkaiux0krZ test-results]# rpm -q util-linux util-linux-2.38~rc4-2.an23.x86_64 Steps to Reproduce: 同上 Actual results: 修改失败 Expected results: 修改成功 Additional info: 早期23版本执行成功: [root@iZbp12nj7zzd2hcr70xlilZ ~]# sleep 10000 & [1] 124870 [root@iZbp12nj7zzd2hcr70xlilZ ~]# chrt -rr --pid 1 124870 [root@iZbp12nj7zzd2hcr70xlilZ ~]# chrt -v -p 124870 pid 124870's current scheduling policy: SCHED_RR pid 124870's current scheduling priority: 1 [root@iZbp12nj7zzd2hcr70xlilZ ~]# uname -a Linux iZbp12nj7zzd2hcr70xlilZ 5.17.0-1.an23.x86_64 #1 SMP PREEMPT Tue Apr 12 16:43:09 CST 2022 x86_64 GNU/Linux [root@iZbp12nj7zzd2hcr70xlilZ ~]# rpm -q util-linux util-linux-2.38~rc4-2.an23.x86_64
这应该是内核的一个bug。通过 strace 和 crash 分析的结果是这样的: strace 查到返回的结果是 -EPERM,对应到 sched_setscheduler 系统调用,是在下面的 if 返回了这个值: if (rt_bandwidth_enabled() && rt_policy(policy) && task_group(p)->rt_bandwidth.rt_runtime == 0 && !task_group_is_autogroup(task_group(p))) { retval = -EPERM; goto unlock; } 通过 crash 分析: 1. 系统中 /proc/sys/kernel/sched_rt_runtime_us 这个值为 950000,说明 if 中的 rt_bandwidth_enabled() 为真; 2. 系统调用传入的参数是 SCHED_RR,rt_policy(policy) 为真; 3. crash 看到进程所在的 task_group 中的 rt_bandwidth.rt_runtim 为 0,第三个条件也为真; 4. 经过 crash 分析task_group_is_autogroup(task_group(p)) 同样为真。 由于开启了 CONFIG_RT_GROUP_SCHED,会给 task_group 分配 rt_bandwidth,且 rt_runtime 默认为 0,则新建的 cgroup 所对应的 task_group 的 rt_runtime 是 0,因此会返回 -EPERM 错误。 然而,cgroup v2 并没有提供设置 rt_runtime_us 的接口(v1 提供了),因此无法通过设置该值来修复它。 而内核调度器的处理逻辑似乎也没有处理这种情况,现在看 upstream 代码也是这样。接下来我会拿 upstream 最新代码来做进一步验证。 目前可以通过设置:echo -1 > /proc/sys/kernel/sched_rt_runtime_us 的方法暂时避开这个问题。
anolis 23 早期的 5.19 内核因为关闭了该 CONFIG,所以没有出现这个问题。
经过验证,upstream 最新代码 6.1 同样会有这个问题: 在 anolis23 中,有两个配置: 1. /proc/sys/kernel/sched_autogroup_enable 为 0; 2. cgroup V2 中,user.slice cgroup 的 controller 配置为 cpuset cpu io memory pids 分析过程如下: 1. 当 sched_autogroup_enable 为 0 时,会导致 !task_group_is_autogroup 判断条件为真; 2. 这一点相对比较复杂:cgroup v2 中,task 的 task group 是第一个设置了 cpu controller 的 cgroup,举一个例子,一个 task 的 cgroup 拓扑如下:0::/user.slice/user-0.slice/session-xx.scope,但是这几个 node 的 controller 没有设置 cpu(root cgroup 中设置了 cpu),因此该 task 的 task_group 是 root_task_group,那么此时 task_group 中的 rt_bandwidth.rt_runtime 是系统默认的值(/proc/sys/kernel/sched_rt_runtim_us,anolis23 中为 9500000),而中间节点的 task_group 中的这个数值默认为 0。因此,如果中间节点配置了 cpu controller(anolis23 中就配置了),那么 rt_bandwidth.rt_runtim 必为 0,因为 cgroup v2 中没有提供设置 rt_runtime 的接口。 所以,满足这两个配置的,会出现 chrt 失败。这应该是内核没有很好的处理这种情况,导致出现了这个问题。
社区 maintainer 似乎不想在 cgroup v2 中提供 rt bandwidth 的接口,有人提过这个相关的 patch:https://lore.kernel.org/lkml/20220622015557.7497-1-zhouchengming@bytedance.com/t/
cgroup v2 上社区无计划支持 rt bandwitdh
*** Bug 8879 has been marked as a duplicate of this bug. ***