10

this is from sched_setscheduler(2) - Linux man page:

"Processes scheduled under one of the real-time policies (SCHED_FIFO, SCHED_RR) have a sched_priority value in the range 1 (low) to 99 (high)."

"A SCHED_FIFO process runs until either it is blocked by an I/O request, it is preempted by a higher priority process, or it calls sched_yield(2)."

I have the following code:

struct sched_param sp;
memset( &sp, 0, sizeof(sp) );
sp.sched_priority = 99;
sched_setscheduler( 0, SCHED_FIFO, &sp );

Now the process should be running under the highest possible priority (99) and should never be preempted.

So, when it starts running the following loop:

while ( 1 ) ;

it should be running forever and no other process should be allowed to run.

In spite of this, when I start such a process, I can use other processes too. Other processes run much slower, but they DO run.

My processor has 2 cores, so I started two copies of the process. Usage of both cores jumped to 97%-100%. Both processes were running their infinite loop.

I could still type commands in a shell and watch their output. I could use GUI programs as well.

How's that possible since a SCHED_FIFO process with a priority of 99 should never be preempted?

Piotr S
  • 95
  • 1
  • 1
  • 4

1 Answers1

13

If you haven't changed any other policy settings, then you're likely getting throttled. See this informative article on the real-time limits added to the scheduler a few years back.

The gist of it is: Unprivileged users can use SCHED_FIFO and try to soak the CPU, but the RT limits code will force a little bit of SCHED_OTHER in anyway so you don't wedge the system. From the article:

Kernels shipped since 2.6.25 have set the rt_bandwidth value for the default group to be 0.95 out of every 1.0 seconds. In other words, the group scheduler is configured, by default, to reserve 5% of the CPU for non-SCHED_FIFO tasks.

Joe Z
  • 17,413
  • 3
  • 28
  • 39
  • 2
    Thank you for the answer. I run the process as root. I also found the following files: /proc/sys/kernel/sched_rt_period_us containing 1000000 and /proc/sys/kernel/sched_rt_runtime_us containing 950000. I wrote 1000000 to sched_rt_runtime_us, but it didn't change anything. SCHED_FIFO processes are still preempted. – Piotr S Dec 21 '13 at 19:41
  • So, when you wrote 1000000 to it, did you read it back and ensure it changed? (edit: I tried it locally and it does change it appropriately.) – Joe Z Dec 21 '13 at 19:43
  • Yes. They both contain 1000000 now. – Piotr S Dec 21 '13 at 19:45
  • It looks like Peter Zijlstra's patch uses -1 to mean "unlimited". Does that do the trick for you? (I've tested that you can set it to -1, but I'm unwilling to test that I can crash my box.) – Joe Z Dec 21 '13 at 19:46
  • I get an error "Invalid argument" whenever I want to write -1 to /proc/sys/kernel/sched_rt_period_us – Piotr S Dec 21 '13 at 19:55
  • Reported where, syslog or similar? And on what kernel? I'm actually on a somewhat ancient system here (2.6.35, Ubuntu 10.10). – Joe Z Dec 21 '13 at 19:58
  • 3
    Ok, I looked in the kernel source, and it should be allowing you to set -1 with `echo -1 > /proc/srs/kernel/sched_rt_runtime_us`. The `sched_rt_global_constraints()` function specifically tests for `RUNTIME_INF`, which is defined as `~0ULL`. (Link: http://lxr.linux.no/#linux+v3.12.6/kernel/sched/core.c#L7021 ) – Joe Z Dec 21 '13 at 20:01
  • 5
    I rebooted the system and now I could write -1 with no error. Previously it was reported in bash after issuing 'echo' or 'cat' as a write error. And WOW! Now everything is working as it should! The process seems to be eating 100% CPU. I can't even move the mouse cursor. Thanks! :) – Piotr S Dec 21 '13 at 20:14
  • I'm glad I could help hose your system. :-) – Joe Z Dec 21 '13 at 20:21
  • I was running this one on Virtual Box :) – Piotr S Dec 21 '13 at 20:30
  • Ah, that's much more convenient to reboot. – Joe Z Dec 21 '13 at 23:11