jcs's openbsd hax
openbsd

taskq_del_barrier(9) and timeout_del_barrier(9) should always call taskq_barrier(9) and timeout_barrier(9) respectively.

In the case that task or timeout were scheduled to run both
*_del_barrier(9) only remove it from pending queue and doesn't wait its
finish. However task could be simultaneously running and scheduled to the
next run, so they need to always wait until running handler has completed.

ok dlg

mvs 2ee1bbb5 0a255fef

+4 -7
+2 -4
sys/kern/kern_task.c
··· 1 - /* $OpenBSD: kern_task.c,v 1.35 2024/05/14 08:26:13 jsg Exp $ */ 1 + /* $OpenBSD: kern_task.c,v 1.36 2025/01/13 03:21:10 mvs Exp $ */ 2 2 3 3 /* 4 4 * Copyright (c) 2013 David Gwynne <dlg@openbsd.org> ··· 333 333 { 334 334 WITNESS_CHECKORDER(&tq->tq_lock_object, LOP_NEWORDER, NULL); 335 335 336 - if (task_del(tq, t)) 337 - return; 338 - 336 + task_del(tq, t); 339 337 taskq_do_barrier(tq); 340 338 } 341 339
+2 -3
sys/kern/kern_timeout.c
··· 1 - /* $OpenBSD: kern_timeout.c,v 1.100 2024/11/07 16:02:29 miod Exp $ */ 1 + /* $OpenBSD: kern_timeout.c,v 1.101 2025/01/13 03:21:10 mvs Exp $ */ 2 2 /* 3 3 * Copyright (c) 2001 Thomas Nordin <nordin@openbsd.org> 4 4 * Copyright (c) 2000-2001 Artur Grabowski <art@openbsd.org> ··· 457 457 timeout_sync_order(ISSET(to->to_flags, TIMEOUT_PROC)); 458 458 459 459 removed = timeout_del(to); 460 - if (!removed) 461 - timeout_barrier(to); 460 + timeout_barrier(to); 462 461 463 462 return removed; 464 463 }