linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next v2] net: stmmac: Enable TSO on VLANs
@ 2024-06-14  6:03 Furong Xu
  2024-06-14  6:29 ` Eric Dumazet
  2024-06-14 10:43 ` Vadim Fedorenko
  0 siblings, 2 replies; 3+ messages in thread
From: Furong Xu @ 2024-06-14  6:03 UTC (permalink / raw)
  To: Russell King (Oracle), David S. Miller, Alexandre Torgue,
	Jose Abreu, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Maxime Coquelin, Joao Pinto, Corinna Vinschen
  Cc: netdev, linux-stm32, linux-arm-kernel, linux-kernel, xfr, rock.xu,
	Furong Xu

The TSO engine works well when the frames are not VLAN Tagged.
But it will produce broken segments when frames are VLAN Tagged.

The first segment is all good, while the second segment to the
last segment are broken, they lack of required VLAN tag.

An example here:
========
// 1st segment of a VLAN Tagged TSO frame, nothing wrong.
MacSrc > MacDst, ethertype 802.1Q (0x8100), length 1518: vlan 100, p 1, ethertype IPv4 (0x0800), HostA:42643 > HostB:5201: Flags [.], seq 1:1449

// 2nd to last segments of a VLAN Tagged TSO frame, VLAN tag is missing.
MacSrc > MacDst, ethertype IPv4 (0x0800), length 1514: HostA:42643 > HostB:5201: Flags [.], seq 1449:2897
MacSrc > MacDst, ethertype IPv4 (0x0800), length 1514: HostA:42643 > HostB:5201: Flags [.], seq 2897:4345
MacSrc > MacDst, ethertype IPv4 (0x0800), length 1514: HostA:42643 > HostB:5201: Flags [.], seq 4345:5793
MacSrc > MacDst, ethertype IPv4 (0x0800), length 1514: HostA:42643 > HostB:5201: Flags [P.], seq 5793:7241

// normal VLAN Tagged non-TSO frame, nothing wrong.
MacSrc > MacDst, ethertype 802.1Q (0x8100), length 1022: vlan 100, p 1, ethertype IPv4 (0x0800), HostA:42643 > HostB:5201: Flags [P.], seq 7241:8193
MacSrc > MacDst, ethertype 802.1Q (0x8100), length 70: vlan 100, p 1, ethertype IPv4 (0x0800), HostA:42643 > HostB:5201: Flags [F.], seq 8193
========

When transmitting VLAN Tagged TSO frames, never insert VLAN tag by HW,
always insert VLAN tag to SKB payload, then TSO works well on VLANs for
all MAC cores.

Tested on DWMAC CORE 5.10a, DWMAC CORE 5.20a and DWXGMAC CORE 3.20a

Signed-off-by: Furong Xu <0x1207@gmail.com>
---
  Changes in v2:
    - Use __vlan_hwaccel_push_inside() to insert vlan tag to the payload.
---
 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 27 ++++++++++---------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index bbedf2a8c60f..e8cbfada63ca 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -4233,18 +4233,27 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct dma_desc *desc, *first, *mss_desc = NULL;
 	struct stmmac_priv *priv = netdev_priv(dev);
-	int nfrags = skb_shinfo(skb)->nr_frags;
-	u32 queue = skb_get_queue_mapping(skb);
 	unsigned int first_entry, tx_packets;
 	struct stmmac_txq_stats *txq_stats;
-	int tmp_pay_len = 0, first_tx;
+	int tmp_pay_len = 0, first_tx, nfrags;
 	struct stmmac_tx_queue *tx_q;
-	bool has_vlan, set_ic;
+	bool set_ic;
 	u8 proto_hdr_len, hdr;
-	u32 pay_len, mss;
+	u32 pay_len, mss, queue;
 	dma_addr_t des;
 	int i;
 
+	/* Always insert VLAN tag to SKB payload for TSO frames.
+	 *
+	 * Never insert VLAN tag by HW, since segments splited by
+	 * TSO engine will be un-tagged by mistake.
+	 */
+	if (skb_vlan_tag_present(skb))
+		skb = __vlan_hwaccel_push_inside(skb);
+
+	nfrags = skb_shinfo(skb)->nr_frags;
+	queue = skb_get_queue_mapping(skb);
+
 	tx_q = &priv->dma_conf.tx_queue[queue];
 	txq_stats = &priv->xstats.txq_stats[queue];
 	first_tx = tx_q->cur_tx;
