release processing KN only when kq_scan has >0 max events. Because calling kevent with =0 max events doesn't mean all events are processed. This results in a subtle race of pre-releasing unprocessed knotes.
This commit is contained in:
parent
d535232e92
commit
61067bc214
@ -2044,6 +2044,7 @@ kqueue_register(struct kqueue *kq, struct kevq *kevq, struct kevent *kev, struct
|
|||||||
KQ_UNLOCK(kq);
|
KQ_UNLOCK(kq);
|
||||||
|
|
||||||
knote_drop(kn, td);
|
knote_drop(kn, td);
|
||||||
|
CTR3(KTR_KQ, "kqueue_register: kq %p deleted kn %p, fd %d", kq, kn, kev->ident);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3068,11 +3069,6 @@ kqueue_scan(struct kevq *kevq, int maxevents, struct kevent_copyops *k_ops,
|
|||||||
error = 0;
|
error = 0;
|
||||||
haskqglobal = 0;
|
haskqglobal = 0;
|
||||||
|
|
||||||
KEVQ_LOCK(kevq);
|
|
||||||
/* release processing knotes first */
|
|
||||||
kevq_rel_proc_kn(kevq);
|
|
||||||
KEVQ_UNLOCK(kevq);
|
|
||||||
|
|
||||||
// it's important that this is done before activate
|
// it's important that this is done before activate
|
||||||
if (maxevents == 0)
|
if (maxevents == 0)
|
||||||
goto done_nl;
|
goto done_nl;
|
||||||
@ -3082,6 +3078,11 @@ kqueue_scan(struct kevq *kevq, int maxevents, struct kevent_copyops *k_ops,
|
|||||||
kevq_activate(kevq, td);
|
kevq_activate(kevq, td);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KEVQ_LOCK(kevq);
|
||||||
|
/* release processing knotes first */
|
||||||
|
kevq_rel_proc_kn(kevq);
|
||||||
|
KEVQ_UNLOCK(kevq);
|
||||||
|
|
||||||
/* adjust max events according to the target frequency */
|
/* adjust max events according to the target frequency */
|
||||||
if ((kq->kq_flags & KQ_FLAG_MULTI) && kq->kq_tfreq > 0 && kevq->kevq_avg_lat > 0) {
|
if ((kq->kq_flags & KQ_FLAG_MULTI) && kq->kq_tfreq > 0 && kevq->kevq_avg_lat > 0) {
|
||||||
/* expected events per syscall
|
/* expected events per syscall
|
||||||
@ -4199,7 +4200,7 @@ knote_activate(struct knote *kn)
|
|||||||
|
|
||||||
KQ_NOTOWNED(kq);
|
KQ_NOTOWNED(kq);
|
||||||
|
|
||||||
CTR2(KTR_KQ, "knote_activate: kn %p, flags %d", kn, kn->kn_status);
|
CTR3(KTR_KQ, "knote_activate: kn %p, fd %d, flags %d", kn, kn->kn_id, kn->kn_status);
|
||||||
KN_FLUX_NOTOWNED(kn);
|
KN_FLUX_NOTOWNED(kn);
|
||||||
KASSERT(kn_in_flux(kn), ("knote %p not in flux", kn));
|
KASSERT(kn_in_flux(kn), ("knote %p not in flux", kn));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user