Operating-System Kernels

kernel preemption

Preemption is the scheduler's power to forcibly take a CPU away from a running task to run a more deserving one, instead of waiting for the task to give it up voluntarily. Kernel preemption is the question of whether this can happen even while a task is running inside the kernel - that is, in the middle of a system call or kernel work. The answer shapes how responsive the system feels: if a low-priority task is deep in some kernel routine and a high-priority task wakes up, can the kernel snatch the CPU right then, or must it wait until the kernel routine finishes?

There is a spectrum. In a non-preemptible kernel, once a task enters the kernel it runs there until it blocks or returns to user space - a high-priority task that wakes up must wait, which adds latency. Voluntary preemption adds checkpoints: the kernel sprinkles in places where, if a higher-priority task is waiting, the current task voluntarily yields - a middle ground that lowers latency without full complexity. A fully preemptible kernel allows the scheduler to preempt kernel code at almost any point (except inside critical sections that explicitly disable preemption, like while holding a spinlock), giving the lowest latency, which matters most for real-time and interactive workloads. This is also why code holding a spinlock disables preemption: it must not be scheduled away mid-critical-section.

A piece of history that illuminates the design: early Linux multiprocessor support used a single Big Kernel Lock (the BKL) - one giant lock that essentially let only one CPU run kernel code at a time. It was simple and correct but a terrible scalability bottleneck, because it serialized the whole kernel. The long, painstaking march of Linux development was to replace that one lock with fine-grained locking (many small locks protecting individual data structures) and to make the kernel preemptible, so multiple cores could run kernel code concurrently and high-priority tasks would not wait. The BKL was finally removed entirely in 2011. The lesson is that 'one big lock' is the easy, slow answer, and real scalability comes from carefully splitting it up - the same lesson that drives spinlocks, RCU, and per-CPU data.

low-priority task is mid-syscall; a high-priority task wakes. non-preemptible: it waits until the syscall finishes. fully preemptible: the scheduler preempts the kernel right now (unless preemption is disabled, e.g. under a spinlock).

Preemptible kernels can take the CPU from kernel code at once for a higher-priority task, lowering latency - except where preemption is deliberately disabled.

The historic Big Kernel Lock was correct but catastrophic for scaling because it serialized the entire kernel; the long fix was fine-grained locking plus preemption, completed when the BKL was removed in 2011. The general lesson: one big lock is simple and slow - scalability comes from splitting it, which is exactly why spinlocks, RCU, and per-CPU data exist.

Also called
preemptible kernelvoluntary preemptionBig Kernel Lock (BKL)可搶占核心大核心鎖