Allow sleeping while clearing a sleep timeout
authorvisa <visa@openbsd.org>
Sun, 12 Jun 2022 10:36:04 +0000 (10:36 +0000)
committervisa <visa@openbsd.org>
Sun, 12 Jun 2022 10:36:04 +0000 (10:36 +0000)
commitef428a5ea72686171402e8ebffa1276567c0409e
tree3c849b8fc93546a8f1c268f877d851ade0b3b176
parenta26b930e92d7c8b0f65a8bb58d831bb5db99b57f
Allow sleeping while clearing a sleep timeout

Since sys/kern/kern_timeout.c r1.84, timeout_barrier() has used sleeping
with soft-interrupt-driven timeouts. Adjust the sleep machinery so that
the timeout clearing can block in sleep_finish().

This adds one step of recursion inside sleep_finish(). However, the
sleep queue handling does not recurse because sleep_finish() completes
it before calling timeout_del_barrier().

This fixes the following panic:

panic: kernel diagnostic assertion "(p->p_flag & P_TIMEOUT) == 0" failed: file "sys/kern/kern_synch.c", line 373
Stopped at db_enter+0x10:  popq    %rbp
db_enter() at db_enter+0x10
panic() at panic+0xbf
__assert() at __assert+0x25
sleep_setup() at sleep_setup+0x1d8
cond_wait() at cond_wait+0x46
timeout_barrier() at timeout_barrier+0x109
timeout_del_barrier() at timeout_del_barrier+0xa2
sleep_finish() at sleep_finish+0x16d
tsleep() at tsleep+0xb2
sys_nanosleep() at sys_nanosleep+0x12d
syscall() at syscall+0x374

OK mpi@ dlg@
sys/kern/kern_synch.c