[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20201016200226.23994-2-ceggers@arri.de>
Date: Fri, 16 Oct 2020 22:02:24 +0200
From: Christian Eggers <ceggers@...i.de>
To: Andrew Lunn <andrew@...n.ch>,
Vivien Didelot <vivien.didelot@...il.com>,
Florian Fainelli <f.fainelli@...il.com>,
Vladimir Oltean <olteanv@...il.com>,
Jakub Kicinski <kuba@...nel.org>,
Kurt Kanzenbach <kurt@...utronix.de>
CC: "David S . Miller" <davem@...emloft.net>,
Woojung Huh <woojung.huh@...rochip.com>,
Microchip Linux Driver Support <UNGLinuxDriver@...rochip.com>,
<netdev@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
Christian Eggers <ceggers@...i.de>
Subject: [PATCH net-next 1/3] net: dsa: don't pass cloned skb's to drivers xmit function
Ensure that the skb is not cloned and has enough tail room for the tail
tag. This code will be removed from the drivers in the next commits.
Signed-off-by: Christian Eggers <ceggers@...i.de>
---
net/dsa/dsa_priv.h | 3 +++
net/dsa/slave.c | 38 ++++++++++++++++++++++++++++++++++++++
2 files changed, 41 insertions(+)
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index 12998bf04e55..975001c625b1 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -77,6 +77,9 @@ struct dsa_slave_priv {
/* Copy of CPU port xmit for faster access in slave transmit hot path */
struct sk_buff * (*xmit)(struct sk_buff *skb,
struct net_device *dev);
+ /* same for tail_tag and overhead */
+ bool tail_tag;
+ unsigned int overhead;
struct pcpu_sw_netstats __percpu *stats64;
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 3bc5ca40c9fb..49a19a3b0736 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -553,6 +553,7 @@ static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev)
struct dsa_slave_priv *p = netdev_priv(dev);
struct pcpu_sw_netstats *s;
struct sk_buff *nskb;
+ int padlen;
s = this_cpu_ptr(p->stats64);
u64_stats_update_begin(&s->syncp);
@@ -567,6 +568,41 @@ static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev)
*/
dsa_skb_tx_timestamp(p, skb);
+ /* We have to pad he packet to the minimum Ethernet frame size,
+ * if necessary, before adding the trailer (tail tagging only).
+ */
+ padlen = (skb->len >= ETH_ZLEN) ? 0 : ETH_ZLEN - skb->len;
+
+ /* To keep the slave's xmit() methods simple, don't pass cloned skbs to
+ * them. Additionally ensure, that suitable room for tail tagging is
+ * available.
+ */
+ if (skb_cloned(skb) ||
+ (p->tail_tag && skb_tailroom(skb) < (padlen + p->overhead))) {
+ struct sk_buff *nskb;
+
+ nskb = alloc_skb(NET_IP_ALIGN + skb->len +
+ padlen + p->overhead, GFP_ATOMIC);
+ if (!nskb) {
+ kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+ skb_reserve(nskb, NET_IP_ALIGN);
+
+ skb_reset_mac_header(nskb);
+ skb_set_network_header(nskb,
+ skb_network_header(skb) - skb->head);
+ skb_set_transport_header(nskb,
+ skb_transport_header(skb) - skb->head);
+ skb_copy_and_csum_dev(skb, skb_put(nskb, skb->len));
+ consume_skb(skb);
+
+ if (padlen)
+ skb_put_zero(nskb, padlen);
+
+ skb = nskb;
+ }
+
/* Transmit function may have to reallocate the original SKB,
* in which case it must have freed it. Only free it here on error.
*/
@@ -1814,6 +1850,8 @@ int dsa_slave_create(struct dsa_port *port)
p->dp = port;
INIT_LIST_HEAD(&p->mall_tc_list);
p->xmit = cpu_dp->tag_ops->xmit;
+ p->tail_tag = cpu_dp->tag_ops->tail_tag;
+ p->overhead = cpu_dp->tag_ops->overhead;
port->slave = slave_dev;
rtnl_lock();
--
Christian Eggers
Embedded software developer
Arnold & Richter Cine Technik GmbH & Co. Betriebs KG
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918
Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477
Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler
Powered by blists - more mailing lists