docs: the grant rides system_spawn, atomically

Questions 6 and 7 both dissolved on inspection, so what was left was only
where the grant is delivered. Three candidates: transfer after spawn, every
driver hellos, or fuse the device into system_spawn.

Take the third. The manager cannot transfer before the child exists, so a
separate transfer always leaves a window in which the child is running and
does not yet hold its device. That window would close on QEMU every time and
open occasionally on a machine with different timing — the exact failure
shape this track exists to delete, and not worth introducing while removing
the others. Fusing it into the spawn removes the window by construction: the
child does not exist until it holds the device. It adds no knowledge to the
kernel, only atomicity — the same rule, you may give away what you hold,
fused with the call that creates the recipient. system_spawn uses five of
six argument registers, and no_device is already the sentinel.

Making every driver hello is a good idea on its own merits — uniform
liveness, the deadline applied to all rather than some, and the
speaks_protocol two-class split leaving the manager, since a wedged ps2-bus
is invisible to its supervisor today. Kept as its own step so grant delivery
does not force it.

Order is now D0 -> D5 -> D6 -> D8, which deletes maximum_children_per_parent.
Only D7 remains blocked, on question 8, and it is needed for neither ceiling.
This commit is contained in:
Daniel Samson
2026-08-08 19:26:32 +01:00
parent 8b628a4a7d
commit cb8d1e2e51
+35 -5
View File
@@ -43,15 +43,18 @@ that cannot safely run in user space.**
| D2 | Adversarial case: a process handed nothing is refused, on a held device and a free one | **done** — `device-authority-test`; the claim half joins it at D6 |
| D3 | The manager claims the seeded devices at boot, before any driver is spawned | **merged into D4** — see below |
| D4 | The manager claims + delegates on `hello`; `usb-xhci-bus` is the first driver converted | **done** — caught an IOMMU regression I introduced; see below |
| D5 | The other four claimants converted: `pci-bus`, `ps2-bus`, `virtio-gpu`, `acpi` | **partial** — `pci-bus` done; the other three need decisions, see below |
| D5 | The other four claimants converted: `pci-bus`, `ps2-bus`, `virtio-gpu`, `acpi` | **partial** — `pci-bus` done; the rest unblocked by D0 below |
| D0 | The grant rides `system_spawn` — atomic, so no driver need change to receive one | not started — **do first** |
| D10 | Every driver hellos, on its own merits (liveness, one class of driver) | not started — optional, independent |
| D6 | `device_claim` refuses a device the caller was not handed; the hole is closed | not started |
| D7 | Zero-resource devices stop being kernel objects — inventory moves to the manager | **blocked** — nothing else mints their ids; see question 8 |
| D8 | **`maximum_children_per_parent` deleted** — the authorisation it stood in for exists | **blocked on D6**, and now ordered after D9 |
| D9 | The device table becomes dynamic; **`maximum_devices` deleted**; per-holder quota declared | **done** — one of the two invented numbers is gone |
**Run 2 stops here.** D1, D2, D4, D5 (`pci-bus` only) and D9 landed; D6, D7, D8 and the
rest of D5 are blocked on questions 6, 7 and 8 below. Suite 118/118, and
`maximum_devices` no longer exists.
**Run 2 resumes at D0.** D1, D2, D4, D5 (`pci-bus` only) and D9 landed; `maximum_devices`
no longer exists and the suite is 118/118. Questions 6 and 7 dissolved, so the order is
now **D0 → D5 → D6 → D8**, which deletes `maximum_children_per_parent`. Only D7 is still
blocked, on question 8, and it is needed for neither ceiling. D10 is optional.
Ordering is load-bearing. D1–D2 build and prove the mechanism with nothing depending on
it. D4–D5 move each claimant across one at a time, so the suite stays green throughout
@@ -84,7 +87,34 @@ They land together, with the manager claiming only for drivers in an explicit
anything in D4 — recorded rather than dismissed, because D4 moved the `hello` earlier
and so did shift boot timing. Watch it across the remaining steps.
### Open questions raised by D5 — three of the four claimants cannot be converted yet
### Settled 2026-08-08: the grant rides `system_spawn` (D0)
Questions 6 and 7 both dissolved on inspection — neither `ps2-bus` nor discovery needs
to start speaking `hello`, and `virtio-gpu` has no standalone path to lose. What remains
is *where the grant is delivered*, and there are three candidates:
| | Race window | Cost |
|---|---|---|
| Transfer after spawn | **yes** | none |
| Every driver hellos | no | `ps2-bus` + discovery gain a handshake |
| **Grant rides `system_spawn`** | **no — atomic** | one more syscall argument |
**Take the third.** The manager cannot transfer before the child exists, so a separate
transfer always leaves a window in which the child is running and does not yet hold its
device. It would close on QEMU every time and open occasionally on a machine with
different timing — the exact failure shape this track exists to delete, and not worth
introducing while removing the others. Fusing the device into the spawn removes it by
construction: the child does not exist until it holds the device. No new knowledge in
the kernel — the same rule, *you may give away what you hold*, made atomic with the call
that creates the recipient. `system_spawn` uses five of six argument registers, so there
is room, and `no_device` is already the sentinel for a driver with no assignment.
**`hello` for every driver is a good idea on its own merits** — uniform liveness, the
deadline applied to all rather than some, and the `speaks_protocol` two-class split
leaving the manager (a wedged `ps2-bus` is invisible to its supervisor today). It is
D10, kept separate so grant delivery does not force it.
### Open questions raised by D5 — resolved except question 8
Delegation is delivered in `onHello`. That works for a driver that says hello, and
**two of the four do not**.