summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvisa <visa@openbsd.org>2020-07-04 08:33:43 +0000
committervisa <visa@openbsd.org>2020-07-04 08:33:43 +0000
commit01647961ab59beedf2e97eb65a8c86bf847e244c (patch)
treec267753015153804d25fd3f575c9fd9385cbe3d9
parentIt's been agreed upon that global locks should be expressed using (diff)
downloadwireguard-openbsd-01647961ab59beedf2e97eb65a8c86bf847e244c.tar.xz
wireguard-openbsd-01647961ab59beedf2e97eb65a8c86bf847e244c.zip
Use klist_invalidate() in knote_processexit()
This leaves knote_remove() for kqueue's internal use. As a result, knote_remove() is used to drop knotes from the knlist of a single kqueue instance. klist_invalidate() clears knotes from a klist that can contain entries from different kqueue instances. Use FILTEROP_ISFD to control how klist_invalidate() treats knotes, to preserve the current behaviour of knote_processexit(). All the existing callers of klist_invalidate() are fd-based. The existing code rewires and activates knotes to give userspace a clear indication that the state of the fd has changed. In knote_processexit(), any remaining knotes in ps_klist are non-fd-based (EVFILT_SIGNAL). Those are dropped without notifying userspace. OK mpi@
-rw-r--r--sys/kern/kern_event.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index ddaf08795ec..b06ecf1820e 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_event.c,v 1.140 2020/06/22 13:14:32 mpi Exp $ */
+/* $OpenBSD: kern_event.c,v 1.141 2020/07/04 08:33:43 visa Exp $ */
/*-
* Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org>
@@ -1336,10 +1336,12 @@ knote_processexit(struct proc *p)
{
struct process *pr = p->p_p;
+ KASSERT(p == curproc);
+
KNOTE(&pr->ps_klist, NOTE_EXIT);
/* remove other knotes hanging off the process */
- knote_remove(p, &pr->ps_klist.kl_list);
+ klist_invalidate(&pr->ps_klist);
}
void
@@ -1446,6 +1448,7 @@ void
klist_invalidate(struct klist *list)
{
struct knote *kn;
+ struct proc *p = curproc;
int s;
/*
@@ -1460,10 +1463,15 @@ klist_invalidate(struct klist *list)
continue;
splx(s);
kn->kn_fop->f_detach(kn);
- kn->kn_fop = &dead_filtops;
- knote_activate(kn);
- s = splhigh();
- knote_release(kn);
+ if (kn->kn_fop->f_flags & FILTEROP_ISFD) {
+ kn->kn_fop = &dead_filtops;
+ knote_activate(kn);
+ s = splhigh();
+ knote_release(kn);
+ } else {
+ knote_drop(kn, p);
+ s = splhigh();
+ }
}
splx(s);
}