Index: sys/kern/kern_event.c =================================================================== --- sys/kern/kern_event.c +++ sys/kern/kern_event.c @@ -427,6 +427,19 @@ * process is gone, so flag the event as finished. */ if (event == NOTE_EXIT) { + /* + * If knote is in kqueue_scan() and process is exiting, before + * setting kn_knlist to null allow kqueue_scan to process the + * knote so that KN_LIST_LOCK and UNLOCK can succeed + */ + if ((kn->kn_status & KN_SCAN) && (p->p_flag & P_WEXIT)) { + kn->kn_status |= KN_WAKEUP; + if (kn->kn_status & KN_HASKQLOCK) + KQ_UNLOCK(kn->kn_kq); + msleep(kn->kn_knlist, &p->p_mtx, PWAIT, "knexit", 0); + if (kn->kn_status & KN_HASKQLOCK) + KQ_LOCK(kn->kn_kq); + } if (!(kn->kn_status & KN_DETACHED)) knlist_remove_inevent(&p->p_klist, kn); kn->kn_flags |= (EV_EOF | EV_ONESHOT); @@ -1575,6 +1588,10 @@ kn->kn_status &= ~(KN_INFLUX | KN_SCAN); KN_LIST_UNLOCK(kn); + if (kn->kn_status & KN_WAKEUP) { + kn->kn_status &= ~KN_WAKEUP; + wakeup(kn->kn_knlist); + } influx = 1; } Index: sys/sys/event.h =================================================================== --- sys/sys/event.h +++ sys/sys/event.h @@ -240,6 +240,7 @@ #define KN_KQUEUE 0x40 /* this knote belongs to a kq */ #define KN_HASKQLOCK 0x80 /* for _inevent */ #define KN_SCAN 0x100 /* flux set in kqueue_scan() */ +#define KN_WAKEUP 0x200 /* for wakeup */ int kn_sfflags; /* saved filter flags */ intptr_t kn_sdata; /* saved data field */ union {