@@ -4297,9 +4306,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 			skb->data_len);
 	}
 
-	/* Check if VLAN can be inserted by HW */
-	has_vlan = stmmac_vlan_insert(priv, skb, tx_q);
-
 	first_entry = tx_q->cur_tx;
 	WARN_ON(tx_q->tx_skbuff[first_entry]);
 
@@ -4309,9 +4315,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 		desc = &tx_q->dma_tx[first_entry];
 	first = desc;
 
-	if (has_vlan)
-		stmmac_set_desc_vlan(priv, first, STMMAC_VLAN_INSERT);
-
 	/* first descriptor: fill Headers on Buf1 */
 	des = dma_map_single(priv->device, skb->data, skb_headlen(skb),
 			     DMA_TO_DEVICE);
@@ -7678,8 +7681,6 @@ int stmmac_dvr_probe(struct device *device,
 		ndev->features |= NETIF_F_RXHASH;
 
 	ndev->vlan_features |= ndev->features;
-	/* TSO doesn't work on VLANs yet */
-	ndev->vlan_features &= ~NETIF_F_TSO;
 
 	/* MTU range: 46 - hw-specific max */
 	ndev->min_mtu = ETH_ZLEN - ETH_HLEN;
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH net-next v2] net: stmmac: Enable TSO on VLANs
  2024-06-14  6:03 [PATCH net-next v2] net: stmmac: Enable TSO on VLANs Furong Xu
@ 2024-06-14  6:29 ` Eric Dumazet
  2024-06-14 10:43 ` Vadim Fedorenko
  1 sibling, 0 replies; 3+ messages in thread
From: Eric Dumazet @ 2024-06-14  6:29 UTC (permalink / raw)
  To: Furong Xu
  Cc: Russell King (Oracle), David S. Miller, Alexandre Torgue,
	Jose Abreu, Jakub Kicinski, Paolo Abeni, Maxime Coquelin,
	Joao Pinto, Corinna Vinschen, netdev, linux-stm32,
	linux-arm-kernel, linux-kernel, xfr, rock.xu

