kqueue: Revise badfd knote handling
authorvisa <visa@openbsd.org>
Mon, 29 Nov 2021 15:54:04 +0000 (15:54 +0000)
committervisa <visa@openbsd.org>
Mon, 29 Nov 2021 15:54:04 +0000 (15:54 +0000)
commit13ce2699ae7dee2b836e0a3a32b459922f3b6e20
tree8b58ef59e9fe0f90b687ef207f84b4dad3228b46
parent08d984e5bf9ac9ac33e6662fba04b2fc0680b237
kqueue: Revise badfd knote handling

When closing a file descriptor and converting the poll/select knotes
into badfd knotes, keep the knotes attached to the by-fd table. This
should prevent kqueue_purge() from returning before the kqueue has
become quiescent. This in turn should fix a
KASSERT(TAILQ_EMPTY(&kq->kq_head)) panic in KQRELE() that bluhm@ has
reported.

The badfd conversion is only needed when a poll/select scan is ongoing.
The system can skip the conversion if the knote is not part of the
active event set.

The code of this commit skips the conversion when the fd is closed by
the same thread that has done the fd polling. This can be improved but
should already cover typical fd usage patterns.

As badfd knotes now hold slots in the by-fd table, kqueue_register()
clears them. poll/select use kqueue_register() to set up a new scan;
any found fd close notification is a leftover from the previous scan.

The new badfd handling should be free of accidental knote accumulation.
This obsoletes kqpoll_dequeue() and lowers kqpoll_init() overhead.

Re-enable lazy removal of poll/select knotes because the panic should
no longer happen.

OK mpi@
sys/kern/kern_event.c
sys/sys/event.h