SCHED_FIFO process with priority of 99 gets preempted? - linux

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?

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.

Related

Do two SCHED_FIFO tasks with equal priority get processing time within each period in Linux?

Do two SCHED_FIFO tasks with equal priority get processing time within each period in Linux, granted neither of the tasks finish before the period ends?
Linux documentation says SCHED_FIFO processes can get preempted only by processes with higher priority, but my understanding is that CFS operates on a higher layer, and assigns timeslots to each of the two tasks within each period.
Linux documentation says SCHED_FIFO processes can get preempted only by processes with higher priority
This is correct, in addition to this, they can also be preempted if you set RLIMIT_RTTIME (getrlimit(2)) and that limit is reached.
The only other reasons why another SCHED_FIFO process (with the same priority) can be scheduled is if the first sleeps or if it voluntary yields (voluntary preemption).
CFS has nothing to do with SCHED_FIFO, it only takes care of SCHED_NORMAL, SCHED_BATCH and SCHED_IDLE.

SCHED_FIFO higher priority thread is getting preempted by the SCHED_FIFO lower priority thread?

I am testing my multithreaded application in Linux RT multicore machine.
However during testing, we are observing that scheduling (created with SCHED_FIFO scheduling policy ) in Linux RT is not happening according to the SCHED_FIFO policy.
We could see in multiple places that the higher priority thread execution is getting preempted by a lower priority thread.
Based on some research we did on the internet, we found that the following kernel parameters need to be changed from
/proc/sys/kernel/sched_rt_period_us containing 1000000
/proc/sys/kernel/sched_rt_runtime_us containing 950000
to
/proc/sys/kernel/sched_rt_period_us containing 1000000
/proc/sys/kernel/sched_rt_runtime_us containing 1000000
or
/proc/sys/kernel/sched_rt_period_us containing -1
/proc/sys/kernel/sched_rt_runtime_us containing -1
We tried doing both but still we are facing the problem sometimes. We are facing the issue even when higher priority thread is not suspended by any system call.
It would be great if you could let us know if you are aware of such problems in Linux RT scheduling and/or have any solutions to make the Linux RT scheduling deterministic based on priority.
There are no printfs or any system calls in the higher priority thread but still the higher priority thread is getting preempted by the lower priority thread.
Also I have made sure all the threads in the process are running on a single core using taskset command.
There could be two reasons:
CPU throttling: the scheduler is designed to reserve some CPU time to non-RT tasks; you have already disabled it by acting on the /proc/sys/kernel/ entries
blocking: your high-priority task is blocking either
on some synchronization mechanism (e.g., mutex, semaphore) or
on some blocking call (e.g., malloc, printf, read, write, etc.)

what is the difference among three priorities used in Linux kernel?

I am new to Linux kernel and right now i am studying about Process Scheduling in Linux kernel . There are three types of priorities in Linux :
Static priority
Dynamic priority
Real time priority
Now what i have understood is that :
Static priority and Dynamic priority are defined only for Conventional processes and they can take value from 100 to 139 only.
Static priority is used to determine base time slice of a process
Dynamic priority is used to select a process to be executed next.
Real time priorities are defined only for Real time processes and it's value can range from 0 to 99
Now my questions are :
Correct me if i am wrong and please also tell me why we are using
three types of priorities in Linux and what are the differences
among these priorities?
Are the processes are differentiated as Real time or Conventional on the basis of priorities that is if priority is between 100 to 139
then processes are Conventional processes otherwise Real time
processes?
How the priorities are changed in Linux , i mean , we know that priority of a process does not remain constant through out the execution ?
Disclaimer: Following is true for scheduling in linux (I am not sure about windows or other OS). Thread and process has been used interchangeably here, althogh there is a difference in between them.
Priorities & differences
1.Static priority: These are the default priorities (value 0 for conventional processes aka non-real time processes ie when real time scheduling is not used) set while creating a new thread. You can change them using:
`pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param);`
where, sched_param contains the priority:
struct sched_param
{
int sched_priority; /* Scheduling priority */
};
2 Dynamic priority: When threads start to starve because higher priority threads being scheduled all the time, there becomes a need to raise the priority of such a thread using various mechanisms. This raised/lowered (yes, this happens too) priority is known as the dynamic priority because it keeps on changing. In Linux, even the fat kid gets to play.
3.Real time priority: This comes into picture only when threads (processes) are scheduled under one of the real-time policies (SCHED_FIFO, SCHED_RR) and have a sched_priority value in the range 1 (low) to 99 (high). This is the highest in comparison to the static/dynamic priorities of non real time processes.
More information: http://man7.org/linux/man-pages/man3/pthread_getschedparam.3.html
Now, to your questions:
Correct me if i am wrong and please also tell me why we are using three types of priorities in Linux and what are the differences among
these priorities?
So, for non-real time scheduling policies, every process has some static priorities, a higher priority gives the thread a kick-start, and later to avoid any injustice, the priority is boosted/lowered which becomes the dynamic priority.
Are the processes are differentiated as Real time or Conventional on the basis of priorities that is if priority is between 100 to 139
then processes are Conventional processes otherwise Real time
processes?
Not really, it depends upon the scheduling mechanism in place.
How the priorities are changed in Linux , i mean , we know that priority of a process does not remain constant through out the
execution ?
That's when the dynamicness comes into picture. Read about the "nice value" in the given links.

