Linux默认调度程序替代方案

时间:2017-01-31 12:02:17

标签: linux ubuntu linux-kernel scheduler

Linux内核将Completely Fair Scheduling (SCHED_NORMAL)算法实现为用于调度实时进程的默认调度算法。

如何修改linux内核,使默认调度策略设置为round-robin (SCHED_RR)或任何其他调度策略?有通用的方法吗?这里需要准确更改哪些文件?

我正在使用Ubuntu 16.04。

2 个答案:

答案 0 :(得分:2)

无论如何,请告诉我这只是一个实验:)我真的看不出任何有关这种异端邪说的好事。

那就是说,这是我的尝试。首先,我们需要一个沙盒。我使用过用户模式Linux(UML)。对于内核,我抓了一个随机的4.10.0-rc1 repo,但任何版本都可以。对于rootfs,UML页面提供了一堆here(陷阱:并非所有这些都能正常工作)。

构建内核的步骤很短:

export ARCH=um
make x86_64_defconfig
make

如果你有Slackware rootfs,你现在可以运行:

 ./vmlinux ubda=./Slamd64-12.1-root_fs
好的,很酷。所以我们有一个安全的地方打破一些内核。我们来吧。您可能知道,init(pid = 1)是第一个进程,也是所有其他进程的父进程。 RT调度类是继承的(除非用标志另有要求,请参阅man 7 sched中的SCHED_RESET_ON_FORK)。这意味着我们可能会更改init进程的调度类,并让其子进程默认继承调度类。

这很容易做到这样:

diff --git a/init/main.c b/init/main.c
index b0c9d6facef9..015f72b318ef 100644
--- a/init/main.c
+++ b/init/main.c
@@ -951,8 +951,11 @@ static inline void mark_readonly(void)

 static int __ref kernel_init(void *unused)
 {
+       struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
        int ret;

+       /* Sit tight and fasten your seat belt! */
+       sched_setscheduler_nocheck(current, SCHED_FIFO, &param);
        kernel_init_freeable();
        /* need to finish all async __init code before freeing the memory */
        async_synchronize_full();

它有效!

root@darkstar:~# sleep 60 &
[1] 549
root@darkstar:~# ps -c
  PID CLS PRI TTY          TIME CMD
  536 FF  139 tty0     00:00:00 bash
  549 FF  139 tty0     00:00:00 sleep
  550 FF  139 tty0     00:00:00 ps

(顺便说一句,SCHED_DEADLINE不能继承,如man 7 sched中所述)。

答案 1 :(得分:0)

我查看了内核代码,SCHED_NORMAL实际上是在几个地方进行了硬编码,例如https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/kernel/sched/core.c#n2394

有可能在所有地方将其更改为SCHED_RR,但正如评论中所写,不建议这样做。它可能会使系统崩溃,例如,长时间运行的计算会阻塞CPU。