Linux用户空间和内核空间调度

3
我有一个使用SCHED_OTHER(0)调度策略和优先级为120(默认优先级,top显示PR为20)的用户空间进程。它在一个无限循环中运行while(1),没有任何系统调用或等待等。它绑定到特定的CPU上,比如CPU 1。
在内核空间中,我有一个内核线程也是用默认调度参数创建的(策略:SCHED_NORMAL(0),优先级为120)。它通过调用wait_event_interruptible()进入睡眠状态。一个中断线程以周期性方式唤醒内核线程,比如每1毫秒唤醒一次。内核线程没有绑定到任何CPU上。
如果内核线程被调度到与用户空间进程相同的CPU上,即使已经调用唤醒,它也不会被唤醒。但是如果内核线程被调度到其他空闲的CPU上,它会被唤醒。只有当内核定时器中断发生并且ksoftirq线程被调度并退出时,它才会调度内核线程。因此,内核线程无法按预期每1毫秒唤醒一次。
我期望内核线程通过抢占用户空间进程而被唤醒,但事实并非如此。请问有人能帮助我解决这个问题吗?
顺便提一下,如果我将内核线程的调度方式更改为SCHED_FIFO并给予RT优先级,则可以正常工作。
1个回答

0
首先,SCHED_OTHERSCHED_NORMAL 的别名。其次,调度程序不区分内核线程和用户空间线程(除非涉及 CGroups 的分层调度)。
唯一的机会是让睡眠线程抢占 CPU 绑定线程,就是如果它在 CPU 上花费的时间更少(通过 vruntime 跟踪),但 1ms 似乎是太小的时间间隔,无法使此效果显著,即 CFS 中计算时间片的基础是 6ms(sysctl_sched_latency)。
您可以尝试使用 cfstrace.stp 脚本(需要 SystemTap)跟踪调度程序状态,并尝试理解为什么会发生这种情况(它将转储包括 vruntime 值在内的 CFS 内部状态)。

我将内核线程的调度更改为 SCHED_FIFO 并赋予 RT 优先级,它可以正常工作。

是的,如果你需要“实时”,你需要使用 SCHED_FIFO 或者 SCHED_DEADLINE


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接