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