> On Fri, 5 Feb 2021 16:34:34 +0000 (UTC) Kalle Valo wrote: > > Hi, > > > > here's a pull request to net tree, more info below. Please let me know if > > there > > are any problems. > > Pulled, thanks! One thing to confirm tho.. > > > ath9k > > > > * fix build regression related to LEDS_CLASS > > > > mt76 > > > > * fix a memory leak > > 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;
}
Regards,
Lorenzo
signature.asc
Description: PGP signature
