gso_features_check() decides whether an egress device can offload a GSO
skb as a single TSO frame by comparing the segment count and the frame
length against the device limits.  The resegmentation path added by a
later patch caps the MSS segments per output skb and needs the same
features computed without those limits, so put the two tests in a helper
and gate them with one flag.

No functional changes.

Assisted-by: LLM
Signed-off-by: Wang Zhan <[email protected]>

---
v3:
- rename the helper to gso_within_dev_limits
- move the check_gso_limits flag and the wrapper split here from patch 4
v2: https://lore.kernel.org/[email protected]/
v1: https://lore.kernel.org/[email protected]/
---
 net/core/dev.c | 29 +++++++++++++++++++----------
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index ffa9b0c27788c..d66b667071837 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3834,17 +3834,19 @@ static bool skb_gso_has_extension_hdr(const struct 
sk_buff *skb)
                         skb_inner_network_header_len(skb) != sizeof(struct 
ipv6hdr)));
 }
 
+static bool
+gso_within_dev_limits(const struct sk_buff *skb, const struct net_device *dev)
+{
+       return skb_shinfo(skb)->gso_segs <= READ_ONCE(dev->gso_max_segs) &&
+              skb->len < netif_get_gso_max_size(dev, vlan_get_protocol(skb));
+}
+
 static netdev_features_t gso_features_check(const struct sk_buff *skb,
                                            struct net_device *dev,
-                                           netdev_features_t features)
+                                           netdev_features_t features,
+                                           bool check_limits)
 {
-       u16 gso_segs = skb_shinfo(skb)->gso_segs;
-
-       if (gso_segs > READ_ONCE(dev->gso_max_segs))
-               return features & ~NETIF_F_GSO_MASK;
-
-       if (unlikely(skb->len >=
-                    netif_get_gso_max_size(dev, vlan_get_protocol(skb))))
+       if (check_limits && !gso_within_dev_limits(skb, dev))
                return features & ~NETIF_F_GSO_MASK;
 
        if (!skb_shinfo(skb)->gso_type) {
@@ -3893,13 +3895,15 @@ static netdev_features_t gso_features_check(const 
struct sk_buff *skb,
        return features;
 }
 
-netdev_features_t netif_skb_features(struct sk_buff *skb)
+static netdev_features_t
+__netif_skb_features(struct sk_buff *skb, bool check_gso_limits)
 {
        struct net_device *dev = skb->dev;
        netdev_features_t features = dev->features;
 
        if (skb_is_gso(skb))
-               features = gso_features_check(skb, dev, features);
+               features = gso_features_check(skb, dev, features,
+                                             check_gso_limits);
 
        /* If encapsulation offload request, verify we are testing
         * hardware encapsulation features instead of standard
@@ -3922,6 +3926,11 @@ netdev_features_t netif_skb_features(struct sk_buff *skb)
 
        return harmonize_features(skb, features);
 }
+
+netdev_features_t netif_skb_features(struct sk_buff *skb)
+{
+       return __netif_skb_features(skb, true);
+}
 EXPORT_SYMBOL(netif_skb_features);
 
 static int xmit_one(struct sk_buff *skb, struct net_device *dev,
-- 
2.47.3

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to