diff options
author | Visa Hankala <visa@cvs.openbsd.org> | 2020-04-07 12:52:28 +0000 |
---|---|---|
committer | Visa Hankala <visa@cvs.openbsd.org> | 2020-04-07 12:52:28 +0000 |
commit | a469bdd2f75259dda9613501bb83503033815c3c (patch) | |
tree | 3718933c14139b862e7172c456ac177d4260f9a9 /sys/kern | |
parent | b3679f4e3174a00fb54acb6c3ba8bf00aa56bdfb (diff) |
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@
Diffstat (limited to 'sys/kern')
-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)) |