Skip to contentSkip to conversation

tg3: TSO related enhancements to prevent memory allocation failure

PATCH In review Michael Chan 2 participants 5 messages May 12, 2014 – May 13, 2014

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover tg3: TSO related enhancements to prevent memory allocation failure

Michael Chan (3):
tg3: Don't modify ip header fields when doing GSO
tg3: Prevent page allocation failure during TSO workaround
tg3: Update copyright and version to 3.137

 drivers/net/ethernet/broadcom/tg3.c |   51 +++++++++++++++++++++++-----------
 drivers/net/ethernet/broadcom/tg3.h |    2 +-
 2 files changed, 35 insertions(+), 18 deletions(-)
#1 lore raw

PATCH 1/3 tg3: Don't modify ip header fields when doing GSO

tg3 uses GSO as workaround if the hardware cannot perform TSO on certain packets. We should not modify the ip header fields if we do GSO on the packet. It happens to work by accident because GSO recalculates the IP checksum and IP total length.

Also fix the tg3_start_xmit comment to reflect that this is the only xmit function for all devices.

---
 drivers/net/ethernet/broadcom/tg3.c |   12 +++++-------
 1 files changed, 5 insertions(+), 7 deletions(-)
drivers/net/ethernet/broadcom/tg3.c +5 -7
index e5d95c5..bdfd08b 100644
@@ -7871,9 +7871,7 @@ tg3_tso_bug_end:
 	return NETDEV_TX_OK;
 }
 
-/* hard_start_xmit for devices that have the 4G bug and/or 40-bit bug and
- * support TG3_FLAG_HW_TSO_1 or firmware TSO only.
- */
+/* hard_start_xmit for all devices */
 static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct tg3 *tp = netdev_priv(dev);
@@ -7927,14 +7925,14 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb) - ETH_HLEN;
 
 		if (!skb_is_gso_v6(skb)) {
+			if (unlikely((ETH_HLEN + hdr_len) > 80) &&
+			    tg3_flag(tp, TSO_BUG))
+				return tg3_tso_bug(tp, skb);
+
 			iph->check = 0;
 			iph->tot_len = htons(mss + hdr_len);
 		}
 
-		if (unlikely((ETH_HLEN + hdr_len) > 80) &&
-		    tg3_flag(tp, TSO_BUG))
-			return tg3_tso_bug(tp, skb);
-
 		base_flags |= (TXD_FLAG_CPU_PRE_DMA |
 			       TXD_FLAG_CPU_POST_DMA);
 
Signature · 1 line
1.7.1
#2 lore raw

PATCH 2/3 tg3: Prevent page allocation failure during TSO workaround

If any TSO fragment hits hardware bug conditions (e.g. 4G boundary), the driver will workaround by calling skb_copy() to copy to a linear SKB. Users have reported page allocation failures as the TSO packet can be up to 64K. Copying such a large packet is also very inefficient. We fix this by using existing tg3_tso_bug() to transmit the packet using GSO.

---
 drivers/net/ethernet/broadcom/tg3.c |   33 ++++++++++++++++++++++++++-------
 1 files changed, 26 insertions(+), 7 deletions(-)
drivers/net/ethernet/broadcom/tg3.c +26 -7
index bdfd08b..36b2b51 100644
@@ -7882,6 +7882,10 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	struct tg3_napi *tnapi;
 	struct netdev_queue *txq;
 	unsigned int last;
+	struct iphdr *iph = NULL;
+	struct tcphdr *tcph = NULL;
+	__sum16 tcp_csum = 0, ip_csum = 0;
+	__be16 ip_tot_len = 0;
 
 	txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
 	tnapi = &tp->napi[skb_get_queue_mapping(skb)];
@@ -7913,7 +7917,6 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	mss = skb_shinfo(skb)->gso_size;
 	if (mss) {
-		struct iphdr *iph;
 		u32 tcp_opt_len, hdr_len;
 
 		if (skb_cow_head(skb, 0))
@@ -7929,6 +7932,8 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			    tg3_flag(tp, TSO_BUG))
 				return tg3_tso_bug(tp, skb);
 
