Thread (4 messages) 4 messages, 3 authors, 2018-10-04

RE: [EXT] [PATCH net] net: mvpp2: Extract the correct ethtype from the skb for tx csum offload

From: Yan Markman <hidden>
Date: 2018-10-04 08:08:38
Also in: lkml
Subsystem: marvell mvpp2 ethernet driver, networking drivers, the rest · Maintainers: Marcin Wojtas, Russell King, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

I'm not sure that kind of ntohs() using is good for the Performance. 
htons(ETH_P_IP) is CONSTANT swapped Big/LittleEndian by COMPILER whilst the 
ntohs(vlan_get_protocol(skb)) is run-time short/byte-swap for every packet.

Yan Markman

-----Original Message-----
From: Maxime Chevallier [mailto:maxime.chevallier@bootlin.com] 
Sent: Thursday, October 04, 2018 11:03 AM
To: davem@davemloft.net
Cc: Maxime Chevallier <maxime.chevallier@bootlin.com>; netdev@vger.kernel.org; linux-kernel@vger.kernel.org; Antoine Tenart <redacted>; thomas.petazzoni@bootlin.com; gregory.clement@bootlin.com; miquel.raynal@bootlin.com; Nadav Haklai <redacted>; Stefan Chulski <redacted>; Yan Markman <redacted>; mw@semihalf.com
Subject: [EXT] [PATCH net] net: mvpp2: Extract the correct ethtype from the skb for tx csum offload

External Email

----------------------------------------------------------------------
When offloading the L3 and L4 csum computation on TX, we need to extract the l3_proto from the ethtype, independently of the presence of a vlan tag.

The actual driver uses skb->protocol as-is, resulting in packets with the wrong L4 checksum being sent when there's a vlan tag in the packet header and checksum offloading is enabled.

This commit makes use of vlan_protocol_get() to get the correct ethtype regardless the presence of a vlan tag.

Fixes: 3f51850 ("ethernet: Add new driver for Marvell Armada 375 network unit")
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
---
 drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index 38cc01beea79..4bd5b251e3c7 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -1737,7 +1737,7 @@ static u32 mvpp2_txq_desc_csum(int l3_offs, int l3_proto,
 	command |= (ip_hdr_len << MVPP2_TXD_IP_HLEN_SHIFT);
 	command |= MVPP2_TXD_IP_CSUM_DISABLE;
 
-	if (l3_proto == htons(ETH_P_IP)) {
+	if (l3_proto == ETH_P_IP) {
 		command &= ~MVPP2_TXD_IP_CSUM_DISABLE;	/* enable IPv4 csum */
 		command &= ~MVPP2_TXD_L3_IP6;		/* enable IPv4 */
 	} else {
@@ -2600,14 +2600,15 @@ static u32 mvpp2_skb_tx_csum(struct mvpp2_port *port, struct sk_buff *skb)
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		int ip_hdr_len = 0;
 		u8 l4_proto;
+		int l3_proto = ntohs(vlan_get_protocol(skb));
 
-		if (skb->protocol == htons(ETH_P_IP)) {
+		if (l3_proto == ETH_P_IP) {
 			struct iphdr *ip4h = ip_hdr(skb);
 
 			/* Calculate IPv4 checksum and L4 checksum */
 			ip_hdr_len = ip4h->ihl;
 			l4_proto = ip4h->protocol;
-		} else if (skb->protocol == htons(ETH_P_IPV6)) {
+		} else if (l3_proto == ETH_P_IPV6) {
 			struct ipv6hdr *ip6h = ipv6_hdr(skb);
 
 			/* Read l4_protocol from one of IPv6 extra headers */ @@ -2619,7 +2620,7 @@ static u32 mvpp2_skb_tx_csum(struct mvpp2_port *port, struct sk_buff *skb)
 		}
 
 		return mvpp2_txq_desc_csum(skb_network_offset(skb),
-				skb->protocol, ip_hdr_len, l4_proto);
+					   l3_proto, ip_hdr_len, l4_proto);
 	}
 
 	return MVPP2_TXD_L4_CSUM_NOT | MVPP2_TXD_IP_CSUM_DISABLE;
--
2.11.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help