docs: D7 blocked, and D8 reordered after D9

D7 would remove zero-resource devices from the kernel. It cannot proceed
because nothing else mints their ids. A USB interface registers with
resource_count = 0, and the id device_register hands back is load-bearing in
three places: the child_added packet's target, the class driver's argv[1],
and the device_token of the usb-transfer WIRE protocol — so the id space is
visible on the wire, not merely internal. usb-xhci-bus records the fourth
constraint itself: the kernel's idempotency is what makes the same port and
interface map back to the same id across a bus restart, which is what stops
a respawned bus spawning duplicate class drivers.

Moving that out means answering who mints the id, how it survives a bus
restart, how it survives a manager restart, and whether device_token changes
meaning. A design step, not a mechanical one.

D8 is reordered to run after D9, correcting the original sequencing. D8's
justification was that the authorisation the per-parent cap stood in for now
exists — but D6 is blocked, so it does not, and deleting the shared cap now
would reopen the exhaustion hole it was written for. D9's per-holder quota
closes that hole independently of authorisation, and closes it better: a
rogue exhausts its own allowance instead of the table everyone shares. Once
the quota exists the per-parent cap is redundant either way.

D9 also no longer depends on D7. Its rationale was that zero-resource
children are the case that sidesteps containment — true, but a per-holder
quota bounds them as well as anything else, because it counts entries per
holder rather than per parent.
This commit is contained in:
Daniel Samson
2026-08-08 18:26:37 +01:00
parent 81dd1e9318
commit 5492607a61
+31 -5
View File
@@ -45,9 +45,9 @@ that cannot safely run in user space.**
| 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 |
| 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 | not started |
| D8 | **`maximum_children_per_parent` deleted** — the authorisation it stood in for exists | not started |
| D9 | The device table becomes dynamic; **`maximum_devices` deleted**; per-holder quota declared | 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 | not started — **runs before D8** |
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
@@ -104,8 +104,34 @@ Delegation is delivered in `onHello`. That works for a driver that says hello, a
but discarding a documented intent is a decision, not a mechanical step.
Until these are answered, `device_claim` cannot be closed off at D6 for those three, so
**D6 is blocked on question 6 and 7**. D7–D9 are not: they concern what the kernel
stores and how the table is sized, and are independent of which drivers have converted.
**D6 is blocked on questions 6 and 7**.
8. **Removing zero-resource devices from the kernel needs someone else to mint their
ids, and nothing says who.** A USB interface is registered with
`resource_count = 0`, and the id `device_register` returns is load-bearing in three
places: it is the `child_added` packet's target, it is the class driver's `argv[1]`,
and it is the `device_token` of the **usb-transfer wire protocol** — so the id space
is visible on the wire, not merely internal. usb-xhci-bus's own comment records the
fourth constraint: the kernel's idempotency is what makes "the same port and
interface always map back to the same device id" across a bus restart, which is what
stops a respawned bus spawning duplicate class drivers.
So the mover has to answer: who mints the id, how it stays stable across a *bus*
restart, how it stays stable across a *manager* restart (open question 3 territory),
and whether the wire protocol's `device_token` changes meaning. That is a design
step, not a mechanical one.
**D8 is reordered to run after D9**, which is a correction to the original sequencing.
D8's justification was "the authorisation it stood in for exists" — but with D6 blocked
it does not, so deleting the shared per-parent cap now would reopen the exhaustion hole
it was written for. D9's **per-holder quota** closes that hole independently of
authorisation, and does it better: a rogue exhausts its own allowance rather than the
table everyone shares. Once the quota exists, the per-parent cap is redundant whether or
not D6 has landed.
D9 also no longer depends on D7. Its original rationale was that zero-resource children
are the case that sidesteps containment — true, but a per-holder quota bounds them just
as well as anything else, because it counts entries per holder rather than per parent.
### Settled, so the run does not re-litigate them