Re: [PATCH v2 1/2] net: dsa: ensure linearized SKBs in case of tail taggers

From: Florian Fainelli
Date: Thu Jul 22 2021 - 00:02:32 EST




On 7/21/2021 4:35 PM, Vladimir Oltean wrote:
On Wed, Jul 21, 2021 at 11:56:41PM +0200, Lino Sanfilippo wrote:
The function skb_put() that is used by tail taggers to make room for the
DSA tag must only be called for linearized SKBS. However in case that the
slave device inherited features like NETIF_F_HW_SG or NETIF_F_FRAGLIST the
SKB passed to the slaves transmit function may not be linearized.
Avoid those SKBs by clearing the NETIF_F_HW_SG and NETIF_F_FRAGLIST flags
for tail taggers.
Furthermore since the tagging protocol can be changed at runtime move the
code for setting up the slaves features into dsa_slave_setup_tagger().

Suggested-by: Vladimir Oltean <olteanv@xxxxxxxxx>
Signed-off-by: Lino Sanfilippo <LinoSanfilippo@xxxxxx>
---
net/dsa/slave.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 22ce11cd770e..ae2a648ed9be 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -1808,6 +1808,7 @@ void dsa_slave_setup_tagger(struct net_device *slave)
struct dsa_slave_priv *p = netdev_priv(slave);
const struct dsa_port *cpu_dp = dp->cpu_dp;
struct net_device *master = cpu_dp->master;
+ const struct dsa_switch *ds = dp->ds;
slave->needed_headroom = cpu_dp->tag_ops->needed_headroom;
slave->needed_tailroom = cpu_dp->tag_ops->needed_tailroom;
@@ -1819,6 +1820,14 @@ void dsa_slave_setup_tagger(struct net_device *slave)
slave->needed_tailroom += master->needed_tailroom;
p->xmit = cpu_dp->tag_ops->xmit;
+
+ slave->features = master->vlan_features | NETIF_F_HW_TC;
+ if (ds->ops->port_vlan_add && ds->ops->port_vlan_del)
+ slave->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
+ slave->hw_features |= NETIF_F_HW_TC;
+ slave->features |= NETIF_F_LLTX;
+ if (slave->needed_tailroom)
+ slave->features &= ~(NETIF_F_SG | NETIF_F_FRAGLIST);
}
static struct lock_class_key dsa_slave_netdev_xmit_lock_key;
@@ -1881,11 +1890,6 @@ int dsa_slave_create(struct dsa_port *port)
if (slave_dev == NULL)
return -ENOMEM;
- slave_dev->features = master->vlan_features | NETIF_F_HW_TC;
- if (ds->ops->port_vlan_add && ds->ops->port_vlan_del)
- slave_dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
- slave_dev->hw_features |= NETIF_F_HW_TC;
- slave_dev->features |= NETIF_F_LLTX;
slave_dev->ethtool_ops = &dsa_slave_ethtool_ops;
if (!is_zero_ether_addr(port->mac))
ether_addr_copy(slave_dev->dev_addr, port->mac);
--
2.32.0


I would have probably changed the code in dsa_slave_create just like
this:

- slave->features = master->vlan_features | NETIF_F_HW_TC;
+ slave->features = NETIF_F_HW_TC;
...
- slave_dev->vlan_features = master->vlan_features;

and in dsa_slave_setup_tagger:

+ vlan_features = master->vlan_features;
+ slave->features &= ~vlan_features;
+ if (slave->needed_tailroom)
+ vlan_features &= ~(NETIF_F_SG | NETIF_F_FRAGLIST);
+ slave->features |= vlan_features;
+ slave->vlan_features = vlan_features;

no need to move around NETIF_F_HW_TC and NETIF_F_LLTX. Makes sense?

And I would probably add:

Fixes: 91da11f870f0 ("net: Distributed Switch Architecture protocol support")

Agreed, with those fixed:

Reviewed-by: Florian Fainelli <f.fainelli@xxxxxxxxx>
--
Florian