Process preemption

Understanding preemption and context switching is key to fully comprehending scheduling and the impact it has on the kernel in maintaining low latency and consistency. Every process must be preempted either implicitly or explicitly to make way for another process. Preemption might lead to context switching, which requires a low-level architecture-specific operation, carried out by the function context_switch(). There are two primary tasks that need to be done for a processor to switch its context: switch the virtual memory mapping of the old process with the new one, and switch the processor state from that of the old process to the new one. These two tasks are carried out by switch_mm() and switch_to().

Preemption can happen for any of the following reasons:

When a high-priority process becomes runnable. For this, the scheduler will have to periodically check for a high-priority runnable thread. On return from interrupts and system calls, TIF_NEED_RESCHEDULE (kernel-provided flag that indicates the need for a reschedule) is set, invoking the scheduler. Since there is a periodic timer interrupt that is guaranteed to occur at regular intervals, invocation of the scheduler is guaranteed. Preemption also happens when a process enters a blocking call or on occurrence of an interrupt event.

The Linux kernel historically has been non-preemptive, which means a task in kernel mode is non-preemptible unless an interrupt event occurs or it chooses to explicitly relinquish CPU. Since the 2.6 kernel, preemption has been added (needs to be enabled during kernel build). With kernel preemption enabled, a task in kernel mode is preemptible for all the reasons listed, but a kernel-mode task is allowed to disable kernel preemption while carrying out critical operations. This has been made possible by adding a preemption counter (preempt_count) to each process's thread_info structure. Tasks can disable/enable preemption through the kernel macros preempt_disable() and preempt_enable(), which in turn increment and decrement the preempt_counter. This ensures that the kernel is preemptible only when the preempt_counter is zero (indicating no acquired locks).

Critical sections in the kernel code are executed by disabling preemption, which is enforced by invoking preempt_disable and preempt_enable calls within kernel lock operations (spinlock, mutex).

Linux kernels build with "preempt rt", supporting fully preemptible kernel option, which when enabled makes all the kernel code including critical sections be fully preemptible.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.67.166