提交 46b699c5 编写于 作者: J Jesse Brandeburg 提交者: Tony Nguyen

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: e94d4478 ("ice: Implement filter sync, NDO operations and bump version")
Signed-off-by: NJesse Brandeburg <jesse.brandeburg@intel.com>
Reviewed-by: NPaul Menzel <pmenzel@molgen.mpg.de>
Tested-by: NGurucharan G <gurucharanx.g@intel.com>
Signed-off-by: NTony Nguyen <anthony.l.nguyen@intel.com>
上级 21338d58
...@@ -568,6 +568,7 @@ struct ice_tx_ctx_desc { ...@@ -568,6 +568,7 @@ struct ice_tx_ctx_desc {
(0x3FFFFULL << ICE_TXD_CTX_QW1_TSO_LEN_S) (0x3FFFFULL << ICE_TXD_CTX_QW1_TSO_LEN_S)
#define ICE_TXD_CTX_QW1_MSS_S 50 #define ICE_TXD_CTX_QW1_MSS_S 50
#define ICE_TXD_CTX_MIN_MSS 64
#define ICE_TXD_CTX_QW1_VSI_S 50 #define ICE_TXD_CTX_QW1_VSI_S 50
#define ICE_TXD_CTX_QW1_VSI_M (0x3FFULL << ICE_TXD_CTX_QW1_VSI_S) #define ICE_TXD_CTX_QW1_VSI_M (0x3FFULL << ICE_TXD_CTX_QW1_VSI_S)
......
...@@ -8525,6 +8525,7 @@ ice_features_check(struct sk_buff *skb, ...@@ -8525,6 +8525,7 @@ ice_features_check(struct sk_buff *skb,
struct net_device __always_unused *netdev, struct net_device __always_unused *netdev,
netdev_features_t features) netdev_features_t features)
{ {
bool gso = skb_is_gso(skb);
size_t len; size_t len;
/* No point in doing any of this if neither checksum nor GSO are /* No point in doing any of this if neither checksum nor GSO are
...@@ -8537,24 +8538,32 @@ ice_features_check(struct sk_buff *skb, ...@@ -8537,24 +8538,32 @@ ice_features_check(struct sk_buff *skb,
/* We cannot support GSO if the MSS is going to be less than /* We cannot support GSO if the MSS is going to be less than
* 64 bytes. If it is then we need to drop support for GSO. * 64 bytes. If it is then we need to drop support for GSO.
*/ */
if (skb_is_gso(skb) && (skb_shinfo(skb)->gso_size < 64)) if (gso && (skb_shinfo(skb)->gso_size < ICE_TXD_CTX_MIN_MSS))
features &= ~NETIF_F_GSO_MASK; features &= ~NETIF_F_GSO_MASK;
len = skb_network_header(skb) - skb->data; len = skb_network_offset(skb);
if (len > ICE_TXD_MACLEN_MAX || len & 0x1) if (len > ICE_TXD_MACLEN_MAX || len & 0x1)
goto out_rm_features; goto out_rm_features;
len = skb_transport_header(skb) - skb_network_header(skb); len = skb_network_header_len(skb);
if (len > ICE_TXD_IPLEN_MAX || len & 0x1) if (len > ICE_TXD_IPLEN_MAX || len & 0x1)
goto out_rm_features; goto out_rm_features;
if (skb->encapsulation) { if (skb->encapsulation) {
len = skb_inner_network_header(skb) - skb_transport_header(skb); /* this must work for VXLAN frames AND IPIP/SIT frames, and in
if (len > ICE_TXD_L4LEN_MAX || len & 0x1) * the case of IPIP frames, the transport header pointer is
goto out_rm_features; * after the inner header! So check to make sure that this
* is a GRE or UDP_TUNNEL frame before doing that math.
*/
if (gso && (skb_shinfo(skb)->gso_type &
(SKB_GSO_GRE | SKB_GSO_UDP_TUNNEL))) {
len = skb_inner_network_header(skb) -
skb_transport_header(skb);
if (len > ICE_TXD_L4LEN_MAX || len & 0x1)
goto out_rm_features;
}
len = skb_inner_transport_header(skb) - len = skb_inner_network_header_len(skb);
skb_inner_network_header(skb);
if (len > ICE_TXD_IPLEN_MAX || len & 0x1) if (len > ICE_TXD_IPLEN_MAX || len & 0x1)
goto out_rm_features; goto out_rm_features;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册