[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20210206115040.0d887565@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>
Date: Sat, 6 Feb 2021 11:50:40 -0800
From: Jakub Kicinski <kuba@...nel.org>
To: Lorenzo Bianconi <lorenzo.bianconi@...hat.com>
Cc: Kalle Valo <kvalo@...eaurora.org>,
Lorenzo Bianconi <lorenzo@...nel.org>, netdev@...r.kernel.org,
linux-wireless@...r.kernel.org, Felix Fietkau <nbd@....name>
Subject: Re: pull-request: wireless-drivers-2021-02-05
On Sat, 6 Feb 2021 20:43:25 +0100 Lorenzo Bianconi wrote:
> > Lorenzo, I'm just guessing what this code does, but you're dropping a
> > frag without invalidating the rest of the SKB, which I presume is now
> > truncated? Shouldn't the skb be dropped?
> >
>
> Hi Jakub,
>
> I agree. We can do something like:
>
> diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
> index e81dfaf99bcb..6d84533d1df2 100644
> --- a/drivers/net/wireless/mediatek/mt76/dma.c
> +++ b/drivers/net/wireless/mediatek/mt76/dma.c
> @@ -511,8 +511,9 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data,
> {
> struct sk_buff *skb = q->rx_head;
> struct skb_shared_info *shinfo = skb_shinfo(skb);
> + int nr_frags = shinfo->nr_frags;
>
> - if (shinfo->nr_frags < ARRAY_SIZE(shinfo->frags)) {
> + if (nr_frags < ARRAY_SIZE(shinfo->frags)) {
> struct page *page = virt_to_head_page(data);
> int offset = data - page_address(page) + q->buf_offset;
>
> @@ -526,7 +527,10 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data,
> return;
>
> q->rx_head = NULL;
> - dev->drv->rx_skb(dev, q - dev->q_rx, skb);
> + if (nr_frags < ARRAY_SIZE(shinfo->frags))
> + dev->drv->rx_skb(dev, q - dev->q_rx, skb);
> + else
> + dev_kfree_skb(skb);
> }
>
>
> I do not know if it can occur, but I guess we should even check q->rx_head
> pointer before overwriting it because if the hw does not report more set to
> false for last fragment we will get a memory leak as well. Something like:
>
> @@ -578,6 +582,8 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
> done++;
>
> if (more) {
> + if (q->rx_head)
> + dev_kfree_skb(q->rx_head);
> q->rx_head = skb;
> continue;
> }
👍
Powered by blists - more mailing lists