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