summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorVisa Hankala <visa@cvs.openbsd.org>2020-04-07 12:52:28 +0000
committerVisa Hankala <visa@cvs.openbsd.org>2020-04-07 12:52:28 +0000
commita469bdd2f75259dda9613501bb83503033815c3c (patch)
tree3718933c14139b862e7172c456ac177d4260f9a9 /sys/kern
parentb3679f4e3174a00fb54acb6c3ba8bf00aa56bdfb (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.c14
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))