Skip to content

Commit a3b0b64

Browse files
vladimirolteankuba-moo
authored andcommitted
net: dsa: implement a central TX reallocation procedure
At the moment, taggers are left with the task of ensuring that the skb headers are writable (which they aren't, if the frames were cloned for TX timestamping, for flooding by the bridge, etc), and that there is enough space in the skb data area for the DSA tag to be pushed. Moreover, the life of tail taggers is even harder, because they need to ensure that short frames have enough padding, a problem that normal taggers don't have. The principle of the DSA framework is that everything except for the most intimate hardware specifics (like in this case, the actual packing of the DSA tag bits) should be done inside the core, to avoid having code paths that are very rarely tested. So provide a TX reallocation procedure that should cover the known needs of DSA today. Note that this patch also gives the network stack a good hint about the headroom/tailroom it's going to need. Up till now it wasn't doing that. So the reallocation procedure should really be there only for the exceptional cases, and for cloned packets which need to be unshared. Signed-off-by: Vladimir Oltean <[email protected]> Tested-by: Christian Eggers <[email protected]> # For tail taggers only Tested-by: Kurt Kanzenbach <[email protected]> Reviewed-by: Florian Fainelli <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 92f9e23 commit a3b0b64

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

net/dsa/slave.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,30 @@ netdev_tx_t dsa_enqueue_skb(struct sk_buff *skb, struct net_device *dev)
548548
}
549549
EXPORT_SYMBOL_GPL(dsa_enqueue_skb);
550550

551+
static int dsa_realloc_skb(struct sk_buff *skb, struct net_device *dev)
552+
{
553+
int needed_headroom = dev->needed_headroom;
554+
int needed_tailroom = dev->needed_tailroom;
555+
556+
/* For tail taggers, we need to pad short frames ourselves, to ensure
557+
* that the tail tag does not fail at its role of being at the end of
558+
* the packet, once the master interface pads the frame. Account for
559+
* that pad length here, and pad later.
560+
*/
561+
if (unlikely(needed_tailroom && skb->len < ETH_ZLEN))
562+
needed_tailroom += ETH_ZLEN - skb->len;
563+
/* skb_headroom() returns unsigned int... */
564+
needed_headroom = max_t(int, needed_headroom - skb_headroom(skb), 0);
565+
needed_tailroom = max_t(int, needed_tailroom - skb_tailroom(skb), 0);
566+
567+
if (likely(!needed_headroom && !needed_tailroom && !skb_cloned(skb)))
568+
/* No reallocation needed, yay! */
569+
return 0;
570+
571+
return pskb_expand_head(skb, needed_headroom, needed_tailroom,
572+
GFP_ATOMIC);
573+
}
574+
551575
static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev)
552576
{
553577
struct dsa_slave_priv *p = netdev_priv(dev);
@@ -567,6 +591,17 @@ static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev)
567591
*/
568592
dsa_skb_tx_timestamp(p, skb);
569593

594+
if (dsa_realloc_skb(skb, dev)) {
595+
dev_kfree_skb_any(skb);
596+
return NETDEV_TX_OK;
597+
}
598+
599+
/* needed_tailroom should still be 'warm' in the cache line from
600+
* dsa_realloc_skb(), which has also ensured that padding is safe.
601+
*/
602+
if (dev->needed_tailroom)
603+
eth_skb_pad(skb);
604+
570605
/* Transmit function may have to reallocate the original SKB,
571606
* in which case it must have freed it. Only free it here on error.
572607
*/
@@ -1791,6 +1826,16 @@ int dsa_slave_create(struct dsa_port *port)
17911826
slave_dev->netdev_ops = &dsa_slave_netdev_ops;
17921827
if (ds->ops->port_max_mtu)
17931828
slave_dev->max_mtu = ds->ops->port_max_mtu(ds, port->index);
1829+
if (cpu_dp->tag_ops->tail_tag)
1830+
slave_dev->needed_tailroom = cpu_dp->tag_ops->overhead;
1831+
else
1832+
slave_dev->needed_headroom = cpu_dp->tag_ops->overhead;
1833+
/* Try to save one extra realloc later in the TX path (in the master)
1834+
* by also inheriting the master's needed headroom and tailroom.
1835+
* The 8021q driver also does this.
1836+
*/
1837+
slave_dev->needed_headroom += master->needed_headroom;
1838+
slave_dev->needed_tailroom += master->needed_tailroom;
17941839
SET_NETDEV_DEVTYPE(slave_dev, &dsa_type);
17951840

17961841
netdev_for_each_tx_queue(slave_dev, dsa_slave_set_lockdep_class_one,

0 commit comments

Comments
 (0)