# Maybe we should revisit microkernels

A short unsigned post on notes.hella.cheap, roughly a page of prose with no benchmarks and no code. It's an argument sketch rather than a design document, and worth reading as one: the claim is narrow and checkable, and the piece doesn't pretend to more evidence than it has.

The definition it works from is the compact one: a microkernel keeps only scheduling, management of access to I/O devices, and IPC in the kernel, and pushes everything else into userspace.

## The case for, restated concretely

Security scoping is the first argument. In a microkernel a bug in one driver gets the attacker that subsystem, or possibly just that driver, instead of the whole machine.

Reliability is the second, and the example is CrowdStrike. On a microkernel Windows, the 2024 outage would have stopped some IT security staff from receiving telemetry rather than making front pages, because the failing component would have taken down only itself.

The third is organizational rather than technical. If Linux were a microkernel system, the kernel team would not be responsible for merging every driver for every device, nor for vetting code whose review requires becoming an expert on the internals of every chip Linux supports. That reframes driver-merge policy as a consequence of the kernel's structure rather than a governance choice.

## Why it didn't stick

The 80s and 90s produced plenty of microkernel operating systems, and the answer they ran into was overhead. The post locates the cause specifically: computers of that era had no way for a userspace process to reach a hardware device directly. So a filesystem server doing a disk read had to make a system call, which meant a context switch, which dragged in expensive locking and copying between address spaces.

That's the whole objection, and the piece's bet is that it was a statement about the hardware of the time rather than about microkernels.

## Why now

IOMMUs have been standard on PCs for about a decade. With an IOMMU plus shared memory used correctly, the author claims context switches can be removed from the happy path entirely, and nearly removed overall if you accept a little latency. The happy path is defined as the case where there are enough cores that all the work needing to be done is done by processes that are already running.

Mapping that onto the three kernel jobs:

Scheduling looks like the Xen hypervisor, since a microkernel built on virtualization technology has the same problem a hypervisor does and IOMMU is part of that technology stack.

I/O device access is managed in hardware, by the IOMMU. That is the whole point of the argument, and it's the piece the 1990s designs didn't have.

IPC needs only two primitives: the ability to allocate shared buffers between processes, and integer atomic compare-and-swap. The shared buffer becomes a command queue — a ring buffer where producer and consumer bump the start and end pointers with atomics. Messages pass asynchronously with no context switch, no copying between address spaces, and no locks. The post notes this is not speculative: GPU drivers already work this way.

Shared libraries get handled exokernel-style. If OS processes are effectively VM guests, link libraries into the program at launch and implement locally whatever doesn't need to cross a process boundary. The supporting observation is that every app already ships a copy of its own operating system in the form of Electron, so redundant copies of libraries in memory are not the cost they were thirty years ago.

The implementation estimate is deliberately unambitious. Xen already provides most of the hypervisor layer. Copy Mach's approach for the servers and take network and filesystem code from FreeBSD. DRM is already built around asynchronous command buffers, so Linux's graphics subsystem could be lifted into userspace largely as-is, possibly with the display server in the same process.

## What the argument leaves out

The IPC claim is the load-bearing one and it's the least examined. "All you need is shared buffers and atomic CAS" describes the transport, not the protocol on top of it, and the transport was never the hard part once the copies are gone. [[microkernel-ipc-design]] covers Seiya Nuta's working diary of exactly this design problem in FTL, and the difficulties there are elsewhere: synchronous IPC deadlocks the moment two servers try to send to each other, so FTL adds a notify-and-pull pattern; a driver that pushes packets to the TCP/IP server inherits the backpressure problem, so FTL inverts it into a pull; and bounding the queue by in-flight requests rather than data volume is what keeps the ring from being a DoS surface. A lock-free ring buffer gives you none of those answers. Nuta reaches the same `io_uring`-shaped conclusion the post gestures at, but by way of the flow-control questions the post skips.

The performance claim is also unquantified. "Virtually eliminate context switches if you're willing to accept a little bit of latency" is the kind of statement the 90s microkernel literature was full of, and it's what the benchmarks eventually contradicted. The hardware premise is solid and checkable; the conclusion from it is asserted.
