All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Dumazet <eric.dumazet@gmail.com>
To: Aleksander Jan Bajkowski <olek2@wp.pl>,
	hauke@hauke-m.de, davem@davemloft.net, kuba@kernel.org,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH net-next] net: lantiq_xrx200: add ingress SG DMA support
Date: Tue, 4 Jan 2022 09:41:13 -0800	[thread overview]
Message-ID: <0215980e-a258-5322-13e9-42fe868817b3@gmail.com> (raw)
In-Reply-To: <20220103194316.1116630-1-olek2@wp.pl>


On 1/3/22 11:43, Aleksander Jan Bajkowski wrote:
> This patch adds support for scatter gather DMA. DMA in PMAC splits
> the packet into several buffers when the MTU on the CPU port is
> less than the MTU of the switch. The first buffer starts at an
> offset of NET_IP_ALIGN. In subsequent buffers, dma ignores the
> offset. Thanks to this patch, the user can still connect to the
> device in such a situation. For normal configurations, the patch
> has no effect on performance.
>
> Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
> ---
>   drivers/net/ethernet/lantiq_xrx200.c | 47 +++++++++++++++++++++++-----
>   1 file changed, 40 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/ethernet/lantiq_xrx200.c b/drivers/net/ethernet/lantiq_xrx200.c
> index 80bfaf2fec92..503fb99c5b90 100644
> --- a/drivers/net/ethernet/lantiq_xrx200.c
> +++ b/drivers/net/ethernet/lantiq_xrx200.c
> @@ -27,6 +27,9 @@
>   #define XRX200_DMA_TX		1
>   #define XRX200_DMA_BURST_LEN	8
>   
> +#define XRX200_DMA_PACKET_COMPLETE	0
> +#define XRX200_DMA_PACKET_IN_PROGRESS	1
> +
>   /* cpu port mac */
>   #define PMAC_RX_IPG		0x0024
>   #define PMAC_RX_IPG_MASK	0xf
> @@ -62,6 +65,9 @@ struct xrx200_chan {
>   	struct ltq_dma_channel dma;
>   	struct sk_buff *skb[LTQ_DESC_NUM];
>   
> +	struct sk_buff *skb_head;
> +	struct sk_buff *skb_tail;
> +
>   	struct xrx200_priv *priv;
>   };
>   
> @@ -205,7 +211,8 @@ static int xrx200_hw_receive(struct xrx200_chan *ch)
>   	struct xrx200_priv *priv = ch->priv;
>   	struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
>   	struct sk_buff *skb = ch->skb[ch->dma.desc];
> -	int len = (desc->ctl & LTQ_DMA_SIZE_MASK);
> +	u32 ctl = desc->ctl;
> +	int len = (ctl & LTQ_DMA_SIZE_MASK);
>   	struct net_device *net_dev = priv->net_dev;
>   	int ret;
>   
> @@ -221,12 +228,36 @@ static int xrx200_hw_receive(struct xrx200_chan *ch)
>   	}
>   
>   	skb_put(skb, len);
> -	skb->protocol = eth_type_trans(skb, net_dev);
> -	netif_receive_skb(skb);
> -	net_dev->stats.rx_packets++;
> -	net_dev->stats.rx_bytes += len;
>   
> -	return 0;
> +	/* add buffers to skb via skb->frag_list */
> +	if (ctl & LTQ_DMA_SOP) {
> +		ch->skb_head = skb;
> +		ch->skb_tail = skb;
> +	} else if (ch->skb_head) {
> +		if (ch->skb_head == ch->skb_tail)
> +			skb_shinfo(ch->skb_tail)->frag_list = skb;
> +		else
> +			ch->skb_tail->next = skb;
> +		ch->skb_tail = skb;
> +		skb_reserve(ch->skb_tail, -NET_IP_ALIGN);
> +		ch->skb_head->len += skb->len;
> +		ch->skb_head->data_len += skb->len;
> +		ch->skb_head->truesize += skb->truesize;
> +	}
> +
> +	if (ctl & LTQ_DMA_EOP) {
> +		ch->skb_head->protocol = eth_type_trans(ch->skb_head, net_dev);
> +		netif_receive_skb(ch->skb_head);
> +		net_dev->stats.rx_packets++;
> +		net_dev->stats.rx_bytes += ch->skb_head->len;


Use after free alert.

Please add/test the following fix.

(It is illegal to deref skb after netif_receive_skb())


diff --git a/drivers/net/ethernet/lantiq_xrx200.c 
b/drivers/net/ethernet/lantiq_xrx200.c
index 503fb99c5b90..bf7e3c7910d1 100644
--- a/drivers/net/ethernet/lantiq_xrx200.c
+++ b/drivers/net/ethernet/lantiq_xrx200.c
@@ -247,9 +247,9 @@ static int xrx200_hw_receive(struct xrx200_chan *ch)

         if (ctl & LTQ_DMA_EOP) {
                 ch->skb_head->protocol = eth_type_trans(ch->skb_head, 
net_dev);
-               netif_receive_skb(ch->skb_head);
                 net_dev->stats.rx_packets++;
                 net_dev->stats.rx_bytes += ch->skb_head->len;
+               netif_receive_skb(ch->skb_head);
                 ch->skb_head = NULL;
                 ch->skb_tail = NULL;
                 ret = XRX200_DMA_PACKET_COMPLETE;



> +		ch->skb_head = NULL;
> +		ch->skb_tail = NULL;
> +		ret = XRX200_DMA_PACKET_COMPLETE;
> +	} else {
> +		ret = XRX200_DMA_PACKET_IN_PROGRESS;
> +	}
> +
> +	return ret;
>   }
>   
>   static int xrx200_poll_rx(struct napi_struct *napi, int budget)
> @@ -241,7 +272,9 @@ static int xrx200_poll_rx(struct napi_struct *napi, int budget)
>   
>   		if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) {
>   			ret = xrx200_hw_receive(ch);
> -			if (ret)
> +			if (ret == XRX200_DMA_PACKET_IN_PROGRESS)
> +				continue;
> +			if (ret != XRX200_DMA_PACKET_COMPLETE)
>   				return ret;
>   			rx++;
>   		} else {

  parent reply	other threads:[~2022-01-04 17:41 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-03 19:43 [PATCH net-next] net: lantiq_xrx200: add ingress SG DMA support Aleksander Jan Bajkowski
2022-01-04 12:40 ` patchwork-bot+netdevbpf
2022-01-04 17:41 ` Eric Dumazet [this message]
2022-01-08 13:27   ` Aleksander Bajkowski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0215980e-a258-5322-13e9-42fe868817b3@gmail.com \
    --to=eric.dumazet@gmail.com \
    --cc=davem@davemloft.net \
    --cc=hauke@hauke-m.de \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=olek2@wp.pl \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.