What the Linux Kernel's Official AI Policy Reveals About Systems Programming
Source: hackernews
The Linux kernel’s documentation tree now contains a file called coding-assistants.rst, sitting alongside the traditional submitting-patches.rst and coding-style.rst that have guided contributors for decades. The document’s existence landed on Hacker News with considerable discussion, and the reaction is understandable: this is Linus Torvalds’ tree officially acknowledging that developers use AI tools and providing guidance accordingly.
The document doesn’t ban AI assistance. It takes a measured position: you can use AI tools to understand kernel code, to learn subsystem patterns, to navigate documentation. If you use AI to write code you intend to submit, you are still fully responsible for understanding every line. The Developer Certificate of Origin, which contributors sign off on each patch with Signed-off-by, certifies that you understand and have the right to submit the code. AI generation changes nothing about that obligation.
That framing is sensible and hard to argue with. But the more interesting part of this document, for anyone who has spent time in both the AI tooling world and the systems programming world, is everything it implies without stating directly.
Why Kernel Code Is a Particularly Bad Match for LLMs
Large language models learn from statistical patterns in code. They have seen a lot of C, a lot of Linux kernel source, and a lot of discussion about both. They can produce code that looks like kernel code, uses the right macros, follows familiar error-handling patterns. The problem is that kernel code correctness depends on invariants that are not visible in any individual code snippet, and LLMs have no mechanism to maintain those invariants across a patch.
Consider memory ordering. The Linux kernel runs on dozens of architectures with wildly different memory models. The kernel’s memory model documentation is tens of thousands of words long and describes a formal model that even experienced kernel developers consult regularly. When you write smp_mb() or READ_ONCE() or smp_load_acquire(), you are making a precise statement about what guarantees you need from the hardware. Getting this wrong doesn’t produce a compile error. It produces a race condition that surfaces once every few weeks on a 48-core ARM server under specific load patterns.
LLMs will produce code that uses these primitives. They will even produce code that uses them in patterns seen in the training corpus. But they cannot reason about whether a specific primitive is correct for the specific ordering guarantee you need in the specific context of your new code path. The model is matching patterns, not reasoning about the memory model.
Lock ordering presents the same problem. The kernel has strict conventions about which locks can be held while acquiring other locks, enforced by lockdep at runtime. These conventions are subsystem-specific, underdocumented in many places, and evolved over decades. An LLM can follow the surface pattern of taking a lock before accessing a data structure without knowing whether taking that lock while holding some other lock creates a deadlock cycle that lockdep will catch, if you’re lucky, or that will silently deadlock in production, if you’re not.
RCU (Read-Copy-Update) is another area where AI assistance is particularly unreliable. The rules around what you can do inside an RCU read-side critical section, when you need rcu_dereference() versus rcu_dereference_protected(), and how grace periods interact with memory reclaim are subtle enough that the kernel’s own RCU documentation warns experienced developers to proceed carefully. An LLM generating RCU code is working from pattern matching on a corpus where correct and incorrect usage both appear.
The Provenance Problem
The coding assistants document also gestures at a concern the kernel community has been managing carefully: licensing and provenance. The Linux kernel is licensed under GPL-2.0-only. Every line merged into the kernel carries that license, and every contributor signing a patch certifies, under the DCO, that they have the right to submit it under that license.
When an LLM generates code, it produces output derived from a training corpus that includes GPL code, MIT code, BSD code, proprietary code, and Stack Overflow posts with varying licensing histories. The model doesn’t track provenance. The generated output might closely resemble GPL-incompatibly-licensed code from that training corpus, or it might be clean synthesis. There is no way to know.
For most projects, this is a theoretical concern that legal teams can disagree about indefinitely. For the Linux kernel, it is a genuine operational problem. The kernel has been through high-profile copyright disputes before (the SCO litigation consumed years of community energy and resources), and the community is appropriately careful about what enters the tree. Code submitted by a developer who wrote it has a clear chain of provenance. Code generated by an LLM and submitted without careful review has none.
Where AI Assistance Is Genuinely Useful
The document is careful to note that AI tools can be genuinely useful for kernel development. This is worth taking seriously rather than dismissing as diplomatic hedging.
The kernel is enormous. The 6.x series contains north of 35 million lines of code across hundreds of subsystems. Even experienced kernel developers are strangers to most of it. When you need to understand how a specific driver initializes its DMA mapping, or how a particular filesystem handles journal recovery, or what the expected calling convention is for a specific interrupt controller API, you are reading code that might have only a handful of people in the world who understand it deeply.
AI tools can help navigate this. They can explain what a function does, summarize a subsystem’s entry points, and help you find the relevant parts of a sprawling codebase. This is reading assistance, not writing assistance, and the failure modes are much less dangerous. If an AI gives you a slightly wrong explanation of what blk_mq_sched_dispatch_requests() does, you’ll catch it when you read the actual source. If an AI gives you subtly wrong memory barrier placement, you might not catch it at all.
This distinction between using AI to understand code versus using AI to generate code is the most practically useful thing in the document, and it generalizes well beyond kernel development. The dangerous zone is not AI assistance per se; it’s AI assistance in domains where the submitter lacks the depth to distinguish plausible-looking output from correct output.
The Cost That Maintainers Bear
Greg Kroah-Hartman and other kernel maintainers have been direct in public about the cost that low-quality AI-generated patches impose on the project. Reviewing a patch takes time whether the patch is good or bad. A maintainer who has to spend an hour understanding and then rejecting a patch that the submitter clearly didn’t understand has spent time that could have gone elsewhere. At the scale of the Linux Kernel Mailing List, which receives thousands of patches weekly, this compounds quickly.
The document handles this with a straightforward principle: use any tools you want to understand the codebase and form your approach, but when you send a patch, it is your patch. You understand it, you have verified it, you can answer questions about it. The AI is a research aid, not a co-author whose work you pass off as your own understanding.
The Broader Signal
The kernel formalizing this guidance is a useful data point in the broader conversation about AI in software development. The mainstream narrative about AI coding tools tends to treat all code as roughly equivalent: you write a function, the AI helps, the tests pass, you ship. That story works reasonably well for application-level code where correctness is enforced by tests, type systems, and runtime exceptions.
Kernel code sits at the other end of that spectrum. There are no type-system-enforced memory safety guarantees across most of the tree; this is C, not Rust, in the vast majority of the codebase (though the Rust-for-Linux project is changing that at the margins). Incorrect code can corrupt memory silently, introduce security vulnerabilities, or produce rare race conditions that are nearly impossible to reproduce. The review process exists because humans with deep domain knowledge need to validate that every patch is correct, not just functional-looking.
The interesting question the document raises, without answering, is whether AI tooling will get better at the specific things kernel code demands: understanding invariants that span files, tracking lock ordering across subsystems, reasoning about memory models. The current generation of tools is not there. Future generations may close some of that gap through better context handling, static analysis integration, or formal verification assistance. Until then, the kernel’s guidance is the right one: treat generated code as a draft from a junior contributor who doesn’t understand the constraints, and review it accordingly.