Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 13 Feb 2012 18:56:34 +0000 (UTC)
From:      Luigi Rizzo <luigi@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r231594 - head/sys/dev/netmap
Message-ID:  <201202131856.q1DIuYCo056761@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: luigi
Date: Mon Feb 13 18:56:34 2012
New Revision: 231594
URL: http://svn.freebsd.org/changeset/base/231594

Log:
  - use struct ifnet as explicit type of the argument to the
    txsync() and rxsync() callbacks, removing some variables made
    useless by this change;
  
  - add generic lock and irq handling routines. These can be useful
    in case there are no driver locks that we can reuse;
  
  - add a few macros to reduce differences with the Linux version.

Modified:
  head/sys/dev/netmap/if_em_netmap.h
  head/sys/dev/netmap/if_igb_netmap.h
  head/sys/dev/netmap/if_lem_netmap.h
  head/sys/dev/netmap/if_re_netmap.h
  head/sys/dev/netmap/ixgbe_netmap.h
  head/sys/dev/netmap/netmap.c
  head/sys/dev/netmap/netmap_kern.h

Modified: head/sys/dev/netmap/if_em_netmap.h
==============================================================================
--- head/sys/dev/netmap/if_em_netmap.h	Mon Feb 13 18:54:15 2012	(r231593)
+++ head/sys/dev/netmap/if_em_netmap.h	Mon Feb 13 18:56:34 2012	(r231594)
@@ -42,9 +42,9 @@
 static void	em_netmap_block_tasks(struct adapter *);
 static void	em_netmap_unblock_tasks(struct adapter *);
 static int	em_netmap_reg(struct ifnet *, int onoff);
-static int	em_netmap_txsync(void *, u_int, int);
-static int	em_netmap_rxsync(void *, u_int, int);
-static void	em_netmap_lock_wrapper(void *, int, u_int);
+static int	em_netmap_txsync(struct ifnet *, u_int, int);
+static int	em_netmap_rxsync(struct ifnet *, u_int, int);
+static void	em_netmap_lock_wrapper(struct ifnet *, int, u_int);
 
 static void
 em_netmap_attach(struct adapter *adapter)
