summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_sched.c
diff options
context:
space:
mode:
authormpi <mpi@openbsd.org>2015-10-16 19:07:24 +0000
committermpi <mpi@openbsd.org>2015-10-16 19:07:24 +0000
commitfc08c3564c7be825f49b082f30a8fd948834bd03 (patch)
tree38c92c9329870faa0d4fd939234878e9c6bc5f9e /sys/kern/kern_sched.c
parentlife is simpler if all requests go in the fifo, and then just remove them (diff)
downloadwireguard-openbsd-fc08c3564c7be825f49b082f30a8fd948834bd03.tar.xz
wireguard-openbsd-fc08c3564c7be825f49b082f30a8fd948834bd03.zip
Make sched_barrier() use its own task queue to avoid deadlocks.
Prevent a deadlock from occuring when intr_barrier() is called from a non-primary CPU in the watchdog task, also enqueued on ``systq''. ok kettenis@
Diffstat (limited to 'sys/kern/kern_sched.c')
-rw-r--r--sys/kern/kern_sched.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c
index a1fa25a54eb..8cd86597bc5 100644
--- a/sys/kern/kern_sched.c
+++ b/sys/kern/kern_sched.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sched.c,v 1.38 2015/09/20 22:05:14 kettenis Exp $ */
+/* $OpenBSD: kern_sched.c,v 1.39 2015/10/16 19:07:24 mpi Exp $ */
/*
* Copyright (c) 2007, 2008 Artur Grabowski <art@openbsd.org>
*
@@ -52,6 +52,10 @@ uint64_t sched_stolen; /* Times we stole proc from other cpus */
uint64_t sched_choose; /* Times we chose a cpu */
uint64_t sched_wasidle; /* Times we came out of idle */
+#ifdef MULTIPROCESSOR
+struct taskq *sbartq;
+#endif
+
/*
* A few notes about cpu_switchto that is implemented in MD code.
*
@@ -94,6 +98,13 @@ sched_init_cpu(struct cpu_info *ci)
*/
cpuset_init_cpu(ci);
cpuset_add(&sched_all_cpus, ci);
+
+#ifdef MULTIPROCESSOR
+ sbartq = taskq_create("sbar", 1, IPL_NONE,
+ TASKQ_MPSAFE | TASKQ_CANTSLEEP);
+ if (sbartq == NULL)
+ panic("unable to create sbar taskq");
+#endif
}
void
@@ -668,7 +679,7 @@ sched_barrier(struct cpu_info *ci)
task_set(&task, sched_barrier_task, ci);
spc = &ci->ci_schedstate;
spc->spc_barrier = 0;
- task_add(systq, &task);
+ task_add(sbartq, &task);
while (!spc->spc_barrier) {
sleep_setup(&sls, &spc->spc_barrier, PWAIT, "sbar");
sleep_finish(&sls, !spc->spc_barrier);