diff options
author | 2020-04-07 12:52:27 +0000 | |
---|---|---|
committer | 2020-04-07 12:52:27 +0000 | |
commit | c43697b96c1dd31ba6e9df83f9ad4b953cce6788 (patch) | |
tree | 081f7976c22887720d446575ba79a34d1f7170b9 | |
parent | Kill board_id variable; its last consumer is gone now. (diff) | |
download | wireguard-openbsd-c43697b96c1dd31ba6e9df83f9ad4b953cce6788.tar.xz wireguard-openbsd-c43697b96c1dd31ba6e9df83f9ad4b953cce6788.zip |
Defer selwakeup() from kqueue_wakeup() to kqueue_task() to prevent
deep recursion. This also helps making kqueue_wakeup() free of the
kernel lock because the current implementation of selwakeup()
requires the lock.
OK mpi@
-rw-r--r-- | sys/kern/kern_event.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index 8514d92b2c0..5eae8dc9095 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_event.c,v 1.129 2020/04/02 07:00:25 mpi Exp $ */ +/* $OpenBSD: kern_event.c,v 1.130 2020/04/07 12:52:27 visa Exp $ */ /*- * Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org> @@ -1102,7 +1102,12 @@ kqueue_task(void *arg) { struct kqueue *kq = arg; - KNOTE(&kq->kq_sel.si_note, 0); + if (kq->kq_state & KQ_SEL) { + kq->kq_state &= ~KQ_SEL; + selwakeup(&kq->kq_sel); + } else { + KNOTE(&kq->kq_sel.si_note, 0); + } KQRELE(kq); } @@ -1114,10 +1119,7 @@ kqueue_wakeup(struct kqueue *kq) kq->kq_state &= ~KQ_SLEEP; wakeup(kq); } - if (kq->kq_state & KQ_SEL) { - kq->kq_state &= ~KQ_SEL; - selwakeup(&kq->kq_sel); - } else if (!SLIST_EMPTY(&kq->kq_sel.si_note)) { + if ((kq->kq_state & KQ_SEL) || !SLIST_EMPTY(&kq->kq_sel.si_note)) { /* Defer activation to avoid recursion. */ KQREF(kq); if (!task_add(systq, &kq->kq_task)) |