summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/mediatek/mt76
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2023-12-08 10:50:04 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-01-01 15:42:38 +0300
commite4006c5a5c0d0ea4fbb31f0cc8b9ef5580a21217 (patch)
tree3211c23deacef96f74700e7fbd1feec6f90a095f /drivers/net/wireless/mediatek/mt76
parentaf60d63b86a40b0ebc3e502d7b739d4122918264 (diff)
downloadlinux-e4006c5a5c0d0ea4fbb31f0cc8b9ef5580a21217.tar.xz
wifi: mt76: fix crash with WED rx support enabled
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>
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76')
-rw-r--r--drivers/net/wireless/mediatek/mt76/dma.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index 6ca7b494c2c2..cd0486597064 100644
--- 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, enum mt76_rxq_id qid)
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, struct mt76_queue *q, void *data,
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 mt76_queue *q, int budget)
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, struct mt76_queue *q, int budget)
}
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, struct mt76_queue *q, int budget)
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);