# DF-5790 — `device_delete_child()` on a probed-but-unattached (DS_ALIVE) device leaks the driver softc

## Root cause

`device_delete_child()` (`sys/kern/subr_bus.c:1283-1310`) calls
`device_detach(child)` first.  For a child that was probed but never
attached (`state == DS_ALIVE`, exactly the state `device_probe_child()`
leaves at `sys/kern/subr_bus.c:1486`), `device_detach()` short-circuits:

```c
	if (dev->state != DS_ATTACHED)
		return(0);			/* subr_bus.c:2136-2137 */
```

without running the teardown at `sys/kern/subr_bus.c:2146-2151` — in
particular without `device_set_driver(dev, NULL)`, which is the only
subr_bus path that frees the softc allocated during probe
(`sys/kern/subr_bus.c:1952-1954`).  `device_delete_child()` then
destroys the device object (`kobj_delete(child, M_BUS)`,
`sys/kern/subr_bus.c:1306`), which frees the `struct bsd_device` only —
`kobj_delete()` (`sys/kern/subr_kobj.c:264-273`) never touches the
softc.  The probe softc is leaked.

The probed-but-unattached delete is driven in-tree by the USB
bus-explore path (`sys/bus/u4b/usb_device.c:1223` creates the temp
child, `:1415` deletes it, with `device_probe_and_attach()` in between)
and by the async-attach machinery; any driver that deletes children
between probe and attach leaks `driver->size` bytes of `M_BUS` per
cycle.

## Build / Run

Same rig as DF-5789 (the KLD also registers driver `dfleak`, softc size
8192):

```
cd /root/df5789 && make KERNBUILDDIR=/usr/obj/usr/src/sys/X86_64_GENERIC
sh run5790.sh     # 100 control cycles (no probe) + 200 leak cycles
```

## Expected (stock kernel)

* kernel log: `DF5790: 100 add/probe/delete cycles ... last child
  state=1 softc=0xfffff801186b4000 (LEAKED, never kfree'd)`
  (state 1 = DS_ALIVE);
* `vmstat -m` `bus` MemUse: 97.6K baseline → 97.7K after control →
  **898K after 100 probe cycles (+~800K = 100×8192)** → **1.66M after
  200** — and the 1.66M survives `kldunload` (permanent).

## Fixed kernel (fix.diff: release driver in device_delete_child)

* same 200 probe cycles: **97.7K → 97.7K → 97.7K** (zero growth).

## Files

`rig.c` (shared), `run.sh` (= run5790.sh), `run.log`, `fixrun.log`,
`build.log`, `fix.diff` (also fixes DF-5789).