On Fri, Jun 14, 2024 at 8:04 AM Furong Xu <0x1207@gmail.com> wrote:
>
> The TSO engine works well when the frames are not VLAN Tagged.
> But it will produce broken segments when frames are VLAN Tagged.
>
> The first segment is all good, while the second segment to the
> last segment are broken, they lack of required VLAN tag.
>
> An example here:
> ========
> // 1st segment of a VLAN Tagged TSO frame, nothing wrong.
> MacSrc > MacDst, ethertype 802.1Q (0x8100), length 1518: vlan 100, p 1, ethertype IPv4 (0x0800), HostA:42643 > HostB:5201: Flags [.], seq 1:1449
>
> // 2nd to last segments of a VLAN Tagged TSO frame, VLAN tag is missing.
> MacSrc > MacDst, ethertype IPv4 (0x0800), length 1514: HostA:42643 > HostB:5201: Flags [.], seq 1449:2897
> MacSrc > MacDst, ethertype IPv4 (0x0800), length 1514: HostA:42643 > HostB:5201: Flags [.], seq 2897:4345
> MacSrc > MacDst, ethertype IPv4 (0x0800), length 1514: HostA:42643 > HostB:5201: Flags [.], seq 4345:5793
> MacSrc > MacDst, ethertype IPv4 (0x0800), length 1514: HostA:42643 > HostB:5201: Flags [P.], seq 5793:7241
>
> // normal VLAN Tagged non-TSO frame, nothing wrong.
> MacSrc > MacDst, ethertype 802.1Q (0x8100), length 1022: vlan 100, p 1, ethertype IPv4 (0x0800), HostA:42643 > HostB:5201: Flags [P.], seq 7241:8193
> MacSrc > MacDst, ethertype 802.1Q (0x8100), length 70: vlan 100, p 1, ethertype IPv4 (0x0800), HostA:42643 > HostB:5201: Flags [F.], seq 8193
> ========
>
> When transmitting VLAN Tagged TSO frames, never insert VLAN tag by HW,
> always insert VLAN tag to SKB payload, then TSO works well on VLANs for
> all MAC cores.
>
> Tested on DWMAC CORE 5.10a, DWMAC CORE 5.20a and DWXGMAC CORE 3.20a
>
> Signed-off-by: Furong Xu <0x1207@gmail.com>
> ---
>   Changes in v2:
>     - Use __vlan_hwaccel_push_inside() to insert vlan tag to the payload.
> ---
>  .../net/ethernet/stmicro/stmmac/stmmac_main.c | 27 ++++++++++---------
>  1 file changed, 14 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index bbedf2a8c60f..e8cbfada63ca 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -4233,18 +4233,27 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
>  {
>         struct dma_desc *desc, *first, *mss_desc = NULL;
>         struct stmmac_priv *priv = netdev_priv(dev);
> -       int nfrags = skb_shinfo(skb)->nr_frags;
> -       u32 queue = skb_get_queue_mapping(skb);
>         unsigned int first_entry, tx_packets;
>         struct stmmac_txq_stats *txq_stats;
> -       int tmp_pay_len = 0, first_tx;
> +       int tmp_pay_len = 0, first_tx, nfrags;
>         struct stmmac_tx_queue *tx_q;
> -       bool has_vlan, set_ic;
> +       bool set_ic;
>         u8 proto_hdr_len, hdr;
> -       u32 pay_len, mss;
> +       u32 pay_len, mss, queue;
>         dma_addr_t des;
>         int i;
>
> +       /* Always insert VLAN tag to SKB payload for TSO frames.
> +        *
> +        * Never insert VLAN tag by HW, since segments splited by
> +        * TSO engine will be un-tagged by mistake.
> +        */
> +       if (skb_vlan_tag_present(skb))
> +               skb = __vlan_hwaccel_push_inside(skb);

skb can be NULL after this point.

> +
> +       nfrags = skb_shinfo(skb)->nr_frags;
> +       queue = skb_get_queue_mapping(skb);
> +
>         tx_q = &priv->dma_conf.tx_queue[queue];
>         txq_stats = &priv->xstats.txq_stats[queue];
>         first_tx = tx_q->cur_tx;
> @@ -4297,9 +4306,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
>                         skb->data_len);
>         }
>
> -       /* Check if VLAN can be inserted by HW */
> -       has_vlan = stmmac_vlan_insert(priv, skb, tx_q);
> -
>         first_entry = tx_q->cur_tx;
>         WARN_ON(tx_q->tx_skbuff[first_entry]);
>
> @@ -4309,9 +4315,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
>                 desc = &tx_q->dma_tx[first_entry];
>         first = desc;
>
> -       if (has_vlan)
> -               stmmac_set_desc_vlan(priv, first, STMMAC_VLAN_INSERT);
> -
>         /* first descriptor: fill Headers on Buf1 */
>         des = dma_map_single(priv->device, skb->data, skb_headlen(skb),
>                              DMA_TO_DEVICE);
> @@ -7678,8 +7681,6 @@ int stmmac_dvr_probe(struct device *device,
>                 ndev->features |= NETIF_F_RXHASH;
>
>         ndev->vlan_features |= ndev->features;
> -       /* TSO doesn't work on VLANs yet */
> -       ndev->vlan_features &= ~NETIF_F_TSO;
>
>         /* MTU range: 46 - hw-specific max */
>         ndev->min_mtu = ETH_ZLEN - ETH_HLEN;
> --
> 2.34.1
>


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH net-next v2] net: stmmac: Enable TSO on VLANs
  2024-06-14  6:03 [PATCH net-next v2] net: stmmac: Enable TSO on VLANs Furong Xu
  2024-06-14  6:29 ` Eric Dumazet
@ 2024-06-14 10:43 ` Vadim Fedorenko
  1 sibling, 0 replies; 3+ messages in thread
