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

Juli Mallett jmallett at FreeBSD.org
Mon Jul 19 21:24:49 UTC 2010


Author: jmallett
Date: Mon Jul 19 21:24:48 2010
New Revision: 210258
URL: http://svn.freebsd.org/changeset/base/210258

Log:
  Lock the transmitted packet queue from the time we start preparing a packet
  through when we free any transmitted packets.  Without doing this we are
  vulnerable to several nasty races involving packets being freed out of order,
  freed twice, etc.  The atomic operations are good as far as they go, but they
  don't provide for consistency with the packet freeing.

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

Modified: user/jmallett/octeon/sys/mips/cavium/octe/ethernet-tx.c
==============================================================================
--- user/jmallett/octeon/sys/mips/cavium/octe/ethernet-tx.c	Mon Jul 19 21:13:07 2010	(r210257)
+++ user/jmallett/octeon/sys/mips/cavium/octe/ethernet-tx.c	Mon Jul 19 21:24:48 2010	(r210258)
@@ -198,6 +198,7 @@ int cvm_oct_xmit(struct mbuf *m, struct 
 		pko_command.s.ipoffp1 = ETHER_HDR_LEN + 1;
 	}
 
+	IF_LOCK(&priv->tx_free_queue[qos]);
 	if (USE_ASYNC_IOBDMA) {
 		/* Get the number of mbufs in use by the hardware */
 		CVMX_SYNCIOBDMA;
@@ -241,13 +242,12 @@ int cvm_oct_xmit(struct mbuf *m, struct 
 
 	/* Free mbufs not in use by the hardware */
 	if (_IF_QLEN(&priv->tx_free_queue[qos]) > in_use) {
-		IF_LOCK(&priv->tx_free_queue[qos]);
 		while (_IF_QLEN(&priv->tx_free_queue[qos]) > in_use) {
 			_IF_DEQUEUE(&priv->tx_free_queue[qos], m);
 			m_freem(m);
 		}
-		IF_UNLOCK(&priv->tx_free_queue[qos]);
 	}
+	IF_UNLOCK(&priv->tx_free_queue[qos]);
 
 	return dropped;
 }


More information about the svn-src-user mailing list