DF-5638 / run_baseline.log
DF-5636/5637/5638 BASELINE RUN -- unmodified production code
Guest: DragonFly 6.5-DEVELOPMENT #0 (image kernel, Jul 2 2026) -- smbus
compiled into X86_64_GENERIC (config line 335), iicbus/iicbb/iicsmb loaded
from unmodified /boot/kernel/*.ko. Chain: fakebb0 -> iicbb0 -> iicbus0 ->
iicsmb0 -> smbus0. Wire sanity round trip passes before every test.
$ kldload iicbus.ko iicbb.ko iicbb_reg.ko df5636_rig.ko iicsmb.ko
fakebb0: <DF-5636 fake GPIO bit-bang i2c master+slave> on motherboard
iicbb0: <I2C bit-banging driver> on fakebb0
iicbus0: <Philips I2C bus> on iicbb0 addr 0x0
[df5636] attach done: iicbus=0xfffff801175bbb60 cdev=0xfffff8008da31c80 busy=0 (now: kldload iicsmb)
[df5636] sanity iicbus_request_bus error=0
[df5636] SANITY: write_ok=1 read_ok=1 starts=2 stops=2
iicsmb0: <SMBus over I2C bridge> on iicbus0
smbus0: <System Management Bus> on iicsmb0
================ F1: wake-path phantom grant (DF-5636) ================
$ ./df5636ctl f1 -> summary=0x3 (phantom grant + double grant)
[df5636] F1.1 request(devA=fakebb0)=0 owner=0xfffff801175bbca0
[df5636] T(devB): calling smbus_request_bus(iicbb0, how=0x3) softc=0xfffff8008d561050
[df5636] F1.2 owner while devB parked=0xfffff801175bbca0 (devA=0xfffff801175bbca0 devB=0xfffff801175ff080)
[df5636] F1.3 release(devA)=0 owner=0
[df5636] T(devB): request RETURNED 0
[df5636] T(devB): sc->owner=0 (caller=0xfffff801175ff080) <<< PHANTOM GRANT: success returned, owner is NOT the caller
[df5636] F1.3w 000ms after release: owner=0 t1.done=1
[df5636] T(devC): calling smbus_request_bus(iicbus0, how=0x3) softc=0xfffff8008d561050
[df5636] T(devC): request RETURNED 0
[df5636] T(devC): sc->owner=0xfffff801175fefe0 (caller=0xfffff801175fefe0)
[df5636] F1.4 after 1s of devC request: owner=0xfffff801175fefe0 devC.done=1 (1 = granted immediately)
[df5636] F1.5 release(devB)=13
[df5636] F1.5b cleanup release(devC)=0 owner=0
[df5636] F1.6 final owner=0 (clean=NULL) t1.done=1 t2.done=1
==> devB was woken by the release and returned SUCCESS (0) without
sc->owner ever being set to it; devC then also granted => two
concurrent callers both believe they hold the bus (DOUBLE GRANT).
F1.5: devB's own release() = EACCES(13) AND (observed live in the
first baseline session) it tore down the iicbus under devC.
================ F2: SMB_DONTWAIT phantom grant (DF-5636) ==============
(from the first baseline session; owner was left = devC by F1's wedge,
which is itself DF-5637's teardown consequence -- the F2 lines show the
DONTWAIT leg on a bus verifiably owned by ANOTHER device)
[df5636] F2.1 request(devA)=-1 owner=0xfffff801175bbb60
[df5636] F2.2 request(devB, SMB_DONTWAIT)=0 owner=0xfffff801175bbb60 caller=0xfffff801175bbc00 <<< PHANTOM GRANT (must be EWOULDBLOCK)
[df5636] F2.3 cleanup release(devA)=13 owner=0xfffff801175bbb60
================ F3: non-owner release teardown (DF-5637) ==============
$ ./df5636ctl f3 -> summary=0x1
[df5636] F3.1 request(devA)=0 owner=0xfffff801175bbca0 (iicbus now held via iicsmb)
[df5636] F3.2 NON-owner release(devB)=13 smbus owner still=0xfffff801175bbca0
[df5636] F3.3 iicbus probe request(devC, DONTWAIT)=0 <<< iicbus TORN DOWN by the non-owner release while devA owns smbus
[df5636] F3.4 cleanup release(devA)=0 owner=0
==> A device that does NOT own the smbus had its release() answered
EACCES at the smbus level, but the underlying iicbus exclusion was
ALREADY released (probe granted) while the real owner devA was
still mid-ownership.
================ F3B: EACCES release wakes waiter into grant ===========
$ ./df5636ctl f3b -> summary=0x1
[df5636] F3B.1 request(devA)=0 owner=0xfffff801175bbca0
[df5636] T(devB): calling smbus_request_bus(iicbb0, how=0x3) softc=0xfffff8008d561050
[df5636] F3B.2 owner while devB parked=0xfffff801175bbca0 (devA=0xfffff801175bbca0)
[df5636] F3B.3 NON-owner release(devC)=13 owner STILL=0xfffff801175bbca0
[df5636] F3B.3w t1 verdict: error=0 owner_seen=0xfffff801175bbca0 (devA=0xfffff801175bbca0) <<< GRANTED while another device verifiably OWNS the bus (no release ever happened)
==> smbconf.c:177's unconditional wakeup(sc) on the EACCES path woke
the parked requester; the broken loop turned it into a success
return WHILE devA STILL OWNS the bus. No release happened at all.
================ F5/PARK: unkillable smbreq park (DF-5638) =============
$ ./df5636ctl park & (PARK holds devA, then parks caller on request(devB, SMB_WAIT=0x1))
$ ps -o pid,stat,wchan,command -p $P
PID STAT WCHAN COMMAND
1742 D4 smbreq ./df5636ctl park <-- D state, non-PCATCH tsleep
$ kill -9 1742; sleep 1
$ ps -o pid,stat,wchan -p 1742
1742 D4 smbreq <-- SURVIVES kill -9
$ ./df5636ctl unpark
[df5636] PARK: holding bus with devA=0xfffff801175bbca0, parking caller on request(devB, SMB_WAIT=0x1)
[df5636] UNPARK: release(devA)=0
[df5636] PARK: woke: request(devB) returned 0 owner=0 caller=0xfffff8008bb64320 <<< phantom grant on wake
==> The user process sat UNKILLABLE (D state, kill -9 ineffective) in
tsleep(sc, 0, "smbreq", 0) -- smbconf.c:92-94 via SMB_WAIT (0x1).
The pending SIGKILL was only delivered after the unwedge, and the
wake path handed it a phantom grant.