+			ip_csum = iph->check;
+			ip_tot_len = iph->tot_len;
 			iph->check = 0;
 			iph->tot_len = htons(mss + hdr_len);
 		}
@@ -7936,16 +7941,18 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		base_flags |= (TXD_FLAG_CPU_PRE_DMA |
 			       TXD_FLAG_CPU_POST_DMA);
 
+		tcph = tcp_hdr(skb);
+		tcp_csum = tcph->check;
+
 		if (tg3_flag(tp, HW_TSO_1) ||
 		    tg3_flag(tp, HW_TSO_2) ||
 		    tg3_flag(tp, HW_TSO_3)) {
-			tcp_hdr(skb)->check = 0;
+			tcph->check = 0;
 			base_flags &= ~TXD_FLAG_TCPUDP_CSUM;
-		} else
-			tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
-								 iph->daddr, 0,
-								 IPPROTO_TCP,
-								 0);
+		} else {
+			tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
+							 0, IPPROTO_TCP, 0);
+		}
 
 		if (tg3_flag(tp, HW_TSO_3)) {
 			mss |= (hdr_len & 0xc) << 12;
@@ -8045,6 +8052,18 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (would_hit_hwbug) {
 		tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, i);
 
+		if (mss) {
+			/* If it's a TSO packet, do GSO instead of
+			 * allocating and copying to a large linear SKB
+			 */
+			if (ip_tot_len) {
+				iph->check = ip_csum;
+				iph->tot_len = ip_tot_len;
+			}
+			tcph->check = tcp_csum;
+			return tg3_tso_bug(tp, skb);
+		}
+
 		/* If the workaround fails due to memory/mapping
 		 * failure, silently drop this packet.
 		 */
Signature · 1 line
1.7.1
#3 lore raw

PATCH 3/3 tg3: Update copyright and version to 3.137

---
 drivers/net/ethernet/broadcom/tg3.c |    6 +++---
 drivers/net/ethernet/broadcom/tg3.h |    2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)
drivers/net/ethernet/broadcom/tg3.c +3 -3
index 36b2b51..ccd9015 100644
@@ -4,7 +4,7 @@
  * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller ([email protected])
  * Copyright (C) 2001, 2002, 2003 Jeff Garzik ([email protected])
  * Copyright (C) 2004 Sun Microsystems Inc.
- * Copyright (C) 2005-2013 Broadcom Corporation.
+ * Copyright (C) 2005-2014 Broadcom Corporation.
  *
  * Firmware is:
  *	Derived from proprietary unpublished source code,
@@ -94,10 +94,10 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits)
 
 #define DRV_MODULE_NAME		"tg3"
 #define TG3_MAJ_NUM			3
-#define TG3_MIN_NUM			136
+#define TG3_MIN_NUM			137
 #define DRV_MODULE_VERSION	\
 	__stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM)
-#define DRV_MODULE_RELDATE	"Jan 03, 2014"
+#define DRV_MODULE_RELDATE	"May 11, 2014"
 
 #define RESET_KIND_SHUTDOWN	0
 #define RESET_KIND_INIT		1
drivers/net/ethernet/broadcom/tg3.h +1 -1
index 04321e5..461acca 100644
@@ -4,7 +4,7 @@
  * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller ([email protected])
  * Copyright (C) 2001 Jeff Garzik ([email protected])
  * Copyright (C) 2004 Sun Microsystems Inc.
- * Copyright (C) 2007-2013 Broadcom Corporation.
+ * Copyright (C) 2007-2014 Broadcom Corporation.
  */
 
 #ifndef _T3_H
Signature · 1 line
1.7.1
maintainer
#4 lore raw
In reply to Michael Chan

From: Michael Chan <[email protected]>
Date: Sun, 11 May 2014 20:22:52 -0700

Quoted 4 lines

Michael Chan (3):
tg3: Don't modify ip header fields when doing GSO
tg3: Prevent page allocation failure during TSO workaround
tg3: Update copyright and version to 3.137

Series applied, thanks Michael.