kqueue: simplify knote_fdclose()
The influx logic in knote_fdclose() is a little misguided, the resulting wakeup() call should always be redundant: knote_drop_detached() will always issue a wakeup before it returns, so anything waiting on *that* knote that had entered fluxwait should have been woken up then. This is the obvious divergence from the other influx/wakeup pattern in the implementation, which will kn_influx-- and then issue the wakeup after it has processed all of the knotes it can make progress on. While we're here, the kq_knlist cannot shrink, so we can avoid that condition in the loop and avoid potentially excessive wakeups from fluxwait on kqueues that we didn't touch. Reviewed by: kib, markj Differential Revision: https://reviews.freebsd.org/D56210
This commit is contained in:
+12
-10
@@ -2836,7 +2836,6 @@ knote_fdclose(struct thread *td, int fd)
|
||||
struct filedesc *fdp = td->td_proc->p_fd;
|
||||
struct kqueue *kq;
|
||||
struct knote *kn;
|
||||
int influx;
|
||||
|
||||
FILEDESC_XLOCK_ASSERT(fdp);
|
||||
|
||||
@@ -2846,22 +2845,25 @@ knote_fdclose(struct thread *td, int fd)
|
||||
*/
|
||||
TAILQ_FOREACH(kq, &fdp->fd_kqlist, kq_list) {
|
||||
KQ_LOCK(kq);
|
||||
if (kq->kq_knlistsize <= fd ||
|
||||
SLIST_EMPTY(&kq->kq_knlist[fd])) {
|
||||
KQ_UNLOCK(kq);
|
||||
continue;
|
||||
}
|
||||
|
||||
again:
|
||||
influx = 0;
|
||||
while (kq->kq_knlistsize > fd &&
|
||||
(kn = SLIST_FIRST(&kq->kq_knlist[fd])) != NULL) {
|
||||
while ((kn = SLIST_FIRST(&kq->kq_knlist[fd])) != NULL) {
|
||||
if (kn_in_flux(kn)) {
|
||||
/* someone else might be waiting on our knote */
|
||||
if (influx)
|
||||
wakeup(kq);
|
||||
/*
|
||||
* Wait for this knote to stabilize, it could be
|
||||
* the case that it's in the process of being
|
||||
* dropped anyways.
|
||||
*/
|
||||
kq->kq_state |= KQ_FLUXWAIT;
|
||||
msleep(kq, &kq->kq_lock, PSOCK, "kqflxwt", 0);
|
||||
goto again;
|
||||
continue;
|
||||
}
|
||||
kn_enter_flux(kn);
|
||||
KQ_UNLOCK(kq);
|
||||
influx = 1;
|
||||
knote_drop(kn, td);
|
||||
KQ_LOCK(kq);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user