4171a69d1d62a6514330ab7e3b769deb4279c2fe
[openwrt/openwrt.git] / target / linux / bmips / patches-5.10 / 010-v5.11-net-dsa-implement-a-central-TX-reallocation-procedur.patch
1 From a3b0b6479700a5b0af2c631cb2ec0fb7a0d978f2 Mon Sep 17 00:00:00 2001
2 From: Vladimir Oltean <vladimir.oltean@nxp.com>
3 Date: Sun, 1 Nov 2020 21:16:09 +0200
4 Subject: [PATCH] net: dsa: implement a central TX reallocation procedure
5
6 At the moment, taggers are left with the task of ensuring that the skb
7 headers are writable (which they aren't, if the frames were cloned for
8 TX timestamping, for flooding by the bridge, etc), and that there is
9 enough space in the skb data area for the DSA tag to be pushed.
10
11 Moreover, the life of tail taggers is even harder, because they need to
12 ensure that short frames have enough padding, a problem that normal
13 taggers don't have.
14
15 The principle of the DSA framework is that everything except for the
16 most intimate hardware specifics (like in this case, the actual packing
17 of the DSA tag bits) should be done inside the core, to avoid having
18 code paths that are very rarely tested.
19
20 So provide a TX reallocation procedure that should cover the known needs
21 of DSA today.
22
23 Note that this patch also gives the network stack a good hint about the
24 headroom/tailroom it's going to need. Up till now it wasn't doing that.
25 So the reallocation procedure should really be there only for the
26 exceptional cases, and for cloned packets which need to be unshared.
27
28 Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
29 Tested-by: Christian Eggers <ceggers@arri.de> # For tail taggers only
30 Tested-by: Kurt Kanzenbach <kurt@linutronix.de>
31 Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
32 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
33 ---
34 net/dsa/slave.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
35 1 file changed, 45 insertions(+)
36
37 --- a/net/dsa/slave.c
38 +++ b/net/dsa/slave.c
39 @@ -548,6 +548,30 @@ netdev_tx_t dsa_enqueue_skb(struct sk_bu
40 }
41 EXPORT_SYMBOL_GPL(dsa_enqueue_skb);
42
43 +static int dsa_realloc_skb(struct sk_buff *skb, struct net_device *dev)
44 +{
45 + int needed_headroom = dev->needed_headroom;
46 + int needed_tailroom = dev->needed_tailroom;
47 +
48 + /* For tail taggers, we need to pad short frames ourselves, to ensure
49 + * that the tail tag does not fail at its role of being at the end of
50 + * the packet, once the master interface pads the frame. Account for
51 + * that pad length here, and pad later.
52 + */
53 + if (unlikely(needed_tailroom && skb->len < ETH_ZLEN))
54 + needed_tailroom += ETH_ZLEN - skb->len;
55 + /* skb_headroom() returns unsigned int... */
56 + needed_headroom = max_t(int, needed_headroom - skb_headroom(skb), 0);
57 + needed_tailroom = max_t(int, needed_tailroom - skb_tailroom(skb), 0);
58 +
59 + if (likely(!needed_headroom && !needed_tailroom && !skb_cloned(skb)))
60 + /* No reallocation needed, yay! */
61 + return 0;
62 +
63 + return pskb_expand_head(skb, needed_headroom, needed_tailroom,
64 + GFP_ATOMIC);
65 +}
66 +
67 static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev)
68 {
69 struct dsa_slave_priv *p = netdev_priv(dev);
70 @@ -567,6 +591,17 @@ static netdev_tx_t dsa_slave_xmit(struct
71 */
72 dsa_skb_tx_timestamp(p, skb);
73
74 + if (dsa_realloc_skb(skb, dev)) {
75 + dev_kfree_skb_any(skb);
76 + return NETDEV_TX_OK;
77 + }
78 +
79 + /* needed_tailroom should still be 'warm' in the cache line from
80 + * dsa_realloc_skb(), which has also ensured that padding is safe.
81 + */
82 + if (dev->needed_tailroom)
83 + eth_skb_pad(skb);
84 +
85 /* Transmit function may have to reallocate the original SKB,
86 * in which case it must have freed it. Only free it here on error.
87 */
88 @@ -1825,6 +1860,16 @@ int dsa_slave_create(struct dsa_port *po
89 slave_dev->netdev_ops = &dsa_slave_netdev_ops;
90 if (ds->ops->port_max_mtu)
91 slave_dev->max_mtu = ds->ops->port_max_mtu(ds, port->index);
92 + if (cpu_dp->tag_ops->tail_tag)
93 + slave_dev->needed_tailroom = cpu_dp->tag_ops->overhead;
94 + else
95 + slave_dev->needed_headroom = cpu_dp->tag_ops->overhead;
96 + /* Try to save one extra realloc later in the TX path (in the master)
97 + * by also inheriting the master's needed headroom and tailroom.
98 + * The 8021q driver also does this.
99 + */
100 + slave_dev->needed_headroom += master->needed_headroom;
101 + slave_dev->needed_tailroom += master->needed_tailroom;
102 SET_NETDEV_DEVTYPE(slave_dev, &dsa_type);
103
104 netdev_for_each_tx_queue(slave_dev, dsa_slave_set_lockdep_class_one,