svn commit: r219927 - projects/sv/sys/dev/e1000

Attilio Rao attilio at FreeBSD.org
Wed Mar 23 19:05:35 UTC 2011


Author: attilio
Date: Wed Mar 23 19:05:34 2011
New Revision: 219927
URL: http://svn.freebsd.org/changeset/base/219927

Log:
  Improve deadlock robustness: force intimate polling functions to skip
  locking when possible.
  
  In this case RX_LOCK'ing in if_lem.
  
  Reported by:	rstone

Modified:
  projects/sv/sys/dev/e1000/if_lem.c

Modified: projects/sv/sys/dev/e1000/if_lem.c
==============================================================================
--- projects/sv/sys/dev/e1000/if_lem.c	Wed Mar 23 18:08:54 2011	(r219926)
+++ projects/sv/sys/dev/e1000/if_lem.c	Wed Mar 23 19:05:34 2011	(r219927)
@@ -95,6 +95,14 @@
 	if ((locking) != 0)						\
 		EM_CORE_UNLOCK(adapter);				\
 } while (0)
+#define	EM_RX_LOCK_COND(adapter, locking) do {				\
+	if ((locking) != 0)						\
+		EM_RX_LOCK(adapter);					\
+} while (0)
+#define	EM_RX_UNLOCK_COND(adapter, locking) do {			\
+	if ((locking) != 0)						\
+		EM_RX_UNLOCK(adapter);					\
+} while (0)
 #define	EM_TX_LOCK_COND(adapter, locking) do {				\
 	if ((locking) != 0)						\
 		EM_TX_LOCK(adapter);					\
@@ -218,7 +226,8 @@ static void	lem_txeof(struct adapter *);
 static void	lem_tx_purge(struct adapter *);
 static int	lem_allocate_receive_structures(struct adapter *);
 static int	lem_allocate_transmit_structures(struct adapter *);
-static bool	lem_rxeof(struct adapter *, int, int *);
+static bool	_lem_rxeof_generic(struct adapter *, int, int *, int);
+#define	lem_rxeof(a, c, d)	_lem_rxeof_generic(a, c, d, 1)
 #ifndef __NO_STRICT_ALIGNMENT
 static int	lem_fixup_rx(struct adapter *);
 #endif
@@ -1296,7 +1305,7 @@ _lem_poll_generic(struct ifnet *ifp, enu
 	}
 	EM_CORE_UNLOCK_COND(adapter, locking);
 
-	lem_rxeof(adapter, count, &rx_done);
+	_lem_rxeof_generic(adapter, count, &rx_done, locking);
 
 	EM_TX_LOCK_COND(adapter, locking);
 	lem_txeof(adapter);
@@ -3475,7 +3484,7 @@ lem_free_receive_structures(struct adapt
  *  For polling we also now return the number of cleaned packets
  *********************************************************************/
 static bool
-lem_rxeof(struct adapter *adapter, int count, int *done)
+_lem_rxeof_generic(struct adapter *adapter, int count, int *done, int locking)
 {
 	struct ifnet	*ifp = adapter->ifp;;
 	struct mbuf	*mp;
@@ -3484,7 +3493,7 @@ lem_rxeof(struct adapter *adapter, int c
 	int		i, rx_sent = 0;
 	struct e1000_rx_desc   *current_desc;
 
-	EM_RX_LOCK(adapter);
+	EM_RX_LOCK_COND(adapter, locking);
 	i = adapter->next_rx_desc_to_check;
 	current_desc = &adapter->rx_desc_base[i];
 	bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map,
@@ -3493,7 +3502,7 @@ lem_rxeof(struct adapter *adapter, int c
 	if (!((current_desc->status) & E1000_RXD_STAT_DD)) {
 		if (done != NULL)
 			*done = rx_sent;
-		EM_RX_UNLOCK(adapter);
+		EM_RX_UNLOCK_COND(adapter, locking);
 		return (FALSE);
 	}
 
@@ -3634,9 +3643,9 @@ discard:
 		/* Call into the stack */
 		if (m != NULL) {
 			adapter->next_rx_desc_to_check = i;
-			EM_RX_UNLOCK(adapter);
+			EM_RX_UNLOCK_COND(adapter, locking);
 			(*ifp->if_input)(ifp, m);
-			EM_RX_LOCK(adapter);
+			EM_RX_LOCK_COND(adapter, locking);
 			rx_sent++;
 			i = adapter->next_rx_desc_to_check;
 		}
@@ -3650,7 +3659,7 @@ discard:
 	E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), i);
 	if (done != NULL)
 		*done = rx_sent;
-	EM_RX_UNLOCK(adapter);
+	EM_RX_UNLOCK_COND(adapter, locking);
 	return ((status & E1000_RXD_STAT_DD) ? TRUE : FALSE);
 }
 


More information about the svn-src-projects mailing list