Index: sys/dev/netmap/netmap_freebsd.c =================================================================== --- sys/dev/netmap/netmap_freebsd.c +++ sys/dev/netmap/netmap_freebsd.c @@ -58,6 +58,7 @@ #include /* RFNOWAIT */ #include /* sched_bind() */ #include /* mp_maxid */ +#include /* taskqueue_enqueue(), taskqueue_drain()*/ #include #include #include /* IFT_ETHER */ @@ -75,16 +76,29 @@ /* ======================== FREEBSD-SPECIFIC ROUTINES ================== */ +static void +nm_kqueue_notify(void *opaque, int pending) +{ + struct nm_selinfo *si = opaque; + + /* We use a non-zero hint to distinguish this notification call + * from the call done in kqueue_scan(), which uses hint=0. + */ + KNOTE_UNLOCKED(&si->si.si_note, /*hint=*/0x100); +} + void nm_os_selinfo_init(NM_SELINFO_T *si) { struct mtx *m = &si->m; mtx_init(m, "nm_kn_lock", NULL, MTX_DEF); knlist_init_mtx(&si->si.si_note, m); + TASK_INIT(&si->ntfytask, 0, nm_kqueue_notify, si); } void nm_os_selinfo_uninit(NM_SELINFO_T *si) { /* XXX kqueue(9) needed; these will mirror knlist_init. */ + taskqueue_drain(taskqueue_swi, &si->ntfytask); knlist_delete(&si->si.si_note, curthread, /*islocked=*/0); knlist_destroy(&si->si.si_note); /* now we don't need the mutex anymore */ @@ -1315,11 +1329,7 @@ if (netmap_verbose) nm_prinf("on knote %p", &si->si.si_note); selwakeuppri(&si->si, PI_NET); - /* We use a non-zero hint to distinguish this notification call - * from the call done in kqueue_scan(), which uses hint=0. - */ - KNOTE(&si->si.si_note, /*hint=*/0x100, - mtx_owned(&si->m) ? KNF_LISTLOCKED : 0); + taskqueue_enqueue(taskqueue_swi, &si->ntfytask); } void Index: sys/dev/netmap/netmap_kern.h =================================================================== --- sys/dev/netmap/netmap_kern.h +++ sys/dev/netmap/netmap_kern.h @@ -134,6 +134,7 @@ struct nm_selinfo { struct selinfo si; struct mtx m; + struct task ntfytask; };