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

Attilio Rao attilio at FreeBSD.org
Wed Mar 23 19:12:49 UTC 2011


Author: attilio
Date: Wed Mar 23 19:12:48 2011
New Revision: 219928
URL: http://svn.freebsd.org/changeset/base/219928

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

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

Modified: projects/sv/sys/dev/e1000/if_igb.c
==============================================================================
--- projects/sv/sys/dev/e1000/if_igb.c	Wed Mar 23 19:05:34 2011	(r219927)
+++ projects/sv/sys/dev/e1000/if_igb.c	Wed Mar 23 19:12:48 2011	(r219928)
@@ -105,6 +105,14 @@
 	if ((locking) != 0)						\
 		IGB_CORE_UNLOCK(adapter);				\
 } while (0)
+#define	IGB_RX_LOCK_COND(rxr, locking) do {				\
+	if ((locking) != 0)						\
+		IGB_RX_LOCK(rxr);					\
+} while (0)
+#define	IGB_RX_UNLOCK_COND(rxr, locking) do {				\
+	if ((locking) != 0)						\
+		IGB_RX_UNLOCK(rxr);					\
+} while (0)
 #define	IGB_TX_LOCK_COND(txr, locking) do {				\
 	if ((locking) != 0)						\
 		IGB_TX_LOCK(txr);					\
@@ -245,7 +253,8 @@ static __inline	void igb_rx_discard(stru
 static __inline void igb_rx_input(struct rx_ring *,
 		    struct ifnet *, struct mbuf *, u32);
 
-static bool	igb_rxeof(struct igb_queue *, int, int *);
+static bool	_igb_rxeof_generic(struct igb_queue *, int, int *, int);
+#define	igb_rxeof(q, c, d)	_igb_rxeof_generic(q, c, d, 1)
 static void	igb_rx_checksum(u32, struct mbuf *, u32);
 static int	igb_tx_ctx_setup(struct tx_ring *, struct mbuf *);
 static bool	igb_tso_setup(struct tx_ring *, struct mbuf *, u32 *);
@@ -1462,7 +1471,7 @@ _igb_poll_generic(struct ifnet *ifp, enu
 	}
 	IGB_CORE_UNLOCK_COND(adapter, locking);
 
-	igb_rxeof(que, count, &rx_done);
+	_igb_rxeof_generic(que, count, &rx_done, locking);
 
 	IGB_TX_LOCK_COND(txr, locking);
 	do {
@@ -4438,7 +4447,7 @@ igb_rx_input(struct rx_ring *rxr, struct
  *  Return TRUE if more to clean, FALSE otherwise
  *********************************************************************/
 static bool
-igb_rxeof(struct igb_queue *que, int count, int *done)
+_igb_rxeof_generic(struct igb_queue *que, int count, int *done, int locking)
 {
 	struct adapter		*adapter = que->adapter;
 	struct rx_ring		*rxr = que->rxr;
@@ -4449,7 +4458,7 @@ igb_rxeof(struct igb_queue *que, int cou
 	u32			ptype, staterr = 0;
 	union e1000_adv_rx_desc	*cur;
 
-	IGB_RX_LOCK(rxr);
+	IGB_RX_LOCK_COND(rxr, locking);
 	/* Sync the ring. */
 	bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
@@ -4628,7 +4637,7 @@ next_desc:
 	if (done != NULL)
 		*done = rxdone;
 
-	IGB_RX_UNLOCK(rxr);
+	IGB_RX_UNLOCK_COND(rxr, locking);
 	return ((staterr & E1000_RXD_STAT_DD) ? TRUE : FALSE);
 }
 


More information about the svn-src-projects mailing list