kernel: maximum_children_per_parent is gone
The second invented ceiling. It was written to stop a driver looping device_register and exhausting a shared table — but there is no shared table to exhaust any more, and each registrar already has its own allowance, so a runaway costs only itself. It never bounded a determined caller in the first place: 16 children per parent, and nothing stopped it claiming more parents. What it reliably did was refuse a real PCI bus with more than 16 functions, which is how an AMD Ryzen booted with a working display, no USB and no storage. The constant, its check, and the now-unused childCount all go. TooManyChildren survives with one meaning instead of two: the caller is at its per-registrar allowance. This was unblocked from the moment D9 landed. The plan said so — "once the quota exists the per-parent cap is redundant whether or not D6 has landed" — in the same edit that left the step tagged "blocked on D6". Three iterations were then spent re-reading that tag instead of the sentence beside it. The containment test now asserts 64 children under one parent, four times the old ceiling; restoring the cap fails it. Suite 118/118.
This commit is contained in:
+35
-30
@@ -48,16 +48,17 @@ that cannot safely run in user space.**
|
||||
| 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 |
|
||||
| D8 | **`maximum_children_per_parent` deleted** | **done** — it was unblocked from the moment D9 landed; I kept reading my own stale label |
|
||||
| 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, blocked.** Landed: D0, D1, D2, D4, D9, and D5 for three of five
|
||||
claimants (`usb-xhci-bus`, `pci-bus`, `virtio-gpu`). `maximum_devices` no longer exists,
|
||||
delegation is atomic with the spawn, and the suite is 118/118.
|
||||
**Run 2 stops, blocked on one question.** Landed: D0, D1, D2, D4, D8, D9, and D5 for
|
||||
three of five claimants (`usb-xhci-bus`, `pci-bus`, `virtio-gpu`). Suite 118/118.
|
||||
|
||||
Blocked: **D6 and D8 on question 9** (`ps2-bus` needs two devices and ignores its
|
||||
assignment; discovery needs a node nobody assigns), and **D7 on question 8**. So
|
||||
`maximum_children_per_parent` — the second invented number — is one answer away.
|
||||
**Both invented ceilings are gone.** `maximum_devices` and
|
||||
`maximum_children_per_parent` no longer exist, and delegation is atomic with the spawn.
|
||||
|
||||
What remains is not a number: **D6 closes the claiming hole** and is blocked on
|
||||
question 9, and D7 moves the inventory and is blocked on question 8.
|
||||
|
||||
Ordering is load-bearing. D1–D2 built and proved the mechanism with nothing depending on
|
||||
it. D4–D5 move each claimant across one at a time, so the suite stays green throughout
|
||||
@@ -90,34 +91,38 @@ 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 question 9 — two drivers need a device nobody assigned them
|
||||
### Open question 9 — danos has two device-acquisition patterns; D6 fits only one
|
||||
|
||||
D0 made delivery atomic and D5 converted `virtio-gpu` with it. The last two do not fit,
|
||||
for the same underlying reason: **they need a device the manager never assigned.**
|
||||
Earlier versions of this question listed symptoms — "`ps2-bus` ignores its `argv[1]`",
|
||||
"discovery has no assignment" — which hid that they are the same fact.
|
||||
|
||||
- **`ps2-bus` ignores its `argv[1]` entirely.** It finds the controller by walking the
|
||||
table for `PNP0303`, and then claims a *second* device — the `PNP0F13` mouse node —
|
||||
which it also finds itself. So it holds two devices and was assigned at most one, and
|
||||
`system_spawn` carries one.
|
||||
- **discovery** is spawned `addDriver("discovery", no_device, false)` and claims the
|
||||
`acpi-tables` node it locates itself, because it is what produces the device tree;
|
||||
there is nothing to assign at that point.
|
||||
| Pattern | Who | How it gets its device |
|
||||
|---|---|---|
|
||||
| Per-device driver | `pci-bus`, `usb-xhci-bus`, `virtio-gpu`, `usb-hid`, `usb-storage` | assigned one id, one instance per device — **all converted** |
|
||||
| Singleton that finds its own | `ps2-bus`, discovery | spawned once with `no_device`, walks the table itself |
|
||||
|
||||
Three shapes of answer, none written down:
|
||||
The second is deliberate, not an oversight. `onChildAdded` says so:
|
||||
|
||||
1. **The manager assigns every device a driver needs.** For `ps2-bus` it would have to
|
||||
understand that one driver serves both `PNP0303` and `PNP0F13` — `devices.csv` maps
|
||||
both to it already, so the manager may simply be spawning two instances today where
|
||||
the driver expects one. Worth checking before designing.
|
||||
2. **A driver asks for a device over the protocol** — a `request(device)` verb the
|
||||
manager answers by transferring. General, and it reintroduces a window, though only
|
||||
for a device the driver asks for after it is running.
|
||||
3. **The bootstrap is exempt**: discovery keeps claiming, and D6 permits a claim of a
|
||||
device nobody holds *only* for the discovery role. Narrow and honest, but it is an
|
||||
exception in the exact place an exception is most expensive.
|
||||
> An hid-matched driver (ps2-bus) is a singleton that finds its own devices once
|
||||
> spawned — spawn it once, no device assignment.
|
||||
|
||||
**D6 stays blocked** until this is answered — closing `device_claim` with these two
|
||||
still depending on it would stop the machine booting.
|
||||
`device_claim` is the mechanism that makes that pattern work. **D6 removes it and puts
|
||||
nothing in its place**, which is the whole of the blockage.
|
||||
|
||||
The manager is not ignorant: it matched *both* `PNP0303` and `PNP0F13` to `ps2-bus` and
|
||||
chose not to assign either, so it already knows which devices a singleton wants. An
|
||||
answer is therefore in reach — hand a singleton each matching device as it matches. The
|
||||
cost: only the first can ride the spawn, so later ones arrive while the driver is
|
||||
running, and `ps2-bus` enumerates once at startup and would have to tolerate that.
|
||||
|
||||
**The decision: do singletons stop being singletons — one instance per device, like
|
||||
everything else — or does the system keep a second acquisition path for them?** The
|
||||
first is uniform and costs a rewrite of `ps2-bus`'s startup. The second keeps a
|
||||
mechanism whose only remaining users are two drivers, and every exemption in an
|
||||
authority model is somewhere the model does not hold.
|
||||
|
||||
Nothing else blocks D6. Both invented ceilings are already gone, so this is about
|
||||
closing the claiming hole, not about a number.
|
||||
|
||||
### Settled 2026-08-08: the grant rides `system_spawn` (D0)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user