]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/commit
MFC r343579
authorVincenzo Maffione <vmaffione@FreeBSD.org>
Wed, 13 Feb 2019 09:03:23 +0000 (09:03 +0000)
committerVincenzo Maffione <vmaffione@FreeBSD.org>
Wed, 13 Feb 2019 09:03:23 +0000 (09:03 +0000)
commite8cc65cdb609724fff1f31aec5b526526503ec57
treef43916bf2357d8fd32ead1fddaf8f61480b056ee
parent7fa914bcf4b70b2e3dc36ca333b1fef50da660c5
MFC r343579

netmap: fix lock order reversal related to kqueue usage

When using poll(), select() or kevent() on netmap file descriptors,
netmap executes the equivalent of NIOCTXSYNC and NIOCRXSYNC commands,
before collecting the events that are ready. In other words, the
poll/kevent callback has side effects. This is done to avoid the
overhead of two system call per iteration (e.g., poll() + ioctl(NIOC*XSYNC)).

When the kqueue subsystem invokes the kqueue(9) f_event callback
(netmap_knrw), it holds the lock of the struct knlist object associated
to the netmap port (the lock is provided at initialization, by calling
knlist_init_mtx).
However, netmap_knrw() may need to wake up another netmap port (or even
the same one), which means that it may need to call knote().
Since knote() needs the lock of the struct knlist object associated to
the to-be-wake-up netmap port, it is possible to have a lock order reversal
problem (AB/BA deadlock).

This change prevents the deadlock by executing the knote() call in a
per-selinfo taskqueue, where it is possible to hold a mutex.

Reviewed by:    aleksandr.fedorov_itglobal.com
Differential Revision:  https://reviews.freebsd.org/D18956
sys/dev/netmap/netmap.c
sys/dev/netmap/netmap_freebsd.c
sys/dev/netmap/netmap_kern.h