测试代码如下
#include <sched.h>
#include <stdio.h>
#include <errno.h>
void main()
{
struct sched_param params;
params.sched_priority = sched_get_priority_max(SCHED_FIFO);
printf("max pri=%d\n\r",params.sched_priority);
if (sched_setscheduler(getpid(), SCHED_FIFO, ¶ms)) {
printf("sched set pri error errno=%d\n\r",errno);
}
return;
}
gcc编译生成可执行程序copy到qemu虚拟机上执行报错,即使是root用户执行也是报错,strace跟踪发现报错 errno=EPERM(1): Operation not permitted。调试查看内核代码(5.2版本)发现kernel/sched/core.c __sched_setscheduler函数的如下位置返回
#ifdef CONFIG_RT_GROUP_SCHED
/*
* Do not allow realtime tasks into groups that have no runtime
* assigned.
*/
if (rt_bandwidth_enabled() && rt_policy(policy) &&
task_group(p)->rt_bandwidth.rt_runtime == 0 &&
!task_group_is_autogroup(task_group(p))) {
task_rq_unlock(rq, p, &rf);
return -EPERM;
}
#endif
task_group(p)->rt_bandwidth.rt_runtime == 0 条件为真,进一步分析,此处对应/sys/fs/cgroup/cpu/user.slice/cpu.rt_runtime_us,将cpu.rt_runtime_us修改为非0,不再报错。cgroup user.slice是由systemd创建的。
参考:
https://access.redhat.com/discussions/2950611
https://github.com/coreos/bugs/issues/410
https://juejin.im/post/6844903858116755463#heading-1
https://github.com/moby/moby/issues/13983