Process & Threads states after termination / blocked

Say I have a running process with 2 running threads, what happen to the threads if the process is terminated? do they get terminated as well?
Also, what happen to the threads if the process is 'losing' the CPU attention (Other process took the CPU's attention) and therefore the process is in waiting state / suspended. Do its threads keep running? or?
thanks
Yes, the threads get disposed of by the operating system if and when the process terminates and gets cleaned up.
The threads in a process are scheduled according to their priority. In most OSes that is fairly straight forward, it's a simple matter of the higher priority threads winning. Windows does something different, a process's priority is adjusted by Windows according to whether it is the foreground process. Thus the process's threads' priorities are also adjusted...

real time scheduling in Linux

This morning I read about Linux real time scheduling. As per the book 'Linux system programming by Robert Love', there are two main scheduling there. One is SCHED_FIFO, fifo and the second is SCHED_RR, the round robin. And I understood how a fifo and a rr algorithm works. But as we have the system call,
sched_setscheduler (pid_t pid, int policy, const struct sched_parem *sp)
we can explicitly set the scheduling policy for our process. So in some case, two process running by root, can have different scheduling policy. As one process having SCHED_FIFO and another having SCHED_RR and with same priority. In that case, which process will be selected first? the FIFO classed process or the RR classed process? Why?
Consider this case. There are three process A,B,C. All are having same priority. A and B are RR classed processes and C is FIFO classed one. A and B are runnable (so both are running alternatively in some time intervel). And currently A is running. Now C becomes runnable. In this case, whether
1. A will preempt for C, or
2. A will run until its timeslice goes zero and let C run. Or
3. A will run until its timeslice goes zero and let B run.
a) here after B runs till its timeslice becomes zero and let C run or
b) after B runs till its timeslice becomes zero and let A run again (then C will starve untill A and B finishes)
In realtime scheduling, FIFO and RR do not have exactly the same meaning they have in non-realtime scheduling. Processes are always selected in a FIFO- manner, however, the time quantum for SCHED_FIFO is not limited unlike the time quantum for SCHED_RR.
SCHED_FIFO processes do not preempt SCHED_RR processes of the same priority.
sched_setscheduler(2) - Linux man page
...
"A process's scheduling policy determines where it will be inserted into the list of processes with equal static priority and how it will move inside this list. All scheduling is preemptive: if a process with a higher static priority becomes ready to run, the currently running process will be preempted and returned to the wait list for its static priority level. The scheduling policy only determines the ordering within the list of runnable processes with equal static priority."
...
"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)."
...
"When a SCHED_FIFO process becomes runnable, it will be inserted at the end of the list for its priority."
...
"SCHED_RR: Round Robin scheduling
SCHED_RR is a simple enhancement of SCHED_FIFO. Everything described above for SCHED_FIFO also applies to SCHED_RR, except that each process is only allowed to run for a maximum time quantum. If a SCHED_RR process has been running for a time period equal to or longer than the time quantum, it will be put at the end of the list for its priority. A SCHED_RR process that has been preempted by a higher priority process and subsequently resumes execution as a running process will complete the unexpired portion of its round robin time quantum."
man sched_setscheduler explains these scheduling policies in detail.
In this particular case because the two real-time processes have the same priority none of them will preempt the other. A SCHED_FIFO process runs until it blocks itself, SCHED_RR process runs until it blocks itself or its time quantum expires.
According to the man page, I think 1 is the answer. A, B are RR policy, C is FIFO policy. Since RR is also an enhancement FIFO, all of them are FIFO class.
Since all of them have the same priority, and man page say " A call to sched_setscheduler() or sched_setparam(2) will put the SCHED_FIFO (or SCHED_RR) process identified by pid at the start of the list if it was runnable. As a consequence, it may preempt the currently running process if it has the same priority. (POSIX.1-2001 specifies that the process should go to the end of the list.)"
Once calling sched_setscheduler to set the policy of C as FIFO, C will preempt A.
My understanding of the two different classes is that a process SCHED_FIFO is never pre-empted by the kernel. Even if another "SCHED_FIFO" class process is waiting its turn...
While SCHED_RR policy shares the cpu ressources a little bit more. The scheduler will let the SCHED_RR process run for a quanta of time, then pre-empt it only to let turn another SCHED_RR process. That is exactly Round Robin.
SCHED_FIFO is "stronger" in the sense that if a SCHED_FIFO process never yield() to the kernel or invoke a system call on a single core device, then all your other Real time processes may never run.

Resources