The kernel preemption model removal has caught a lot of people off guard. You upgrade your kernel, fire up a build, and suddenly the config options you've relied on for years simply aren't there. No PREEMPT_NONE. No PREEMPT_VOLUNTARY. Just errors, missing menu entries, and a build that won't complete. This guide covers exactly what's happened, why it's happened, and how to get your system back on track without guessing.
TL;DR
The kernel preemption model removal means PREEMPT_NONE and PREEMPT_VOLUNTARY are no longer available on major architectures. Update your .config or build scripts to use a currently supported preemption mode like CONFIG_PREEMPT=y or CONFIG_PREEMPT_DYNAMIC=y, clean your build tree with make mrproper, and rebuild. If you're on a distro kernel, boot the default flavour and let the distro handle it.
Key Takeaways
- The kernel preemption model removal affects PREEMPT_NONE and PREEMPT_VOLUNTARY, which are being phased out on x86, arm64, riscv and powerpc.
- The most common trigger is a stale .config or build script that still references the removed symbols after a kernel upgrade.
- The fix is to replace deprecated symbols with CONFIG_PREEMPT=y or CONFIG_PREEMPT_DYNAMIC=y and rebuild from a clean tree.
- Architecture support is not uniform, so a config fragment that works on x86 may fail on arm64.
- Distro users can recover quickly by booting the default kernel and rolling back the custom build.
At a Glance
- Difficulty: Advanced
- Time Required: 30 mins
What Causes the Kernel Preemption Model Removal Problem?
The kernel preemption model removal isn't a bug or a mistake. It's a deliberate simplification of the kernel's scheduler subsystem. For years, Linux offered three main preemption modes: no preemption (PREEMPT_NONE), voluntary preemption (PREEMPT_VOLUNTARY), and full preemption (PREEMPT). The older two modes were primarily useful for throughput-focused server workloads where you wanted the scheduler to stay out of the way as much as possible. But as the kernel has matured and PREEMPT_DYNAMIC has arrived as a flexible runtime-switchable option, the older static modes have become redundant on most architectures.
So why does this break things? Almost always, it comes down to a config mismatch. You've upgraded your kernel source or your distro has pushed a new kernel package, but your old .config file, your custom build script, or your CI pipeline still has CONFIG_PREEMPT_NONE=y or CONFIG_PREEMPT_VOLUNTARY=y baked in. The kernel build system hits that symbol, can't find it in the current Kconfig, and either throws an error or silently ignores it and picks a default you didn't intend.
There's also a vendor versus mainline split to be aware of. Some distribution kernels, particularly older LTS branches or embedded vendor trees, may still carry these options. If you're cross-referencing documentation written against one of those trees and applying it to a mainline build, you'll hit the kernel preemption model removal immediately. The docs aren't wrong for their target, but they're wrong for yours.
Architecture differences make this messier. The removal has not landed uniformly. On x86_64, the transition is well underway. On arm64 and riscv, the situation has been moving at a different pace. Powerpc has its own quirks. A config fragment that compiles cleanly on one architecture can fail on another, which is a particular problem for anyone maintaining a multi-arch build pipeline. If you've got a CI system that builds kernel images for several targets from a shared config fragment, one architecture's build breaking while others pass is a classic symptom of this exact issue.
And then there's the documentation problem. A lot of kernel tuning guides, blog posts, and forum answers written before this change still recommend setting PREEMPT_NONE for server workloads or PREEMPT_VOLUNTARY as a middle ground. People follow those guides in good faith and then wonder why menuconfig doesn't show those options any more. The kernel hasn't broken. The guide is just out of date.
Kernel Preemption Model Removal: Quick Fix
This one's for people who need to get back up and running fast without digging into build systems. If you've hit the kernel preemption model removal after a distro upgrade rather than a custom build, this is where to start.
Boot the Distro Default Kernel Easy
- Reboot and access the bootloader
Restart your machine and holdShift(GRUB legacy) or pressEscduring boot to access the GRUB menu. Select the previous or default kernel entry from the Advanced options submenu. - Confirm you're on the distro kernel
Once booted, rununame -rin a terminal. You should see the distro's kernel version string, typically something like6.x.x-genericor6.x.x-amd64depending on your distribution. - Check the preemption config
Rungrep -i preempt /boot/config-$(uname -r). The distro kernel should show a supported preemption mode with no references to the removed symbols. This confirms the distro package is clean and the issue is isolated to your custom build. - Roll back the broken kernel package if needed
On Debian or Ubuntu, usesudo apt-mark hold linux-image-to prevent the broken kernel from being selected automatically. On Fedora or RHEL-based systems, usesudo dnf versionlock add kernel-. This buys you time to fix the underlying config issue without being forced back into the broken build on next reboot.
More Kernel Preemption Model Removal Solutions
For anyone building a custom kernel or maintaining a config file directly, you need to update the preemption selection itself. This is the intermediate path and covers the majority of cases where the quick fix isn't enough.
Update Your Kernel Config Directly Intermediate
- Locate your current config
Your active kernel config is usually at/boot/config-$(uname -r). If you're building from source, your working config is the.configfile in your kernel source tree root. Copy it as a backup before making any changes:cp .config .config.bak. - Find and remove deprecated preemption symbols
Open the config file in any text editor and search forCONFIG_PREEMPT_NONEandCONFIG_PREEMPT_VOLUNTARY. Remove or comment out any lines that set these toy. On a system that has already been upgraded, you may find these lines simply don't exist, which means the build system is picking a default you haven't explicitly set. - Set a supported preemption mode
For a desktop or workstation workload, addCONFIG_PREEMPT=y. For a server where you want runtime flexibility, addCONFIG_PREEMPT_DYNAMIC=yif your kernel version and architecture support it. Check availability withgrep PREEMPT_DYNAMIC kernel/Kconfig.preemptin your source tree. For a reference on what each mode does at the scheduler level, the official kernel scheduler documentation covers the current supported options clearly. - Run olddefconfig to resolve conflicts
From your kernel source root, runmake olddefconfig. This processes your updated .config against the current Kconfig and fills in any missing symbols with their defaults. It won't prompt you for every option, which is what you want here. Check the output for any warnings about unrecognised symbols. - Verify the result
Rungrep -i preempt .configand confirm you see your chosen mode set toyand no references to the removed symbols. Then proceed with your normal build process.
One thing that catches people out here: if you're using make menuconfig and you can't find the preemption option in the menu, it's because the symbol genuinely isn't there for your architecture and kernel version. Don't go hunting for it. Check Kconfig directly. For a general reference on the traditional kernel compilation process, the Arch Linux kernel compilation wiki is one of the clearest resources available and covers the config step in detail. It's architecture-neutral enough to be useful even if you're not on Arch.
If you're dealing with a kernel config mismatch in a more complex environment, such as an embedded build system or a Yocto layer, the approach is the same but the file locations differ. Your config fragment will be somewhere in your layer's recipes-kernel/linux/ directory. Find the fragment that sets the preemption symbol and update it there rather than patching the generated .config, otherwise your changes will be overwritten on the next build.
Advanced Kernel Preemption Model Removal Fixes
If you're maintaining a build pipeline, a CI system, or a multi-architecture kernel build, the intermediate fix above isn't enough on its own. You need to make sure the removed symbols don't creep back in through automation.
Audit and Fix Build Scripts and CI Pipelines Advanced
- Search all automation for hardcoded preemption symbols
Run a recursive grep across your entire build system:grep -r 'PREEMPT_NONE\|PREEMPT_VOLUNTARY' .from your repo root. Check Makefiles, shell scripts, Python build scripts, Yocto layers, Buildroot configs, and any CI YAML files. Every hit is a potential source of the kernel preemption model removal problem reappearing after a clean. - Replace hardcoded symbols with conditional detection
Instead of unconditionally settingCONFIG_PREEMPT_NONE=y, query whether the symbol exists in the target kernel's Kconfig before setting it. In a shell script, you can do this with:grep -q 'config PREEMPT_NONE' kernel/Kconfig.preempt && echo CONFIG_PREEMPT_NONE=y || echo CONFIG_PREEMPT=y. This way the script adapts to the kernel version rather than assuming a fixed set of available options. - Add architecture conditionals
The kernel preemption model removal is not uniform across architectures. Wrap preemption config logic in arch checks. In a Makefile fragment:ifeq ($(ARCH),x86_64)then set one option;else ifeq ($(ARCH),arm64)then set another. Check thearch/$(ARCH)/Kconfigfile in your kernel source to confirm which preemption symbols are actually selectable on each target. For a full list of kernel boot and config parameters, the kernel.org admin guide is the authoritative reference. - Clean the build tree before rebuilding
Runmake mrproperfrom your kernel source root. This removes all generated files including the .config, so start from your updated config fragment rather than any cached state. Then runmake olddefconfigfollowed by your full build command. Stale config fragments are the single most common reason the kernel preemption model removal problem persists after you think you've fixed it. This one often needs a second clean before it fully sticks if you've been iterating on the config. - Version your config fragments
Store your kernel config fragments in version control alongside your build scripts. Tag or branch them against the kernel version they were written for. When you upgrade the kernel source, diff the old fragments against the new Kconfig to catch removed or renamed symbols before they cause a build failure. This is the single most useful habit for avoiding the kernel preemption model removal class of problem in future. - Validate the built kernel's preemption model
After a successful build and install, boot the new kernel and rungrep -i preempt /boot/config-$(uname -r). Confirm the active preemption mode matches your intent. For performance-sensitive workloads, benchmark latency and throughput against your previous kernel before committing the change to production. Old assumptions about PREEMPT_NONE delivering better throughput may not hold once you're on PREEMPT_DYNAMIC with the right runtime setting.
preempt= kernel parameter. Real-time workloads should consider PREEMPT_RT patches separately, which is a different topic from the kernel preemption model removal covered here.For anyone dealing with a vendor kernel that still exposes PREEMPT_NONE or PREEMPT_VOLUNTARY, the temptation is to keep using those modes because they're available. That's fine short-term, but plan for the transition. When that vendor tree eventually catches up with mainline, you'll hit the same kernel preemption model removal issue again, and it's better to migrate on your own schedule than under pressure during a production upgrade. If you're managing Linux systems at scale and want help sorting this remotely, see our Linux kernel troubleshooting service for options.
Kernel build failures from the preemption model removal can be sorted remotely. Our engineers can audit your .config, fix your build scripts, and get your kernel compiling cleanly without you needing to be a kernel developer yourself.
Get remote helpPreventing the Kernel Preemption Model Removal Problem
Prevention here is almost entirely about build hygiene. The kernel preemption model removal didn't happen overnight. It was signalled in kernel release notes and Kconfig comments well before the symbols disappeared. The people who got caught were the ones who hadn't read the notes or had automation that assumed a fixed set of config options forever.
The most important habit is reading kernel release notes before upgrading, particularly for changes to the scheduler, Kconfig symbols, and architecture support. The kernel changelog is dense but searchable. A quick grep -i preempt through the release notes for a major version bump takes two minutes and can save hours of debugging. For a structured overview of how the kernel versioning and release process works, the Linux kernel versions guide on this site covers what to look for before a major upgrade.
Second most important: never hardcode preemption symbols in automation. Detect what's available per kernel and architecture at build time. This applies to CI systems, Yocto layers, Buildroot configs, and any shell script that touches a .config. A five-line detection block in your build script is far less painful than a broken pipeline at 2am.
Keep your config fragments versioned and tagged against the kernel version they target. When you upgrade the kernel source, run a diff between the old Kconfig and the new one to catch removed or renamed symbols before they cause a failure. This is the kind of process that feels like overhead until the day it saves you from a production outage.
Test kernel upgrades in a staging environment first. This is obvious advice but it's ignored constantly. A staging kernel build that fails because of the kernel preemption model removal is a ten-minute fix. The same failure in production during a maintenance window is a much bigger problem. If your team needs a repeatable process for this, our Linux system maintenance checklist covers kernel upgrade staging as part of a broader workflow.
Finally, prefer distro defaults unless you have a specific, measured reason to customise preemption behaviour. Distro maintainers track these changes and update their configs accordingly. If you're running a general-purpose server or desktop and you're customising the preemption model based on a guide from five years ago, stop. Check what your distro ships, benchmark it against your actual workload, and only deviate if the numbers justify it.
Kernel Preemption Model Removal: Summary
The kernel preemption model removal is a build-time and configuration problem, not a runtime fault. PREEMPT_NONE and PREEMPT_VOLUNTARY are being phased out on major architectures and the fix is to update your .config or build scripts to use a currently supported preemption mode. For most workloads, CONFIG_PREEMPT=y is the right replacement. For environments needing runtime flexibility, CONFIG_PREEMPT_DYNAMIC=y is the modern option. Clean your build tree with make mrproper after any config change, audit your automation for hardcoded symbols, and version your config fragments against the kernel source they target. Do those things and the kernel preemption model removal stops being a recurring problem.


