Here is some description quoted from Wiki
The Linux kernel provides preemptive scheduling under certain conditions. Until kernel version 2.4, only processes were preemptive, i.e. in addition to time quantum expiration, an execution of current process in user mode would be interrupted if higher dynamic priority processes entered TASK_RUNNING state. Towards Linux 2.6, an ability to interrupt a task executing kernel code was added, although with that not all sections of the kernel code can be preempted.
Then it also says this,
Preemption improves latency, increases responsiveness, and makes Linux more suitable for desktop and real-time applications. Older versions of the kernel had a so-called big kernel lock for synchronization across the entire kernel. This was finally removed by Arnd Bergmann in 2011
So does the above statement hold true for the current linux kernel that kernel preemption is conditional? e.g. if a process is trapped into kernel mode by making a system call, this process will not be under preemptive scheduling?
Where can I find some up-to-date introduction articles/books about linux scheduling in both user mode and kernel mode?
If it is set and preemption is enabled, kernel calls schedule() where a new process is selected to run. Actually, whenever an interrupt occurs(even other than timer interrupt), the kernel checks whether current process can be preempted or not and calls schedule() accordingly.
Linux uses a Completely Fair Scheduling (CFS) algorithm, which is an implementation of weighted fair queueing (WFQ). Imagine a single CPU system to start with: CFS time-slices the CPU among running threads.
The part of the kernel, which is responsible for granting CPU time to tasks, is called process scheduler. A scheduler chooses the next task to be run, and maintains the order, which all the processes on the system should be run in, as well.
The scheduler will be invoked if the current thread/process is going to sleep/wait for some event/resource to be released. In one of the cases of worker threads which executes the bottom half in the form of workqueues, it will run in a while loop and check if the workqueue list is empty.
Of course kernel preemption is conditional. You would not want the kernel to switch tasks while holding an exclusive lock or while writing to time-sensitive hardware registers in a device driver.
However, the Linux kernel does its best to minimize these conditions in order to make preemption happen as quickly as it can.
Note that this in-kernel preemption is only compiled into the kernel when the compile option CONFIG_PREEMPT is yes. There is also CONFIG_PREEMPT_VOLUNTARY which only does task switching when the kernel explicitly checks for it.
Kernel preemption comes with a cost. Rapidly switching tasks requires doing a lot of mostly wasted housekeeping work instead of actual work. This slows down the whole system and results in less work being done. That is why these compile options exist. A Linux kernel built for a database or web server should not use preemption at all. A kernel built for HPC is sometimes modified to only switch tasks once a second, or less.
That all changes for real-time tasks. These tasks rely on reacting quickly and within a reliable timeframe. The default Linux kernel is pretty good at this, but there is a patch set called the "-rt patches" that makes it really good. The patch set does all sorts of things like prioritize interrupt handlers and change kernel locks so that locks can be dropped and restarted later.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With