| From cd607f2cbbbec90682b2f6d6b85e1525d0f43b19 Mon Sep 17 00:00:00 2001 |
| From: Felix Fietkau <nbd@nbd.name> |
| Date: Fri, 8 Dec 2023 08:50:04 +0100 |
| Subject: wifi: mt76: fix crash with WED rx support enabled |
| |
| From: Felix Fietkau <nbd@nbd.name> |
| |
| 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@vger.kernel.org |
| Fixes: 2f5c3c77fc9b ("wifi: mt76: switch to page_pool allocator") |
| Signed-off-by: Felix Fietkau <nbd@nbd.name> |
| Acked-by: Lorenzo Bianconi <lorenzo@kernel.org> |
| Signed-off-by: Kalle Valo <kvalo@kernel.org> |
| Link: https://lore.kernel.org/r/20231208075004.69843-1-nbd@nbd.name |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| 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); |