diff --git a/docs/bounds-track-plan.md b/docs/bounds-track-plan.md index 25e8952..01cce41 100644 --- a/docs/bounds-track-plan.md +++ b/docs/bounds-track-plan.md @@ -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