Use klist_invalidate() in knote_processexit()

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Use klist_invalidate() in knote_processexit()

Visa Hankala-2
knote_processexit() uses knote_remove() to clear any remaining knotes
from &pr->ps_klist when process `pr' exits. All EVFILT_PROC knotes are
removed by the KNOTE(&pr->ps_klist, NOTE_EXIT) call. However, ps_klist
can contain EVFILT_SIGNAL knotes after the KNOTE().

To reserve knote_remove() for the kqueue subsystem's internal use, the
diff below makes knote_processexit() use klist_invalidate() instead.
For now, knote_remove() and klist_invalidate() are quite similar.
However, more differences will arise with fine-grained locking, and
knote_remove() will no longer be appropriate for knote_processexit().

To keep the existing behaviour with EVFILT_SIGNAL knotes, the diff
adjusts klist_invalidate() to drop non-fd-based knotes instead of
activating them with an EOF condition. This overloading of FILTEROP_ISFD
should be fine because EVFILT_PROC, EVFILT_SIGNAL and EVFILT_TIMER
are the only filter types that are not fd-based; EVFILT_PROC and
EVFILT_SIGNAL use the same knote list, whereas EVFILT_TIMER does not
use a knote list. The existing uses of klist_invalidate() should not
be affected.

OK?

Index: kern/kern_event.c
===================================================================
RCS file: src/sys/kern/kern_event.c,v
retrieving revision 1.140
diff -u -p -r1.140 kern_event.c
--- kern/kern_event.c 22 Jun 2020 13:14:32 -0000 1.140
+++ kern/kern_event.c 29 Jun 2020 16:10:14 -0000
@@ -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);
 }