From: Vadim Fedorenko @ 2024-06-14 10:43 UTC (permalink / raw)
  To: Furong Xu, Russell King (Oracle), David S. Miller,
	Alexandre Torgue, Jose Abreu, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Maxime Coquelin, Joao Pinto, Corinna Vinschen
  Cc: netdev, linux-stm32, linux-arm-kernel, linux-kernel, xfr, rock.xu

On 14/06/2024 07:03, Furong Xu wrote:
> The TSO engine works well when the frames are not VLAN Tagged.
> But it will produce broken segments when frames are VLAN Tagged.
> 
> The first segment is all good, while the second segment to the
> last segment are broken, they lack of required VLAN tag.
> 
> An example here:
> ========
> // 1st segment of a VLAN Tagged TSO frame, nothing wrong.
> MacSrc > MacDst, ethertype 802.1Q (0x8100), length 1518: vlan 100, p 1, ethertype IPv4 (0x0800), HostA:42643 > HostB:5201: Flags [.], seq 1:1449
> 
> // 2nd to last segments of a VLAN Tagged TSO frame, VLAN tag is missing.
> MacSrc > MacDst, ethertype IPv4 (0x0800), length 1514: HostA:42643 > HostB:5201: Flags [.], seq 1449:2897
> MacSrc > MacDst, ethertype IPv4 (0x0800), length 1514: HostA:42643 > HostB:5201: Flags [.], seq 2897:4345
> MacSrc > MacDst, ethertype IPv4 (0x0800), length 1514: HostA:42643 > HostB:5201: Flags [.], seq 4345:5793
> MacSrc > MacDst, ethertype IPv4 (0x0800), length 1514: HostA:42643 > HostB:5201: Flags [P.], seq 5793:7241
> 
> // normal VLAN Tagged non-TSO frame, nothing wrong.
> MacSrc > MacDst, ethertype 802.1Q (0x8100), length 1022: vlan 100, p 1, ethertype IPv4 (0x0800), HostA:42643 > HostB:5201: Flags [P.], seq 7241:8193
> MacSrc > MacDst, ethertype 802.1Q (0x8100), length 70: vlan 100, p 1, ethertype IPv4 (0x0800), HostA:42643 > HostB:5201: Flags [F.], seq 8193
> ========
> 
> When transmitting VLAN Tagged TSO frames, never insert VLAN tag by HW,
> always insert VLAN tag to SKB payload, then TSO works well on VLANs for
> all MAC cores.
> 
> Tested on DWMAC CORE 5.10a, DWMAC CORE 5.20a and DWXGMAC CORE 3.20a
> 
> Signed-off-by: Furong Xu <0x1207@gmail.com>
> ---
>    Changes in v2:
>      - Use __vlan_hwaccel_push_inside() to insert vlan tag to the payload.
> ---
>   .../net/ethernet/stmicro/stmmac/stmmac_main.c | 27 ++++++++++---------
>   1 file changed, 14 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index bbedf2a8c60f..e8cbfada63ca 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -4233,18 +4233,27 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
>   {
>   	struct dma_desc *desc, *first, *mss_desc = NULL;
>   	struct stmmac_priv *priv = netdev_priv(dev);
> -	int nfrags = skb_shinfo(skb)->nr_frags;
> -	u32 queue = skb_get_queue_mapping(skb);
>   	unsigned int first_entry, tx_packets;
>   	struct stmmac_txq_stats *txq_stats;
> -	int tmp_pay_len = 0, first_tx;
> +	int tmp_pay_len = 0, first_tx, nfrags;
>   	struct stmmac_tx_queue *tx_q;
> -	bool has_vlan, set_ic;
> +	bool set_ic;
>   	u8 proto_hdr_len, hdr;
> -	u32 pay_len, mss;
> +	u32 pay_len, mss, queue;
>   	dma_addr_t des;
>   	int i;
>   

As there will be another iteration, could you please re-arrange
variables to keep reverse x-mas tree order?




^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-06-14 10:43 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-14  6:03 [PATCH net-next v2] net: stmmac: Enable TSO on VLANs Furong Xu
2024-06-14  6:29 ` Eric Dumazet
2024-06-14 10:43 ` Vadim Fedorenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).