DF-4466 / run.log
=== DF-4466 baseline reproduction (unpatched kernel, 3 independent runs) ===
uname: DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64
--- RUN 1: variant F0 (deterministic: in-flight read parked 12s in dm-delay,
--- reload with FAST table, resume destroys old crypt config) ---
[F] cd0 = crypt -> dl0 (12s delay) -> /dev/vn0
[reader 69.6s] warmup pread n=512
[reader 69.6s] REAL pread dispatched (held ~5s in delay)
[F 7.0s] suspend + reload FAST table (crypt->/dev/vn0 direct) + resume => probe is fast, OLD priv freed NOW
[F 7.0s] resume returned => OLD crypt priv is freed; bio completes at ~+12s into freed memory
(ssh session died - guest panicked)
Serial console (boot.log):
Fatal trap 12: page fault while in kernel mode
cpuid = 3; lapic id = 3
fault virtual address = 0x0
fault code = supervisor write data, page not present
instruction pointer = 0x8:0xffffffff8065c482
stack pointer = 0x10:0xfffff80116a7e7b0
frame pointer = 0x10:0xfffff80116a7e7f0
processor eflags = interrupt enabled, resume, IOPL = 0
current process = Idle
kernel: type 12 trap, code=2
CPU3 stopping CPUs: 0x00000037
stopped
Stopped at mpipe_alloc_callback+0x1a2: movq %rcx,(%rax)
db>
--- RUN 2: variant F0 (identical setup) ---
(ssh session died - guest panicked)
Serial console: identical signature:
Fatal trap 12 ... Stopped at mpipe_alloc_callback+0x1a2: movq %rcx,(%rax)
(cpuid = 5)
--- RUN 3: variant F2 (F0 + valid-config spray of 6 fresh crypt devices) ---
[F 13.0s] suspend + reload FAST table ... OLD priv freed NOW
[F 13.0s] resume returned => OLD crypt priv is freed; bio completes at ~+12s into freed memory
[F 13.2s] valid-config spray done (key2)
[F 14.2s ... 22.2s] waiting for completion...
(ssh session died - guest panicked)
Serial console: identical signature: Fatal trap 12 ... mpipe_alloc_callback+0x1a2
=== supporting observations (same bug, other manifestations) ===
(a) variant A/C with reload-equal-table: resume blocks for exactly the delay
period because dmsetdiskinfo()->disk_config() waits for the async label
probe whose reads traverse the same (slow) reload table. This accidental
serialization is the ONLY thing standing between variant B and the race
when the reloaded table is equally slow. It does not drain arbitrary
in-flight bios (see VERDICT.md).
(b) variant D (write hammer through the delay stack + remove):
writers end up in permanent D state; ps -axHww shows all writer threads
stuck in disk wait forever (ps_hang_variantD.txt): in-flight bios whose
completions depended on the destroyed table never complete.
PID TID TT STAT TIME COMMAND
2436 2 ?? D2 0:00.00 ./dmrace D /dev/vn0 131072
2436 3 ?? D0 0:00.01 ./dmrace D /dev/vn0 131072
2436 4 ?? D1 0:00.01 ./dmrace D /dev/vn0 131072
2436 5 ?? D2 0:00.00 ./dmrace D /dev/vn0 131072