Skip to content
Advertisement

Linux default scheduler alternatives

The Linux kernel implements the Completely Fair Scheduling (SCHED_NORMAL) algorithm as its default scheduling algorithm for scheduling real-time processes.

How to modify the linux kernel such that the default scheduling policy is set to round-robin (SCHED_RR) or any other scheduling policy ? Is there a generic way to do so ? What files need to be exactly changed here ?

I’m working on Ubuntu 16.04.

Advertisement

Answer

By all means, please tell me this is just an experiment 🙂 I really can’t see anything good coming out of trying such heresy.

That said, here’s my try at it. First of all, we need to get a sandbox. I’ve used User Mode Linux (UML). For the kernel, I grabbed a random 4.10.0-rc1 repo, but any version would do. For the rootfs, the UML page provides a bunch of them here (pitfall: not all of them work fine).

Steps to build the kernel are quite short:

export ARCH=um
make x86_64_defconfig
make

If you got the Slackware rootfs, you can now run as:

 ./vmlinux ubda=./Slamd64-12.1-root_fs

OK, cool. So we have a safe place to break some kernels. Let’s get to it. As you probably know, the init (pid=1) is the first process and the parent of all the other processes. RT scheduling class is inherited (unless asked otherwise with a flag, see SCHED_RESET_ON_FORK in man 7 sched). This means we might change the scheduling class for the init process and get its children to inherit the scheduling class by default.

This is easily doable with something like this:

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();

And it works!

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

(By the way, SCHED_DEADLINE cannot be inherited, as noted in man 7 sched).

Advertisement