Hi:
The e1000 xmit routine is lockless and it checks last_tx_tso outside the
locked section. So if a TSO packet wins a race against a non-TSO packet
with last_tx_tso == 0 then we may overwrite an existing buffer_info entry
which would corrupt memory.
The e1000_transfer_dhcp_info call also seems to assume exclusive ownership
of the hardware so I've moved it into the locked section.
Signed-off-by: Herbert Xu <[EMAIL PROTECTED]>
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[EMAIL PROTECTED]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 49cd096..96b7bef 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -2821,13 +2821,6 @@
count++;
#endif
-#ifdef NETIF_F_TSO
- /* Controller Erratum workaround */
- if (!skb->data_len && tx_ring->last_tx_tso &&
- !skb_shinfo(skb)->tso_size)
- count++;
-#endif
-
count += TXD_USE_COUNT(len, max_txd_pwr);
if (adapter->pcix_82544)
@@ -2846,11 +2839,6 @@
max_txd_pwr);
if (adapter->pcix_82544)
count += nr_frags;
-
-
- if (adapter->hw.tx_pkt_filtering &&
- (adapter->hw.mac_type == e1000_82573))
- e1000_transfer_dhcp_info(adapter, skb);
local_irq_save(flags);
if (!spin_trylock(&tx_ring->tx_lock)) {
@@ -2858,6 +2846,17 @@
local_irq_restore(flags);
return NETDEV_TX_LOCKED;
}
+
+#ifdef NETIF_F_TSO
+ /* Controller Erratum workaround */
+ if (!skb->data_len && tx_ring->last_tx_tso &&
+ !skb_shinfo(skb)->tso_size)
+ count++;
+#endif
+
+ if (adapter->hw.tx_pkt_filtering &&
+ (adapter->hw.mac_type == e1000_82573))
+ e1000_transfer_dhcp_info(adapter, skb);
/* need: count + 2 desc gap to keep tail from touching
* head, otherwise try next time */