summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincenzo Maffione <vmaffione@FreeBSD.org>2019-02-18 14:21:41 +0000
committerVincenzo Maffione <vmaffione@FreeBSD.org>2019-02-18 14:21:41 +0000
commit45100257c683b4421bbf134238df2c3b3aba6fad (patch)
tree8d27d1fcb340ef025618d9275e3fea92e54c21cc
parent19a227ee354eee259f8a61ae537e8bc3f4c72a92 (diff)
Notes
-rw-r--r--sys/dev/netmap/netmap_freebsd.c29
-rw-r--r--sys/dev/netmap/netmap_kern.h3
2 files changed, 25 insertions, 7 deletions
diff --git a/sys/dev/netmap/netmap_freebsd.c b/sys/dev/netmap/netmap_freebsd.c
index d99e526f3d10..c6cd24461b6b 100644
--- a/sys/dev/netmap/netmap_freebsd.c
+++ b/sys/dev/netmap/netmap_freebsd.c
@@ -105,6 +105,7 @@ int nm_os_selinfo_init(NM_SELINFO_T *si, const char *name) {
snprintf(si->mtxname, sizeof(si->mtxname), "nmkl%s", name);
mtx_init(&si->m, si->mtxname, NULL, MTX_DEF);
knlist_init_mtx(&si->si.si_note, &si->m);
+ si->kqueue_users = 0;
return (0);
}
@@ -1351,7 +1352,9 @@ void
nm_os_selwakeup(struct nm_selinfo *si)
{
selwakeuppri(&si->si, PI_NET);
- taskqueue_enqueue(si->ntfytq, &si->ntfytask);
+ if (si->kqueue_users > 0) {
+ taskqueue_enqueue(si->ntfytq, &si->ntfytask);
+ }
}
void
@@ -1364,20 +1367,28 @@ static void
netmap_knrdetach(struct knote *kn)
{
struct netmap_priv_d *priv = (struct netmap_priv_d *)kn->kn_hook;
- struct selinfo *si = &priv->np_si[NR_RX]->si;
+ struct nm_selinfo *si = priv->np_si[NR_RX];
- nm_prinf("remove selinfo %p", si);
- knlist_remove(&si->si_note, kn, /*islocked=*/0);
+ knlist_remove(&si->si.si_note, kn, /*islocked=*/0);
+ NMG_LOCK();
+ KASSERT(si->kqueue_users > 0, ("kqueue_user underflow on %s",
+ si->mtxname));
+ si->kqueue_users--;
+ nm_prinf("kqueue users for %s: %d", si->mtxname, si->kqueue_users);
+ NMG_UNLOCK();
}
static void
netmap_knwdetach(struct knote *kn)
{
struct netmap_priv_d *priv = (struct netmap_priv_d *)kn->kn_hook;
- struct selinfo *si = &priv->np_si[NR_TX]->si;
+ struct nm_selinfo *si = priv->np_si[NR_TX];
- nm_prinf("remove selinfo %p", si);
- knlist_remove(&si->si_note, kn, /*islocked=*/0);
+ knlist_remove(&si->si.si_note, kn, /*islocked=*/0);
+ NMG_LOCK();
+ si->kqueue_users--;
+ nm_prinf("kqueue users for %s: %d", si->mtxname, si->kqueue_users);
+ NMG_UNLOCK();
}
/*
@@ -1465,6 +1476,10 @@ netmap_kqfilter(struct cdev *dev, struct knote *kn)
kn->kn_fop = (ev == EVFILT_WRITE) ?
&netmap_wfiltops : &netmap_rfiltops;
kn->kn_hook = priv;
+ NMG_LOCK();
+ si->kqueue_users++;
+ nm_prinf("kqueue users for %s: %d", si->mtxname, si->kqueue_users);
+ NMG_UNLOCK();
knlist_add(&si->si.si_note, kn, /*islocked=*/0);
return 0;
diff --git a/sys/dev/netmap/netmap_kern.h b/sys/dev/netmap/netmap_kern.h
index f8db7a38ac9c..ef2b1bcf0fb5 100644
--- a/sys/dev/netmap/netmap_kern.h
+++ b/sys/dev/netmap/netmap_kern.h
@@ -132,11 +132,14 @@ struct netmap_adapter *netmap_getna(if_t ifp);
#define MBUF_QUEUED(m) 1
struct nm_selinfo {
+ /* Support for select(2) and poll(2). */
struct selinfo si;
+ /* Support for kqueue(9). See comments in netmap_freebsd.c */
struct taskqueue *ntfytq;
struct task ntfytask;
struct mtx m;
char mtxname[32];
+ int kqueue_users;
};