[PATCH 6.6 099/156] wifi: mt76: fix crash with WED rx support enabled

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



6.6-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Felix Fietkau <nbd@xxxxxxxx>

commit cd607f2cbbbec90682b2f6d6b85e1525d0f43b19 upstream.

If WED rx is enabled, rx buffers are added to a buffer pool that can be
filled from multiple page pools. Because buffers freed from rx poll are
not guaranteed to belong to the processed queue's page pool, lockless
caching must not be used in this case.

Cc: stable@xxxxxxxxxxxxxxx
Fixes: 2f5c3c77fc9b ("wifi: mt76: switch to page_pool allocator")
Signed-off-by: Felix Fietkau <nbd@xxxxxxxx>
Acked-by: Lorenzo Bianconi <lorenzo@xxxxxxxxxx>
Signed-off-by: Kalle Valo <kvalo@xxxxxxxxxx>
Link: https://lore.kernel.org/r/20231208075004.69843-1-nbd@xxxxxxxx
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
 drivers/net/wireless/mediatek/mt76/dma.c |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -776,7 +776,7 @@ mt76_dma_rx_reset(struct mt76_dev *dev,
 
 static void
 mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data,
-		  int len, bool more, u32 info)
+		  int len, bool more, u32 info, bool allow_direct)
 {
 	struct sk_buff *skb = q->rx_head;
 	struct skb_shared_info *shinfo = skb_shinfo(skb);
@@ -788,7 +788,7 @@ mt76_add_fragment(struct mt76_dev *dev,
 
 		skb_add_rx_frag(skb, nr_frags, page, offset, len, q->buf_size);
 	} else {
-		mt76_put_page_pool_buf(data, true);
+		mt76_put_page_pool_buf(data, allow_direct);
 	}
 
 	if (more)
@@ -808,6 +808,7 @@ mt76_dma_rx_process(struct mt76_dev *dev
 	struct sk_buff *skb;
 	unsigned char *data;
 	bool check_ddone = false;
+	bool allow_direct = !mt76_queue_is_wed_rx(q);
 	bool more;
 
 	if (IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED) &&
@@ -848,7 +849,8 @@ mt76_dma_rx_process(struct mt76_dev *dev
 		}
 
 		if (q->rx_head) {
-			mt76_add_fragment(dev, q, data, len, more, info);
+			mt76_add_fragment(dev, q, data, len, more, info,
+					  allow_direct);
 			continue;
 		}
 
@@ -877,7 +879,7 @@ mt76_dma_rx_process(struct mt76_dev *dev
 		continue;
 
 free_frag:
-		mt76_put_page_pool_buf(data, true);
+		mt76_put_page_pool_buf(data, allow_direct);
 	}
 
 	mt76_dma_rx_fill(dev, q, true);






[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux