Skip to content

Commit 46b699c

Browse files
jbrandebanguy11
authored andcommitted
ice: fix IPIP and SIT TSO offload
The driver was avoiding offload for IPIP (at least) frames due to parsing the inner header offsets incorrectly when trying to check lengths. This length check works for VXLAN frames but fails on IPIP frames because skb_transport_offset points to the inner header in IPIP frames, which meant the subtraction of transport_header from inner_network_header returns a negative value (-20). With the code before this patch, everything continued to work, but GSO was being used to segment, causing throughputs of 1.5Gb/s per thread. After this patch, throughput is more like 10Gb/s per thread for IPIP traffic. Fixes: e94d447 ("ice: Implement filter sync, NDO operations and bump version") Signed-off-by: Jesse Brandeburg <[email protected]> Reviewed-by: Paul Menzel <[email protected]> Tested-by: Gurucharan G <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent 21338d5 commit 46b699c

File tree

2 files changed

+18
-8
lines changed

2 files changed

+18
-8
lines changed

drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,7 @@ struct ice_tx_ctx_desc {
568568
(0x3FFFFULL << ICE_TXD_CTX_QW1_TSO_LEN_S)
569569

570570
#define ICE_TXD_CTX_QW1_MSS_S 50
571+
#define ICE_TXD_CTX_MIN_MSS 64
571572

572573
#define ICE_TXD_CTX_QW1_VSI_S 50
573574
#define ICE_TXD_CTX_QW1_VSI_M (0x3FFULL << ICE_TXD_CTX_QW1_VSI_S)

drivers/net/ethernet/intel/ice/ice_main.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8525,6 +8525,7 @@ ice_features_check(struct sk_buff *skb,
85258525
struct net_device __always_unused *netdev,
85268526
netdev_features_t features)
85278527
{
8528+
bool gso = skb_is_gso(skb);
85288529
size_t len;
85298530

85308531
/* No point in doing any of this if neither checksum nor GSO are
@@ -8537,24 +8538,32 @@ ice_features_check(struct sk_buff *skb,
85378538
/* We cannot support GSO if the MSS is going to be less than
85388539
* 64 bytes. If it is then we need to drop support for GSO.
85398540
*/
8540-
if (skb_is_gso(skb) && (skb_shinfo(skb)->gso_size < 64))
8541+
if (gso && (skb_shinfo(skb)->gso_size < ICE_TXD_CTX_MIN_MSS))
85418542
features &= ~NETIF_F_GSO_MASK;
85428543

8543-
len = skb_network_header(skb) - skb->data;
8544+
len = skb_network_offset(skb);
85448545
if (len > ICE_TXD_MACLEN_MAX || len & 0x1)
85458546
goto out_rm_features;
85468547

8547-
len = skb_transport_header(skb) - skb_network_header(skb);
8548+
len = skb_network_header_len(skb);
85488549
if (len > ICE_TXD_IPLEN_MAX || len & 0x1)
85498550
goto out_rm_features;
85508551

85518552
if (skb->encapsulation) {
8552-
len = skb_inner_network_header(skb) - skb_transport_header(skb);
8553-
if (len > ICE_TXD_L4LEN_MAX || len & 0x1)
8554-
goto out_rm_features;
8553+
/* this must work for VXLAN frames AND IPIP/SIT frames, and in
8554+
* the case of IPIP frames, the transport header pointer is
8555+
* after the inner header! So check to make sure that this
8556+
* is a GRE or UDP_TUNNEL frame before doing that math.
8557+
*/
8558+
if (gso && (skb_shinfo(skb)->gso_type &
8559+
(SKB_GSO_GRE | SKB_GSO_UDP_TUNNEL))) {
8560+
len = skb_inner_network_header(skb) -
8561+
skb_transport_header(skb);
8562+
if (len > ICE_TXD_L4LEN_MAX || len & 0x1)
8563+
goto out_rm_features;
8564+
}
85558565

8556-
len = skb_inner_transport_header(skb) -
8557-
skb_inner_network_header(skb);
8566+
len = skb_inner_network_header_len(skb);
85588567
if (len > ICE_TXD_IPLEN_MAX || len & 0x1)
85598568
goto out_rm_features;
85608569
}

0 commit comments

Comments
 (0)