kernel: improve GRO performance
[openwrt/openwrt.git] / target / linux / generic / pending-6.1 / 680-NET-skip-GRO-for-foreign-MAC-addresses.patch
diff --git a/target/linux/generic/pending-6.1/680-NET-skip-GRO-for-foreign-MAC-addresses.patch b/target/linux/generic/pending-6.1/680-NET-skip-GRO-for-foreign-MAC-addresses.patch
deleted file mode 100644 (file)
index a589fca..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: net: replace GRO optimization patch with a new one that supports VLANs/bridges with different MAC addresses
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
- include/linux/netdevice.h |  2 ++
- include/linux/skbuff.h    |  3 ++-
- net/core/dev.c            | 48 +++++++++++++++++++++++++++++++++++++++++++++++
- net/ethernet/eth.c        | 18 +++++++++++++++++-
- 4 files changed, 69 insertions(+), 2 deletions(-)
-
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -2157,6 +2157,8 @@ struct net_device {
-       struct netdev_hw_addr_list      mc;
-       struct netdev_hw_addr_list      dev_addrs;
-+      unsigned char           local_addr_mask[MAX_ADDR_LEN];
-+
- #ifdef CONFIG_SYSFS
-       struct kset             *queues_kset;
- #endif
---- a/include/linux/skbuff.h
-+++ b/include/linux/skbuff.h
-@@ -967,6 +967,7 @@ struct sk_buff {
- #ifdef CONFIG_IPV6_NDISC_NODETYPE
-       __u8                    ndisc_nodetype:2;
- #endif
-+      __u8                    gro_skip:1;
-       __u8                    ipvs_property:1;
-       __u8                    inner_protocol_type:1;
---- a/net/core/gro.c
-+++ b/net/core/gro.c
-@@ -492,6 +492,9 @@ static enum gro_result dev_gro_receive(s
-       int same_flow;
-       int grow;
-+      if (skb->gro_skip)
-+              goto normal;
-+
-       if (netif_elide_gro(skb->dev))
-               goto normal;
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -7628,6 +7628,48 @@ static void __netdev_adjacent_dev_unlink
-                                          &upper_dev->adj_list.lower);
- }
-+static void __netdev_addr_mask(unsigned char *mask, const unsigned char *addr,
-+                             struct net_device *dev)
-+{
-+      int i;
-+
-+      for (i = 0; i < dev->addr_len; i++)
-+              mask[i] |= addr[i] ^ dev->dev_addr[i];
-+}
-+
-+static void __netdev_upper_mask(unsigned char *mask, struct net_device *dev,
-+                              struct net_device *lower)
-+{
-+      struct net_device *cur;
-+      struct list_head *iter;
-+
-+      netdev_for_each_upper_dev_rcu(dev, cur, iter) {
-+              __netdev_addr_mask(mask, cur->dev_addr, lower);
-+              __netdev_upper_mask(mask, cur, lower);
-+      }
-+}
-+
-+static void __netdev_update_addr_mask(struct net_device *dev)
-+{
-+      unsigned char mask[MAX_ADDR_LEN];
-+      struct net_device *cur;
-+      struct list_head *iter;
-+
-+      memset(mask, 0, sizeof(mask));
-+      __netdev_upper_mask(mask, dev, dev);
-+      memcpy(dev->local_addr_mask, mask, dev->addr_len);
-+
-+      netdev_for_each_lower_dev(dev, cur, iter)
-+              __netdev_update_addr_mask(cur);
-+}
-+
-+static void netdev_update_addr_mask(struct net_device *dev)
-+{
-+      rcu_read_lock();
-+      __netdev_update_addr_mask(dev);
-+      rcu_read_unlock();
-+}
-+
- static int __netdev_upper_dev_link(struct net_device *dev,
-                                  struct net_device *upper_dev, bool master,
-                                  void *upper_priv, void *upper_info,
-@@ -7679,6 +7721,7 @@ static int __netdev_upper_dev_link(struc
-       if (ret)
-               return ret;
-+      netdev_update_addr_mask(dev);
-       ret = call_netdevice_notifiers_info(NETDEV_CHANGEUPPER,
-                                           &changeupper_info.info);
-       ret = notifier_to_errno(ret);
-@@ -7775,6 +7818,7 @@ static void __netdev_upper_dev_unlink(st
-       __netdev_adjacent_dev_unlink_neighbour(dev, upper_dev);
-+      netdev_update_addr_mask(dev);
-       call_netdevice_notifiers_info(NETDEV_CHANGEUPPER,
-                                     &changeupper_info.info);
-@@ -8827,6 +8871,7 @@ int dev_set_mac_address(struct net_devic
-       if (err)
-               return err;
-       dev->addr_assign_type = NET_ADDR_SET;
-+      netdev_update_addr_mask(dev);
-       call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
-       add_device_randomness(dev->dev_addr, dev->addr_len);
-       return 0;
---- a/net/ethernet/eth.c
-+++ b/net/ethernet/eth.c
-@@ -143,6 +143,18 @@ u32 eth_get_headlen(const struct net_dev
- }
- EXPORT_SYMBOL(eth_get_headlen);
-+static inline bool
-+eth_check_local_mask(const void *addr1, const void *addr2, const void *mask)
-+{
-+      const u16 *a1 = addr1;
-+      const u16 *a2 = addr2;
-+      const u16 *m = mask;
-+
-+      return (((a1[0] ^ a2[0]) & ~m[0]) |
-+              ((a1[1] ^ a2[1]) & ~m[1]) |
-+              ((a1[2] ^ a2[2]) & ~m[2]));
-+}
-+
- /**
-  * eth_type_trans - determine the packet's protocol ID.
-  * @skb: received socket data
-@@ -174,6 +186,10 @@ __be16 eth_type_trans(struct sk_buff *sk
-               } else {
-                       skb->pkt_type = PACKET_OTHERHOST;
-               }
-+
-+              if (eth_check_local_mask(eth->h_dest, dev->dev_addr,
-+                                       dev->local_addr_mask))
-+                      skb->gro_skip = 1;
-       }
-       /*