Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 25 Feb 2019 08:50:26 +0000 (UTC)
From:      Vincenzo Maffione <vmaffione@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r344508 - stable/12/sys/dev/netmap
Message-ID:  <201902250850.x1P8oQL3007097@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: vmaffione
Date: Mon Feb 25 08:50:25 2019
New Revision: 344508
URL: https://svnweb.freebsd.org/changeset/base/344508

Log:
  MFC r344253
  
  netmap: don't schedule kqueue notify task when kqueue is not used
  
  This change adds a counter (kqueue_users) to keep track of how many
  kqueue users are referencing a given struct nm_selinfo.
  In this way, nm_os_selwakeup() can schedule the kevent notification
  task only when kqueue is actually being used.
  This is important to avoid wasting CPU in the common case where
  kqueue is not used.
  
  Reviewed by:    Aleksandr Fedorov <aleksandr.fedorov@itglobal.com>
  Differential Revision:  https://reviews.freebsd.org/D19177

Modified:
  stable/12/sys/dev/netmap/netmap_freebsd.c
  stable/12/sys/dev/netmap/netmap_kern.h
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/dev/netmap/netmap_freebsd.c
==============================================================================
--- stable/12/sys/dev/netmap/netmap_freebsd.c	Mon Feb 25 03:29:12 2019	(r344507)
+++ stable/12/sys/dev/netmap/netmap_freebsd.c	Mon Feb 25 08:50:25 2019	(r344508)
@@ -105,6 +105,7 @@ int nm_os_selinfo_init(NM_SELINFO_T *si, const char *n
 	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;

Modified: stable/12/sys/dev/netmap/netmap_kern.h
==============================================================================
--- stable/12/sys/dev/netmap/netmap_kern.h	Mon Feb 25 03:29:12 2019	(r344507)
+++ stable/12/sys/dev/netmap/netmap_kern.h	Mon Feb 25 08:50:25 2019	(r344508)
@@ -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;
 };
 
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201902250850.x1P8oQL3007097>