@@ -69,9 +69,9 @@ em_netmap_attach(struct adapter *adapter
  * wrapper to export locks to the generic code
  */
 static void
-em_netmap_lock_wrapper(void *_a, int what, u_int queueid)
+em_netmap_lock_wrapper(struct ifnet *ifp, int what, u_int queueid)
 {
-	struct adapter *adapter = _a;
+	struct adapter *adapter = ifp->if_softc;
 
 	ASSERT(queueid < adapter->num_queues);
 	switch (what) {
@@ -183,9 +183,9 @@ fail:
  * Reconcile hardware and user view of the transmit ring.
  */
 static int
-em_netmap_txsync(void *a, u_int ring_nr, int do_lock)
+em_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
 {
-	struct adapter *adapter = a;
+	struct adapter *adapter = ifp->if_softc;
 	struct tx_ring *txr = &adapter->tx_rings[ring_nr];
 	struct netmap_adapter *na = NA(adapter->ifp);
 	struct netmap_kring *kring = &na->tx_rings[ring_nr];
@@ -289,9 +289,9 @@ em_netmap_txsync(void *a, u_int ring_nr,
  * Reconcile kernel and user view of the receive ring.
  */
 static int
-em_netmap_rxsync(void *a, u_int ring_nr, int do_lock)
+em_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
 {
-	struct adapter *adapter = a;
+	struct adapter *adapter = ifp->if_softc;
 	struct rx_ring *rxr = &adapter->rx_rings[ring_nr];
 	struct netmap_adapter *na = NA(adapter->ifp);
 	struct netmap_kring *kring = &na->rx_rings[ring_nr];

Modified: head/sys/dev/netmap/if_igb_netmap.h
==============================================================================
--- head/sys/dev/netmap/if_igb_netmap.h	Mon Feb 13 18:54:15 2012	(r231593)
+++ head/sys/dev/netmap/if_igb_netmap.h	Mon Feb 13 18:56:34 2012	(r231594)
@@ -38,9 +38,9 @@
 #include <dev/netmap/netmap_kern.h>
 
 static int	igb_netmap_reg(struct ifnet *, int onoff);
-static int	igb_netmap_txsync(void *, u_int, int);
-static int	igb_netmap_rxsync(void *, u_int, int);
-static void	igb_netmap_lock_wrapper(void *, int, u_int);
+static int	igb_netmap_txsync(struct ifnet *, u_int, int);
+static int	igb_netmap_rxsync(struct ifnet *, u_int, int);
+static void	igb_netmap_lock_wrapper(struct ifnet *, int, u_int);
 
 
 static void
@@ -66,9 +66,9 @@ igb_netmap_attach(struct adapter *adapte
  * wrapper to export locks to the generic code
  */
 static void
-igb_netmap_lock_wrapper(void *_a, int what, u_int queueid)
+igb_netmap_lock_wrapper(struct ifnet *ifp, int what, u_int queueid)
 {
-	struct adapter *adapter = _a;
+	struct adapter *adapter = ifp->if_softc;
 
 	ASSERT(queueid < adapter->num_queues);
 	switch (what) {
@@ -140,9 +140,9 @@ fail:
  * Reconcile kernel and user view of the transmit ring.
  */
 static int
-igb_netmap_txsync(void *a, u_int ring_nr, int do_lock)
+igb_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
 {
-	struct adapter *adapter = a;
+	struct adapter *adapter = ifp->if_softc;
 	struct tx_ring *txr = &adapter->tx_rings[ring_nr];
 	struct netmap_adapter *na = NA(adapter->ifp);
 	struct netmap_kring *kring = &na->tx_rings[ring_nr];
@@ -258,9 +258,9 @@ igb_netmap_txsync(void *a, u_int ring_nr
  * Reconcile kernel and user view of the receive ring.
  */
 static int
-igb_netmap_rxsync(void *a, u_int ring_nr, int do_lock)
+igb_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
 {
-	struct adapter *adapter = a;
+	struct adapter *adapter = ifp->if_softc;
 	struct rx_ring *rxr = &adapter->rx_rings[ring_nr];
 	struct netmap_adapter *na = NA(adapter->ifp);
 	struct netmap_kring *kring = &na->rx_rings[ring_nr];

Modified: head/sys/dev/netmap/if_lem_netmap.h
==============================================================================
--- head/sys/dev/netmap/if_lem_netmap.h	Mon Feb 13 18:54:15 2012	(r231593)
+++ head/sys/dev/netmap/if_lem_netmap.h	Mon Feb 13 18:56:34 2012	(r231594)
@@ -40,9 +40,9 @@
 #include <dev/netmap/netmap_kern.h>
 
 static int	lem_netmap_reg(struct ifnet *, int onoff);
-static int	lem_netmap_txsync(void *, u_int, int);
-static int	lem_netmap_rxsync(void *, u_int, int);
-static void	lem_netmap_lock_wrapper(void *, int, u_int);
+static int	lem_netmap_txsync(struct ifnet *, u_int, int);
+static int	lem_netmap_rxsync(struct ifnet *, u_int, int);
+static void	lem_netmap_lock_wrapper(struct ifnet *, int, u_int);
 
 
 SYSCTL_NODE(_dev, OID_AUTO, lem, CTLFLAG_RW, 0, "lem card");
@@ -67,9 +67,9 @@ lem_netmap_attach(struct adapter *adapte
 
 
 static void
-lem_netmap_lock_wrapper(void *_a, int what, u_int ringid)
+lem_netmap_lock_wrapper(struct ifnet *ifp, int what, u_int ringid)
 {
-	struct adapter *adapter = _a;
+	struct adapter *adapter = ifp->if_softc;
 
 	/* only one ring here so ignore the ringid */
 	switch (what) {
@@ -153,9 +153,9 @@ fail:
  * Reconcile kernel and user view of the transmit ring.
  */
 static int
-lem_netmap_txsync(void *a, u_int ring_nr, int do_lock)
+lem_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
 {
-	struct adapter *adapter = a;
+	struct adapter *adapter = ifp->if_softc;
 	struct netmap_adapter *na = NA(adapter->ifp);
 	struct netmap_kring *kring = &na->tx_rings[0];
 	struct netmap_ring *ring = kring->ring;
@@ -257,9 +257,9 @@ lem_netmap_txsync(void *a, u_int ring_nr
  * Reconcile kernel and user view of the receive ring.
  */
 static int
-lem_netmap_rxsync(void *a, u_int ring_nr, int do_lock)
+lem_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
 {
-	struct adapter *adapter = a;
+	struct adapter *adapter = ifp->if_softc;
 	struct netmap_adapter *na = NA(adapter->ifp);
 	struct netmap_kring *kring = &na->rx_rings[0];
 	struct netmap_ring *ring = kring->ring;

Modified: head/sys/dev/netmap/if_re_netmap.h
==============================================================================
--- head/sys/dev/netmap/if_re_netmap.h	Mon Feb 13 18:54:15 2012	(r231593)
+++ head/sys/dev/netmap/if_re_netmap.h	Mon Feb 13 18:56:34 2012	(r231594)
@@ -37,9 +37,9 @@
 #include <dev/netmap/netmap_kern.h>
 
 static int re_netmap_reg(struct ifnet *, int onoff);
-static int re_netmap_txsync(void *, u_int, int);
-static int re_netmap_rxsync(void *, u_int, int);
-static void re_netmap_lock_wrapper(void *, int, u_int);
+static int re_netmap_txsync(struct ifnet *, u_int, int);
+static int re_netmap_rxsync(struct ifnet *, u_int, int);
+static void re_netmap_lock_wrapper(struct ifnet *, int, u_int);
 
 static void
 re_netmap_attach(struct rl_softc *sc)
@@ -65,9 +65,9 @@ re_netmap_attach(struct rl_softc *sc)
  * We should not use the tx/rx locks
  */
 static void
-re_netmap_lock_wrapper(void *_a, int what, u_int queueid)
+re_netmap_lock_wrapper(struct ifnet *ifp, int what, u_int queueid)
 {
-	struct rl_softc *adapter = _a;
+	struct rl_softc *adapter = ifp->if_softc;
 
 	switch (what) {
 	case NETMAP_CORE_LOCK:
@@ -133,9 +133,9 @@ fail:
  * Reconcile kernel and user view of the transmit ring.
  */
 static int
-re_netmap_txsync(void *a, u_int ring_nr, int do_lock)
+re_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
 {
-	struct rl_softc *sc = a;
+	struct rl_softc *sc = ifp->if_softc;
 	struct rl_txdesc *txd = sc->rl_ldata.rl_tx_desc;
 	struct netmap_adapter *na = NA(sc->rl_ifp);
 	struct netmap_kring *kring = &na->tx_rings[ring_nr];
@@ -236,9 +236,9 @@ re_netmap_txsync(void *a, u_int ring_nr,
  * Reconcile kernel and user view of the receive ring.
  */
 static int
-re_netmap_rxsync(void *a, u_int ring_nr, int do_lock)
+re_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
 {
-	struct rl_softc *sc = a;
+	struct rl_softc *sc = ifp->if_softc;
 	struct rl_rxdesc *rxd = sc->rl_ldata.rl_rx_desc;
 	struct netmap_adapter *na = NA(sc->rl_ifp);
 	struct netmap_kring *kring = &na->rx_rings[ring_nr];

Modified: head/sys/dev/netmap/ixgbe_netmap.h
==============================================================================
--- head/sys/dev/netmap/ixgbe_netmap.h	Mon Feb 13 18:54:15 2012	(r231593)
+++ head/sys/dev/netmap/ixgbe_netmap.h	Mon Feb 13 18:56:34 2012	(r231594)
@@ -55,9 +55,9 @@
  * *_netmap_attach() routine.
  */
 static int	ixgbe_netmap_reg(struct ifnet *, int onoff);
-static int	ixgbe_netmap_txsync(void *, u_int, int);
-static int	ixgbe_netmap_rxsync(void *, u_int, int);
-static void	ixgbe_netmap_lock_wrapper(void *, int, u_int);
+static int	ixgbe_netmap_txsync(struct ifnet *, u_int, int);
+static int	ixgbe_netmap_rxsync(struct ifnet *, u_int, int);
+static void	ixgbe_netmap_lock_wrapper(struct ifnet *, int, u_int);
 
 
 /*
@@ -90,9 +90,9 @@ ixgbe_netmap_attach(struct adapter *adap
  * wrapper to export locks to the generic netmap code.
  */
 static void
-ixgbe_netmap_lock_wrapper(void *_a, int what, u_int queueid)
+ixgbe_netmap_lock_wrapper(struct ifnet *_a, int what, u_int queueid)
 {
-	struct adapter *adapter = _a;
+	struct adapter *adapter = _a->if_softc;
 
 	ASSERT(queueid < adapter->num_queues);
 	switch (what) {
@@ -190,9 +190,9 @@ fail:
  * buffers irrespective of interrupt mitigation.
  */
 static int
-ixgbe_netmap_txsync(void *a, u_int ring_nr, int do_lock)
+ixgbe_netmap_txsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
 {
-	struct adapter *adapter = a;
+	struct adapter *adapter = ifp->if_softc;
 	struct tx_ring *txr = &adapter->tx_rings[ring_nr];
 	struct netmap_adapter *na = NA(adapter->ifp);
 	struct netmap_kring *kring = &na->tx_rings[ring_nr];
@@ -418,9 +418,9 @@ ring_reset:
  * do_lock has a special meaning: please refer to txsync.
  */
 static int
-ixgbe_netmap_rxsync(void *a, u_int ring_nr, int do_lock)
+ixgbe_netmap_rxsync(struct ifnet *ifp, u_int ring_nr, int do_lock)
 {
-	struct adapter *adapter = a;
+	struct adapter *adapter = ifp->if_softc;
 	struct rx_ring *rxr = &adapter->rx_rings[ring_nr];
 	struct netmap_adapter *na = NA(adapter->ifp);
 	struct netmap_kring *kring = &na->rx_rings[ring_nr];

Modified: head/sys/dev/netmap/netmap.c
==============================================================================
--- head/sys/dev/netmap/netmap.c	Mon Feb 13 18:54:15 2012	(r231593)
+++ head/sys/dev/netmap/netmap.c	Mon Feb 13 18:56:34 2012	(r231594)
@@ -749,7 +749,7 @@ netmap_dtor_locked(void *data)
 		D("deleting last netmap instance for %s", ifp->if_xname);
 		/*
 		 * there is a race here with *_netmap_task() and
-		 * netmap_poll(), which don't run under NETMAP_CORE_LOCK.
+		 * netmap_poll(), which don't run under NETMAP_REG_LOCK.
 		 * na->refcount == 0 && na->ifp->if_capenable & IFCAP_NETMAP
 		 * (aka NETMAP_DELETING(na)) are a unique marker that the
 		 * device is dying.
@@ -759,9 +759,9 @@ netmap_dtor_locked(void *data)
 		 * should check the condition at entry and quit if
 		 * they cannot run.
 		 */
-		na->nm_lock(ifp->if_softc, NETMAP_CORE_UNLOCK, 0);
+		na->nm_lock(ifp, NETMAP_REG_UNLOCK, 0);
 		tsleep(na, 0, "NIOCUNREG", 4);
-		na->nm_lock(ifp->if_softc, NETMAP_CORE_LOCK, 0);
+		na->nm_lock(ifp, NETMAP_REG_LOCK, 0);
 		na->nm_register(ifp, 0); /* off, clear IFCAP_NETMAP */
 		/* Wake up any sleeping threads. netmap_poll will
 		 * then return POLLERR
@@ -803,9 +803,9 @@ netmap_dtor(void *data)
 	struct ifnet *ifp = priv->np_ifp;
 	struct netmap_adapter *na = NA(ifp);
 
-	na->nm_lock(ifp->if_softc, NETMAP_CORE_LOCK, 0);
+	na->nm_lock(ifp, NETMAP_REG_LOCK, 0);
 	netmap_dtor_locked(data);
-	na->nm_lock(ifp->if_softc, NETMAP_CORE_UNLOCK, 0); 
+	na->nm_lock(ifp, NETMAP_REG_UNLOCK, 0); 
 
 	if_rele(ifp);
 	bzero(priv, sizeof(*priv));	/* XXX for safety */
@@ -863,7 +863,7 @@ netmap_sync_to_host(struct netmap_adapte
 		netmap_ring_reinit(kring);
 		return;
 	}
-	// na->nm_lock(na->ifp->if_softc, NETMAP_CORE_LOCK, 0);
+	// na->nm_lock(na->ifp, NETMAP_CORE_LOCK, 0);
 
 	/* Take packets from hwcur to cur and pass them up.
 	 * In case of no buffers we give up. At the end of the loop,
@@ -890,16 +890,15 @@ netmap_sync_to_host(struct netmap_adapte
 	}
 	kring->nr_hwcur = k;
 	kring->nr_hwavail = ring->avail = lim;
-	// na->nm_lock(na->ifp->if_softc, NETMAP_CORE_UNLOCK, 0);
+	// na->nm_lock(na->ifp, NETMAP_CORE_UNLOCK, 0);
 
 	/* send packets up, outside the lock */
 	while ((m = head) != NULL) {
 		head = head->m_nextpkt;
 		m->m_nextpkt = NULL;
-		m->m_pkthdr.rcvif = na->ifp;
 		if (netmap_verbose & NM_VERB_HOST)
-			D("sending up pkt %p size %d", m, m->m_pkthdr.len);
-		(na->ifp->if_input)(na->ifp, m);
+			D("sending up pkt %p size %d", m, MBUF_LEN(m));
+		NM_SEND_UP(na->ifp, m);
 	}
 }
 
@@ -919,7 +918,7 @@ netmap_sync_from_host(struct netmap_adap
 	int error = 1, delta;
 	u_int k = ring->cur, lim = kring->nkr_num_slots;
 
-	na->nm_lock(na->ifp->if_softc, NETMAP_CORE_LOCK, 0);
+	na->nm_lock(na->ifp, NETMAP_CORE_LOCK, 0);
 	if (k >= lim) /* bad value */
 		goto done;
 	delta = k - kring->nr_hwcur;
@@ -936,7 +935,7 @@ netmap_sync_from_host(struct netmap_adap
 	if (k && (netmap_verbose & NM_VERB_HOST))
 		D("%d pkts from stack", k);
 done:
-	na->nm_lock(na->ifp->if_softc, NETMAP_CORE_UNLOCK, 0);
+	na->nm_lock(na->ifp, NETMAP_CORE_UNLOCK, 0);
 	if (error)
 		netmap_ring_reinit(kring);
 }
@@ -1028,7 +1027,6 @@ netmap_set_ringid(struct netmap_priv_d *
 {
 	struct ifnet *ifp = priv->np_ifp;
 	struct netmap_adapter *na = NA(ifp);
-	void *adapter = na->ifp->if_softc;	/* shorthand */
 	u_int i = ringid & NETMAP_RING_MASK;
 	/* first time we don't lock */
 	int need_lock = (priv->np_qfirst != priv->np_qlast);
@@ -1038,7 +1036,7 @@ netmap_set_ringid(struct netmap_priv_d *
 		return (EINVAL);
 	}
 	if (need_lock)
-		na->nm_lock(adapter, NETMAP_CORE_LOCK, 0);
+		na->nm_lock(ifp, NETMAP_CORE_LOCK, 0);
 	priv->np_ringid = ringid;
 	if (ringid & NETMAP_SW_RING) {
 		priv->np_qfirst = na->num_queues;
@@ -1052,7 +1050,7 @@ netmap_set_ringid(struct netmap_priv_d *
 	}
 	priv->np_txpoll = (ringid & NETMAP_NO_TX_POLL) ? 0 : 1;
 	if (need_lock)
-		na->nm_lock(adapter, NETMAP_CORE_UNLOCK, 0);
+		na->nm_lock(ifp, NETMAP_CORE_UNLOCK, 0);
 	if (ringid & NETMAP_SW_RING)
 		D("ringid %s set to SW RING", ifp->if_xname);
 	else if (ringid & NETMAP_HW_RING)
@@ -1085,7 +1083,6 @@ netmap_ioctl(__unused struct cdev *dev, 
 	struct ifnet *ifp;
 	struct nmreq *nmr = (struct nmreq *) data;
 	struct netmap_adapter *na;
-	void *adapter;
 	int error;
 	u_int i;
 	struct netmap_if *nifp;
@@ -1127,7 +1124,6 @@ netmap_ioctl(__unused struct cdev *dev, 
 		if (error)
 			break;
 		na = NA(ifp); /* retrieve netmap adapter */
-		adapter = na->ifp->if_softc;	/* shorthand */
 		/*
 		 * Allocate the private per-thread structure.
 		 * XXX perhaps we can use a blocking malloc ?
@@ -1141,10 +1137,10 @@ netmap_ioctl(__unused struct cdev *dev, 
 		}
 
 		for (i = 10; i > 0; i--) {
-			na->nm_lock(adapter, NETMAP_CORE_LOCK, 0);
+			na->nm_lock(ifp, NETMAP_REG_LOCK, 0);
 			if (!NETMAP_DELETING(na))
 				break;
-			na->nm_lock(adapter, NETMAP_CORE_UNLOCK, 0);
+			na->nm_lock(ifp, NETMAP_REG_UNLOCK, 0);
 			tsleep(na, 0, "NIOCREGIF", hz/10);
 		}
 		if (i == 0) {
@@ -1175,14 +1171,14 @@ netmap_ioctl(__unused struct cdev *dev, 
 
 		if (error) {	/* reg. failed, release priv and ref */
 error:
-			na->nm_lock(adapter, NETMAP_CORE_UNLOCK, 0);
+			na->nm_lock(ifp, NETMAP_REG_UNLOCK, 0);
 			if_rele(ifp);	/* return the refcount */
 			bzero(priv, sizeof(*priv));
 			free(priv, M_DEVBUF);
 			break;
 		}
 
-		na->nm_lock(adapter, NETMAP_CORE_UNLOCK, 0);
+		na->nm_lock(ifp, NETMAP_REG_UNLOCK, 0);
 		error = devfs_set_cdevpriv(priv, netmap_dtor);
 
 		if (error != 0) {
@@ -1219,7 +1215,6 @@ error:
 		}
 		ifp = priv->np_ifp;	/* we have a reference */
 		na = NA(ifp); /* retrieve netmap adapter */
-		adapter = ifp->if_softc;	/* shorthand */
 
 		if (priv->np_qfirst == na->num_queues) {
 			/* queues to/from host */
@@ -1237,13 +1232,13 @@ error:
 				D("sync tx ring %d cur %d hwcur %d",
 					i, kring->ring->cur,
 					kring->nr_hwcur);
-                        na->nm_txsync(adapter, i, 1 /* do lock */);
+                        na->nm_txsync(ifp, i, 1 /* do lock */);
 			if (netmap_verbose & NM_VERB_TXSYNC)
 				D("after sync tx ring %d cur %d hwcur %d",
 					i, kring->ring->cur,
 					kring->nr_hwcur);
 		    } else {
-			na->nm_rxsync(adapter, i, 1 /* do lock */);
+			na->nm_rxsync(ifp, i, 1 /* do lock */);
 			microtime(&na->rx_rings[i].ring->ts);
 		    }
 		}
@@ -1297,7 +1292,6 @@ netmap_poll(__unused struct cdev *dev, i
 	struct ifnet *ifp;
 	struct netmap_kring *kring;
 	u_int core_lock, i, check_all, want_tx, want_rx, revents = 0;
-	void *adapter;
 	enum {NO_CL, NEED_CL, LOCKED_CL }; /* see below */
 
 	if (devfs_get_cdevpriv((void **)&priv) != 0 || priv == NULL)
@@ -1313,7 +1307,6 @@ netmap_poll(__unused struct cdev *dev, i
 	want_tx = events & (POLLOUT | POLLWRNORM);
 	want_rx = events & (POLLIN | POLLRDNORM);
 
-	adapter = ifp->if_softc;
 	na = NA(ifp); /* retrieve netmap adapter */
 
 	/* how many queues we are scanning */
@@ -1411,16 +1404,16 @@ netmap_poll(__unused struct cdev *dev, i
 			if (!want_tx && kring->ring->cur == kring->nr_hwcur)
 				continue;
 			if (core_lock == NEED_CL) {
-				na->nm_lock(adapter, NETMAP_CORE_LOCK, 0);
+				na->nm_lock(ifp, NETMAP_CORE_LOCK, 0);
 				core_lock = LOCKED_CL;
 			}
 			if (na->separate_locks)
-				na->nm_lock(adapter, NETMAP_TX_LOCK, i);
+				na->nm_lock(ifp, NETMAP_TX_LOCK, i);
 			if (netmap_verbose & NM_VERB_TXSYNC)
 				D("send %d on %s %d",
 					kring->ring->cur,
 					ifp->if_xname, i);
-			if (na->nm_txsync(adapter, i, 0 /* no lock */))
+			if (na->nm_txsync(ifp, i, 0 /* no lock */))
 				revents |= POLLERR;
 
 			/* Check avail/call selrecord only if called with POLLOUT */
@@ -1435,7 +1428,7 @@ netmap_poll(__unused struct cdev *dev, i
 					selrecord(td, &kring->si);
 			}
 			if (na->separate_locks)
-				na->nm_lock(adapter, NETMAP_TX_UNLOCK, i);
+				na->nm_lock(ifp, NETMAP_TX_UNLOCK, i);
 		}
 	}
 
@@ -1447,13 +1440,13 @@ netmap_poll(__unused struct cdev *dev, i
 		for (i = priv->np_qfirst; i < priv->np_qlast; i++) {
 			kring = &na->rx_rings[i];
 			if (core_lock == NEED_CL) {
-				na->nm_lock(adapter, NETMAP_CORE_LOCK, 0);
+				na->nm_lock(ifp, NETMAP_CORE_LOCK, 0);
 				core_lock = LOCKED_CL;
 			}
 			if (na->separate_locks)
-				na->nm_lock(adapter, NETMAP_RX_LOCK, i);
+				na->nm_lock(ifp, NETMAP_RX_LOCK, i);
 
-			if (na->nm_rxsync(adapter, i, 0 /* no lock */))
+			if (na->nm_rxsync(ifp, i, 0 /* no lock */))
 				revents |= POLLERR;
 			if (netmap_no_timestamp == 0 ||
 					kring->ring->flags & NR_TIMESTAMP) {
@@ -1465,7 +1458,7 @@ netmap_poll(__unused struct cdev *dev, i
 			else if (!check_all)
 				selrecord(td, &kring->si);
 			if (na->separate_locks)
-				na->nm_lock(adapter, NETMAP_RX_UNLOCK, i);
+				na->nm_lock(ifp, NETMAP_RX_UNLOCK, i);
 		}
 	}
 	if (check_all && revents == 0) {
@@ -1476,7 +1469,7 @@ netmap_poll(__unused struct cdev *dev, i
 			selrecord(td, &na->rx_rings[i].si);
 	}
 	if (core_lock == LOCKED_CL)
-		na->nm_lock(adapter, NETMAP_CORE_UNLOCK, 0);
+		na->nm_lock(ifp, NETMAP_CORE_UNLOCK, 0);
 
 	return (revents);
 }
@@ -1484,6 +1477,48 @@ netmap_poll(__unused struct cdev *dev, i
 /*------- driver support routines ------*/
 
 /*
+ * default lock wrapper. On linux we use mostly netmap-specific locks.
+ */
+static void
+netmap_lock_wrapper(struct ifnet *_a, int what, u_int queueid)
+{
+	struct netmap_adapter *na = NA(_a);
+
+	switch (what) {
+#ifndef __FreeBSD__	/* some system do not need lock on register */
+	case NETMAP_REG_LOCK:
+	case NETMAP_REG_UNLOCK:
+		break;
+#endif
+
+	case NETMAP_CORE_LOCK:
+		mtx_lock(&na->core_lock);
+		break;
+
+	case NETMAP_CORE_UNLOCK:
+		mtx_unlock(&na->core_lock);
+		break;
+
+	case NETMAP_TX_LOCK:
+		mtx_lock(&na->tx_rings[queueid].q_lock);
+		break;
+
+	case NETMAP_TX_UNLOCK:
+		mtx_unlock(&na->tx_rings[queueid].q_lock);
+		break;
+
+	case NETMAP_RX_LOCK:
+		mtx_lock(&na->rx_rings[queueid].q_lock);
+		break;
+
+	case NETMAP_RX_UNLOCK:
+		mtx_unlock(&na->rx_rings[queueid].q_lock);
+		break;
+	}
+}
+
+
+/*
  * Initialize a ``netmap_adapter`` object created by driver on attach.
  * We allocate a block of memory with room for a struct netmap_adapter
  * plus two sets of N+2 struct netmap_kring (where N is the number
@@ -1500,6 +1535,7 @@ netmap_attach(struct netmap_adapter *na,
 	int size = sizeof(*na) + 2 * n * sizeof(struct netmap_kring);
 	void *buf;
 	struct ifnet *ifp = na->ifp;
+	int i;
 
 	if (ifp == NULL) {
 		D("ifp not set, giving up");
@@ -1516,6 +1552,15 @@ netmap_attach(struct netmap_adapter *na,
 		na->buff_size = NETMAP_BUF_SIZE;
 		bcopy(na, buf, sizeof(*na));
 		ifp->if_capabilities |= IFCAP_NETMAP;
+
+		na = buf;
+		if (na->nm_lock == NULL)
+			na->nm_lock = netmap_lock_wrapper;
+		mtx_init(&na->core_lock, "netmap core lock", NULL, MTX_DEF);
+		for (i = 0 ; i < num_queues; i++)
+			mtx_init(&na->tx_rings[i].q_lock, "netmap txq lock", NULL, MTX_DEF);
+		for (i = 0 ; i < num_queues; i++)
+			mtx_init(&na->rx_rings[i].q_lock, "netmap rxq lock", NULL, MTX_DEF);
 	}
 	D("%s for %s", buf ? "ok" : "failed", ifp->if_xname);
 
@@ -1556,14 +1601,14 @@ netmap_start(struct ifnet *ifp, struct m
 {
 	struct netmap_adapter *na = NA(ifp);
 	struct netmap_kring *kring = &na->rx_rings[na->num_queues];
-	u_int i, len = m->m_pkthdr.len;
+	u_int i, len = MBUF_LEN(m);
 	int error = EBUSY, lim = kring->nkr_num_slots - 1;
 	struct netmap_slot *slot;
 
 	if (netmap_verbose & NM_VERB_HOST)
 		D("%s packet %d len %d from the stack", ifp->if_xname,
 			kring->nr_hwcur + kring->nr_hwavail, len);
-	na->nm_lock(ifp->if_softc, NETMAP_CORE_LOCK, 0);
+	na->nm_lock(ifp, NETMAP_CORE_LOCK, 0);
 	if (kring->nr_hwavail >= lim) {
 		D("stack ring %s full\n", ifp->if_xname);
 		goto done;	/* no space */
@@ -1586,7 +1631,7 @@ netmap_start(struct ifnet *ifp, struct m
 	selwakeuppri(&kring->si, PI_NET);
 	error = 0;
 done:
-	na->nm_lock(ifp->if_softc, NETMAP_CORE_UNLOCK, 0);
+	na->nm_lock(ifp, NETMAP_CORE_UNLOCK, 0);
 
 	/* release the mbuf in either cases of success or failure. As an
 	 * alternative, put the mbuf in a free list and free the list
@@ -1645,6 +1690,48 @@ netmap_reset(struct netmap_adapter *na, 
 
 
 /*
+ * Default functions to handle rx/tx interrupts
+ * we have 4 cases:
+ * 1 ring, single lock:
+ *     lock(core); wake(i=0); unlock(core)
+ * N rings, single lock:
+ *     lock(core); wake(i); wake(N+1) unlock(core)
+ * 1 ring, separate locks: (i=0)
+ *     lock(i); wake(i); unlock(i)
+ * N rings, separate locks:
+ *     lock(i); wake(i); unlock(i); lock(core) wake(N+1) unlock(core)
+ */
+int netmap_rx_irq(struct ifnet *ifp, int q, int *work_done)
+{
+	struct netmap_adapter *na;
+	struct netmap_kring *r;
+
+	if (!(ifp->if_capenable & IFCAP_NETMAP))
+		return 0;
+	na = NA(ifp);
+	r = work_done ? na->rx_rings : na->tx_rings;
+	if (na->separate_locks) {
+		mtx_lock(&r[q].q_lock);
+		selwakeuppri(&r[q].si, PI_NET);
+		mtx_unlock(&r[q].q_lock);
+		if (na->num_queues > 1) {
+			mtx_lock(&na->core_lock);
+			selwakeuppri(&r[na->num_queues + 1].si, PI_NET);
+			mtx_unlock(&na->core_lock);
+		}
+	} else {
+		mtx_lock(&na->core_lock);
+		selwakeuppri(&r[q].si, PI_NET);
+		if (na->num_queues > 1)
+			selwakeuppri(&r[na->num_queues + 1].si, PI_NET);
+		mtx_unlock(&na->core_lock);
+	}
+	if (work_done)
+		*work_done = 1; /* do not fire napi again */
+	return 1;
+}
+
+/*
  * Module loader.
  *
  * Create the /dev/netmap device and initialize all global

Modified: head/sys/dev/netmap/netmap_kern.h
==============================================================================
--- head/sys/dev/netmap/netmap_kern.h	Mon Feb 13 18:54:15 2012	(r231593)
+++ head/sys/dev/netmap/netmap_kern.h	Mon Feb 13 18:56:34 2012	(r231594)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Matteo Landi, Luigi Rizzo. All rights reserved.
+ * Copyright (C) 2011-2012 Matteo Landi, Luigi Rizzo. All rights reserved.
  * 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -34,6 +34,20 @@
 #ifndef _NET_NETMAP_KERN_H_
 #define _NET_NETMAP_KERN_H_
 
+#if defined(__FreeBSD__)
+#define	NM_LOCK_T	struct mtx
+#define	NM_SELINFO_T	struct selinfo
+#define	MBUF_LEN(m)	((m)->m_pkthdr.len)
+#define	NM_SEND_UP(ifp, m)	((ifp)->if_input)(ifp, m)
+#elif defined (__linux__)
+#define	NM_LOCK_T	spinlock_t
+#define	NM_SELINFO_T	wait_queue_head_t
+#define	MBUF_LEN(m)	((m)->len)
+#define	NM_SEND_UP(ifp, m)	netif_rx(m)
+#else
+#error unsupported platform
+#endif
+
 #ifdef MALLOC_DECLARE
 MALLOC_DECLARE(M_NETMAP);
 #endif
@@ -53,11 +67,10 @@ struct netmap_adapter;
 /*
  * private, kernel view of a ring.
  *
- * XXX 20110627-todo
- * The index in the NIC and netmap ring is offset by nkr_hwofs slots.
+ * The indexes in the NIC and netmap rings are offset by nkr_hwofs slots.
  * This is so that, on a reset, buffers owned by userspace are not
  * modified by the kernel. In particular:
- * RX rings: the next empty buffer (hwcur + hwavail + hwofs) coincides
+ * RX rings: the next empty buffer (hwcur + hwavail + hwofs) coincides with
  * 	the next empty buffer as known by the hardware (next_to_check or so).
  * TX rings: hwcur + hwofs coincides with next_to_send
  */
@@ -70,12 +83,13 @@ struct netmap_kring {
 	u_int nkr_num_slots;
 
 	int	nkr_hwofs;	/* offset between NIC and netmap ring */
-	struct netmap_adapter *na;	 // debugging
-	struct selinfo si; /* poll/select wait queue */
+	struct netmap_adapter *na;
+	NM_SELINFO_T si;	/* poll/select wait queue */
+	NM_LOCK_T q_lock;	/* used if no device lock available */
 } __attribute__((__aligned__(64)));
 
 /*
- * This struct is part of and extends the 'struct adapter' (or
+ * This struct extends the 'struct adapter' (or
  * equivalent) device descriptor. It contains all fields needed to
  * support netmap operation.
  */
@@ -93,9 +107,9 @@ struct netmap_adapter {
 
 	u_int num_tx_desc; /* number of descriptor in each queue */
 	u_int num_rx_desc;
-	u_int buff_size;
+	u_int buff_size;	
 
-	u_int	flags;
+	//u_int	flags;	// XXX unused
 	/* tx_rings and rx_rings are private but allocated
 	 * as a contiguous chunk of memory. Each array has
 	 * N+1 entries, for the adapter queues and for the host queue.
@@ -107,7 +121,7 @@ struct netmap_adapter {
 	 * packets from the network stack when netmap is active.
 	 * XXX probably if_qflush is not necessary.
 	 */
-	void    (*if_qflush)(struct ifnet *);
+	//void    (*if_qflush)(struct ifnet *);	// XXX unused
 	int     (*if_transmit)(struct ifnet *, struct mbuf *);
 
 	/* references to the ifnet and device routines, used by
@@ -115,10 +129,12 @@ struct netmap_adapter {
 	 */
 	struct ifnet *ifp; /* adapter is ifp->if_softc */
 
+	NM_LOCK_T core_lock;	/* used if no device lock available */
+
 	int (*nm_register)(struct ifnet *, int onoff);
-	void (*nm_lock)(void *, int what, u_int ringid);
-	int (*nm_txsync)(void *, u_int ring, int lock);
-	int (*nm_rxsync)(void *, u_int ring, int lock);
+	void (*nm_lock)(struct ifnet *, int what, u_int ringid);
+	int (*nm_txsync)(struct ifnet *, u_int ring, int lock);
+	int (*nm_rxsync)(struct ifnet *, u_int ring, int lock);
 };
 
 /*
@@ -144,6 +160,12 @@ enum {
 	NETMAP_CORE_LOCK, NETMAP_CORE_UNLOCK,
 	NETMAP_TX_LOCK, NETMAP_TX_UNLOCK,
 	NETMAP_RX_LOCK, NETMAP_RX_UNLOCK,
+#ifdef __FreeBSD__
+#define	NETMAP_REG_LOCK		NETMAP_CORE_LOCK
+#define	NETMAP_REG_UNLOCK	NETMAP_CORE_UNLOCK
+#else
+	NETMAP_REG_LOCK, NETMAP_REG_UNLOCK
+#endif
 };
 
 /*
@@ -251,4 +273,11 @@ PNMB(struct netmap_slot *slot, uint64_t 
 	return ret;
 }
 
+/* default functions to handle rx/tx interrupts */
+int netmap_rx_irq(struct ifnet *, int, int *);
+#define netmap_tx_irq(_n, _q) netmap_rx_irq(_n, _q, NULL)
+#ifdef __linux__
+#define bus_dmamap_sync(_a, _b, _c) // wmb() or rmb() ?
+netdev_tx_t netmap_start_linux(struct sk_buff *skb, struct net_device *dev);
+#endif
 #endif /* _NET_NETMAP_KERN_H_ */



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