1 From: Alexander Lobakin <bloodyreaper@yandex.ru>
2 Date: Tue, 21 Apr 2020 16:41:08 +0300
3 Subject: [PATCH] net: dsa: add GRO support via gro_cells
5 gro_cells lib is used by different encapsulating netdevices, such as
6 geneve, macsec, vxlan etc. to speed up decapsulated traffic processing.
7 CPU tag is a sort of "encapsulation", and we can use the same mechs to
8 greatly improve overall DSA performance.
9 skbs are passed to the GRO layer after removing CPU tags, so we don't
10 need any new packet offload types as it was firstly proposed by me in
11 the first GRO-over-DSA variant [1].
13 The size of struct gro_cells is sizeof(void *), so hot struct
14 dsa_slave_priv becomes only 4/8 bytes bigger, and all critical fields
15 remain in one 32-byte cacheline.
16 The other positive side effect is that drivers for network devices
17 that can be shipped as CPU ports of DSA-driven switches can now use
18 napi_gro_frags() to pass skbs to kernel. Packets built that way are
19 completely non-linear and are likely being dropped without GRO.
21 This was tested on to-be-mainlined-soon Ethernet driver that uses
22 napi_gro_frags(), and the overall performance was on par with the
23 variant from [1], sometimes even better due to minimal overhead.
24 net.core.gro_normal_batch tuning may help to push it to the limit
25 on particular setups and platforms.
27 iperf3 IPoE VLAN NAT TCP forwarding (port1.218 -> port0) setup
28 on 1.2 GHz MIPS board:
32 [ID] Interval Transfer Bitrate Retr
33 [ 5] 0.00-120.01 sec 9.00 GBytes 644 Mbits/sec 413 sender
34 [ 5] 0.00-120.00 sec 8.99 GBytes 644 Mbits/sec receiver
36 Iface RX packets TX packets
40 port1.218 6671677 425851
44 [ID] Interval Transfer Bitrate Retr
45 [ 5] 0.00-120.01 sec 12.2 GBytes 870 Mbits/sec 122 sender
46 [ 5] 0.00-120.00 sec 12.2 GBytes 870 Mbits/sec receiver
48 Iface RX packets TX packets
52 port1.218 353144 455024
55 - Add some performance examples in the commit message;
56 - No functional changes.
58 [1] https://lore.kernel.org/netdev/20191230143028.27313-1-alobakin@dlink.ru/
60 Signed-off-by: Alexander Lobakin <bloodyreaper@yandex.ru>
61 Signed-off-by: David S. Miller <davem@davemloft.net>
66 @@ -9,6 +9,7 @@ menuconfig NET_DSA
67 tristate "Distributed Switch Architecture"
68 depends on HAVE_NET_DSA
69 depends on BRIDGE || BRIDGE=n
76 @@ -238,7 +238,7 @@ static int dsa_switch_rcv(struct sk_buff
77 if (dsa_skb_defer_rx_timestamp(p, skb))
80 - netif_receive_skb(skb);
81 + gro_cells_receive(&p->gcells, skb);
85 --- a/net/dsa/dsa_priv.h
86 +++ b/net/dsa/dsa_priv.h
88 #include <linux/netdevice.h>
89 #include <linux/netpoll.h>
91 +#include <net/gro_cells.h>
94 DSA_NOTIFIER_AGEING_TIME,
95 @@ -68,6 +69,8 @@ struct dsa_slave_priv {
97 struct pcpu_sw_netstats *stats64;
99 + struct gro_cells gcells;
101 /* DSA port data, such as switch, port index, etc. */
104 --- a/net/dsa/slave.c
105 +++ b/net/dsa/slave.c
106 @@ -1431,6 +1431,11 @@ int dsa_slave_create(struct dsa_port *po
107 free_netdev(slave_dev);
111 + ret = gro_cells_init(&p->gcells, slave_dev);
116 INIT_LIST_HEAD(&p->mall_tc_list);
117 INIT_WORK(&port->xmit_work, dsa_port_xmit_work);
118 @@ -1443,7 +1448,7 @@ int dsa_slave_create(struct dsa_port *po
119 ret = dsa_slave_phy_setup(slave_dev);
121 netdev_err(master, "error %d setting up slave phy\n", ret);
126 dsa_slave_notify(slave_dev, DSA_PORT_REGISTER);
127 @@ -1462,6 +1467,8 @@ out_phy:
128 phylink_disconnect_phy(p->dp->pl);
130 phylink_destroy(p->dp->pl);
132 + gro_cells_destroy(&p->gcells);
134 free_percpu(p->stats64);
135 free_netdev(slave_dev);
136 @@ -1482,6 +1489,7 @@ void dsa_slave_destroy(struct net_device
137 dsa_slave_notify(slave_dev, DSA_PORT_UNREGISTER);
138 unregister_netdev(slave_dev);
139 phylink_destroy(dp->pl);
140 + gro_cells_destroy(&p->gcells);
141 free_percpu(p->stats64);
142 free_netdev(slave_dev);