Thursday, February 20, 2014

Linux Kernel Preemption

The Linux kernel, unlike most other Unix variants and many other operating systems, is a fully preemptive kernel. In non-preemptive kernels, kernel code runs until completion. That is, the scheduler cannot reschedule a task while it is in the kernel—kernel code is scheduled cooperatively, not preemptively. Kernel code runs until it finishes (returns to user-space) or explicitly blocks.

In the 2.6 kernel, however, the Linux kernel became preemptive: It is now possible to preempt a task at any point, so long as the kernel is in a state in which it is safe to reschedule. So when is it safe to reschedule? The kernel can preempt a task running in the kernel so long as it does not hold a lock.That is, locks are used as markers of regions of nonpreemptibility. Because the kernel is SMP-safe, if a lock is not held, the current code is reentrant and capable of being preempted.

Changes in Linux kernel to support Preemption

The first change in supporting kernel preemption was the addition of a preemption counter, preempt_count, to each process’s thread_info.This counter begins at zero and increments once for each lock that is acquired and decrements once for each lock that is released.When the counter is zero, the kernel is preemptible. Upon return from interrupt, if returning to kernel-space, the kernel checks the values of need_resched and preempt_count. If need_resched is set and preempt_count is zero, then a more important task is runnable, and it is safe to preempt.Thus, the scheduler is invoked. If preempt_count is nonzero, a lock is held, and it is unsafe to reschedule. In that case, the interrupt returns as usual to the currently executing task.When all the locks that the current task is holding are released, preempt_count returns to zero.At that time, the unlock code checks whether need_resched is set. If so, the scheduler is invoked. Enabling and disabling kernel preemption is sometimes required in kernel code

Kernel preemption can occur...
1.When an interrupt handler exits, before returning to kernel-space
2.When kernel code becomes preemptible again
3. If a task in the kernel explicitly calls schedule()
4. If a task in the kernel blocks (which results in a call to schedule())

Reference:-
Linux Kernel Development by Robert Love

No comments:

Post a Comment