DF-4751 / panic.txt
# DF-4751 โ three captured Fatal trap 12 panics (kernel page faults) # All from: ./dm_unloadrace 30..45 (create<->remove churn on # /dev/mapper/control while another thread loops `kldunload dm; kldload dm`) # # Run 1 (dirty guest, stock dm.ko): in-flight ioctl on control dev raced unload Fatal trap 12: page fault while in kernel mode cpuid = 5; lapic id = 5 fault virtual address = 0xffffffff8260848c fault code = supervisor read data, page not present instruction pointer = 0x8:0xffffffff8062cd6b kernel: type 12 trap, code=0 Stopped at dev_dioctl+0x1b: movl 0xc(%rax),%edi # -> dev_dioctl (sys/kern/kern_device.c:237) reading through freed/stale ops # Run 2 (fresh `vm.sh reset with-src` guest, stock dm.ko): call through zeroed ops Fatal trap 12: page fault while in kernel mode cpuid = 4; lapic id = 4 fault virtual address = 0x0 fault code = supervisor read instruction, page not present instruction pointer = 0x8:0x0 kernel: type 12 trap, code=10 Stopped at 0: # -> dispatch through a NULL/freed d_ioctl entry # Run 3 (fix v1: destroy_dev+re-arm before counter check, patched dm.ko): # still panics โ executing freed module text fault virtual address = 0xffffffff82601029 fault code = supervisor read instruction, page not present instruction pointer = 0x8:0xffffffff82601029 Stopped at -0x7d9fefd7: # Run 4 (fix v2: + sync_devs(), patched dm.ko): still panics โ INSIDE dmioctl Fatal trap 12: page fault while in kernel mode cpuid = 4; lapic id = 4 fault virtual address = 0xffffffff8260078f fault code = supervisor read instruction, page not present instruction pointer = 0x8:0xffffffff8260078f Stopped at dmioctl+0x2bf: movq -0x38(%rbp),%rdi # => an ioctl already executing dmioctl (sys/dev/disk/dm/device-mapper.c:241) # when the linker freed the module text: dev_dioctl holds no reference on # si_ops across the dispatch (kern_device.c:258), and destroy_dev()'s # revector to dead_dev_ops happens asynchronously in the devfs core # (sys/vfs/devfs/devfs_core.c:755-765), so sync_devs() cannot cover # already-entered calls. # Corroborating console noise on EVERY crashing run (counter-check race): malloc_uninit: 1984 bytes of 'dm' still allocated on cpu 6 # -> devices/allocations created after the unlocked dm_dev_counter>0 read # (device-mapper.c:161) still existed when dmdestroy() ran.