svn commit: r208575 - user/jmallett/octeon/sys/mips/cavium/octe

Juli Mallett jmallett at FreeBSD.org
Wed May 26 18:36:24 UTC 2010


Author: jmallett
Date: Wed May 26 18:36:23 2010
New Revision: 208575
URL: http://svn.freebsd.org/changeset/base/208575

Log:
  Add cursory locking of the if_snd queue to prevent races between the ifq empty
  check and processing the first packet (or, worse, double-processing.)
  
  There needs to be more locking of the upper-level structures in this driver, but
  this is a good place to start.  All of the things below the ifnet have their
  own locking or don't need it.  (Especially where there are already critical
  sections to prevent migration when accessing per-CPU registers.)
  
  Reported by:	stas

Modified:
  user/jmallett/octeon/sys/mips/cavium/octe/cavium-ethernet.h
  user/jmallett/octeon/sys/mips/cavium/octe/octe.c

Modified: user/jmallett/octeon/sys/mips/cavium/octe/cavium-ethernet.h
==============================================================================
--- user/jmallett/octeon/sys/mips/cavium/octe/cavium-ethernet.h	Wed May 26 18:00:44 2010	(r208574)
+++ user/jmallett/octeon/sys/mips/cavium/octe/cavium-ethernet.h	Wed May 26 18:36:23 2010	(r208575)
@@ -119,6 +119,8 @@ typedef struct {
 
 	struct ifmedia media;
 	int if_flags;
+
+	struct mtx tx_mtx;
 } cvm_oct_private_t;
 
 

Modified: user/jmallett/octeon/sys/mips/cavium/octe/octe.c
==============================================================================
--- user/jmallett/octeon/sys/mips/cavium/octe/octe.c	Wed May 26 18:00:44 2010	(r208574)
+++ user/jmallett/octeon/sys/mips/cavium/octe/octe.c	Wed May 26 18:36:23 2010	(r208575)
@@ -78,6 +78,9 @@
 
 #include "miibus_if.h"
 
+#define	OCTE_TX_LOCK(priv)	mtx_lock(&(priv)->tx_mtx)
+#define	OCTE_TX_UNLOCK(priv)	mtx_unlock(&(priv)->tx_mtx)
+
 static int		octe_probe(device_t);
 static int		octe_attach(device_t);
 static int		octe_detach(device_t);
@@ -174,6 +177,8 @@ octe_attach(device_t dev)
 
 	priv->if_flags = ifp->if_flags;
 
+	mtx_init(&priv->tx_mtx, ifp->if_xname, "octe tx send queue", MTX_DEF);
+
 	for (qos = 0; qos < 16; qos++) {
 		mtx_init(&priv->tx_free_queue[qos].ifq_mtx, ifp->if_xname, "octe tx free queue", MTX_DEF);
 		IFQ_SET_MAXLEN(&priv->tx_free_queue[qos], MAX_OUT_QUEUE_DEPTH);
@@ -181,9 +186,11 @@ octe_attach(device_t dev)
 
 	ether_ifattach(ifp, priv->mac);
 
+	OCTE_TX_LOCK(priv);
 	IFQ_SET_MAXLEN(&ifp->if_snd, MAX_OUT_QUEUE_DEPTH);
 	ifp->if_snd.ifq_drv_maxlen = MAX_OUT_QUEUE_DEPTH;
 	IFQ_SET_READY(&ifp->if_snd);
+	OCTE_TX_UNLOCK(priv);
 
 	return (0);
 }
@@ -280,9 +287,12 @@ octe_start(struct ifnet *ifp)
 	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != IFF_DRV_RUNNING)
 		return;
 
+	OCTE_TX_LOCK(priv);
 	while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
 		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
 
+		OCTE_TX_UNLOCK(priv);
+
 		/*
 		 * XXX
 		 *
@@ -312,6 +322,7 @@ octe_start(struct ifnet *ifp)
 			return;
 		}
 	}
+	OCTE_TX_UNLOCK(priv);
 }
 
 static int


More information about the svn-src-user mailing list