DF-5739 / fix_run.log
DF-5739 fix validation — patched module (fix.diff: exactly-once
atomic teardown guard + callout_drain/terminate), same race stress.
PASS 1 (100k arm / 100k discon / 50k frag rounds):
$ sysctl hw.hlh_race_arm=5 && sleep 3 && sysctl hw.hlh_state=1 # sanity ok
$ (sysctl hw.hlh_race_discon=100000 &); (sysctl hw.hlh_race_frag=50000 &); sleep 1
$ sysctl hw.hlh_race_arm=100000
PASS1_ARM_DONE
$ dmesg | grep -ac "already freed"
0
guest: up
-> the double-kfree panic did NOT recur.
PASS 2 (150k arm / 150k discon / 100k frag rounds):
$ (sysctl hw.hlh_race_discon=150000 &); (sysctl hw.hlh_race_frag=100000 &); sleep 1
$ sysctl hw.hlh_race_arm=150000
... guest died during the pass; serial console (fix_panic_patched.txt):
hcih0: dropped incomplete ACL packet (rx-path prints, concurrent)
...
panic with 1 spinlocks held
panic: Bad link elm 0xfffff8011954ee28 next->prev != elm
cpuid = 0
Trace beginning at frame 0xfffff8008d1f8a50
lwkt_spin_getport() at lwkt_spin_getport+0x134 (mis-symbolized module frames)
lwkt_spin_getport() at lwkt_spin_getport+0x134
netmsg_service_loop() at netmsg_service_loop+0xaf
Debugger("panic")
-> QUEUEDEBUG list-consistency panic (sys/sys/queue.h:392/525): the
still-unserialized TAILQ_INSERT_HEAD in hci_link_alloc() (arm
thread) raced TAILQ_REMOVE in hci_link_free() (netisr/softclock)
on unit->hci_links — a SIBLING manifestation of the same missing
serialization, not the patched double-kfree path.
CONCLUSION: fix is PARTIAL.
- the demonstrated primitive (double kfree from two hci_link_free()
contexts) did not recur under the patched build;
- the same stress still corrupts the system through other
unsynchronized entry points (link-list mutation);
- full remediation = serialize the netbt link lifecycle + refcount
handle-lookup users (upstream design change).
fix_status: inconclusive