Map

Linux preemption models

Wiki conceptlinuxkernelscheduling โ†ณ show in map Markdown
title
Linux preemption models
type
concept
summary
PREEMPT_NONE, PREEMPT_FULL, and PREEMPT_LAZY โ€” when the kernel is allowed to take the CPU away from a running thread
tags
linux, kernel, scheduling
created
2026-04-30
updated
2026-05-14

Preemption is the scheduler's decision about when it's allowed to interrupt a running thread and hand the CPU to another. Different workloads want different answers, so the Linux kernel exposes the choice as a build-time configuration.

The three models

PREEMPT_NONE โ€” the kernel almost never interrupts a running thread. It runs until it gives up the CPU itself: a syscall, blocking I/O, an explicit sleep. Few context switches, high throughput, predictable behavior under load. Traditional server default.

PREEMPT_FULL โ€” the kernel can interrupt a running thread at almost any safe point, including inside the kernel itself. Lower latency, more context-switch overhead. Traditional desktop default, where responsiveness wins over throughput.

PREEMPT_LAZY โ€” introduced in Linux 6.12 as a compromise. Preemption is allowed but the scheduler tries to wait for natural boundaries before cutting in. Designed as a drop-in replacement for PREEMPT_NONE on throughput workloads.

What changed in Linux 7.0

Linux 7.0 removed PREEMPT_NONE on modern CPU architectures, leaving PREEMPT_FULL and PREEMPT_LAZY. Most server distros shifted their default to PREEMPT_LAZY. The transition is invisible for most software. But where it isn't, it really isn't โ€” see linux-7-postgres-regression for a workload (PostgreSQL on a 96-vCPU box) where the change cut throughput in half because the scheduler can now preempt a thread that's holding a spinlock and is midโ€“page fault.

Why "drop-in" isn't drop-in

PREEMPT_NONE was a free implicit guarantee for any code holding a spinlock: even if the holder did something the kernel had to handle (a fault, a slow path), it wouldn't get descheduled until it was done. Code written before PREEMPT_LAZY could quietly rely on that. Once removed, every "the holder will be gone in nanoseconds" assumption needs to actually be true โ€” or be backed by something stronger like restartable sequences.

What happens before any of this matters

The preemption model only takes effect after boot. During Phase 4 of linux-kernel-startup (start_kernel), interrupts are disabled for almost the entire run and the scheduler exists but isn't load-balancing yet. Real multitasking โ€” the world where preemption decisions actually matter โ€” starts in Phase 6 with sched_init_smp(). See linux-boot-phases for the broader ordering.

Sub-pages