mirror of
https://github.com/outbackdingo/mt76.git
synced 2026-10-24 21:36:52 +00:00
mt76: move de-amsdu buffer per-phy
mt7615d users report the following crash running both phy concurrently: [ 147.273909] CPU 1 Unable to handle kernel paging request at virtual address 00000000, epc == 8e4f288c, ra == 8e58a968 [ 147.284570] Oops[#1]: [ 147.286854] CPU: 1 PID: 3724 Comm: kworker/u9:3 Not tainted 5.4.105 #0 [ 147.293403] Workqueue: napi_workq napi_workfn [ 147.297742] $ 0 : 00000000 00000001 8e595ec0 00000000 [ 147.302950] $ 4 : 8e595ec0 00000000 8e5ca600 00000000 [ 147.308161] $ 8 : 00000000 000004c1 80808080 fefefeff [ 147.313370] $12 : 00000000 00000000 80704f1c 00000040 [ 147.323781] $20 : 00000050 00000044 00000011 01ce9502 [ 147.334195] $28 : 8e004000 8e005d18 8ddf2020 8e58a968 [ 147.342266] Lo : 00000000 [ 147.350397] ra : 8e58a968 mt7615_queue_rx_skb+0x94c/0xd0c [mt7615_common] [ 147.361580] Cause : 4080000c (ExcCode 03) [ 147.368434] PrId : 0001992f (MIPS 1004Kc) [ 147.456965] Process kworker/u9:3 (pid: 3724, threadinfo=9ece68d6, task=b16d155f, tls=00000000) [ 147.473857] 0001ce95 00004188 00000000 00000080 00004c10 00000002 8074a2b8 80043dcc [ 147.490505] 00000000 8e4f0110 8069ddf4 806ab148 8dfc0000 00001000 00000000 00000050 [ 147.507150] ... [ 147.512033] [<8e4f288c>] mt76_rx+0x124/0x320 [mt76] [ 147.526633] [ 147.528512] ---[ end trace 3d137e75bb109149 ]--- The issue has been introduce enabling hw rx de-amsdu since the hw can interleave amsdu frames from both phy. Fix the issue moving the de-amsdu buffer per-phy. Signed-off-by: Lorenzo Bianconi <[email protected]> Acked-by: Ryder Lee <[email protected]>
This commit is contained in:
committed by
Felix Fietkau
parent
ca22cc221a
commit
0b6c9a043f
+15
-14
@@ -508,40 +508,41 @@ void mt76_free_device(struct mt76_dev *dev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76_free_device);
|
||||
|
||||
static void mt76_rx_release_burst(struct mt76_dev *dev, enum mt76_rxq_id q,
|
||||
static void mt76_rx_release_burst(struct mt76_phy *phy, enum mt76_rxq_id q,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
|
||||
struct sk_buff *nskb = dev->rx_amsdu[q].head;
|
||||
struct sk_buff *nskb = phy->rx_amsdu[q].head;
|
||||
struct mt76_dev *dev = phy->dev;
|
||||
|
||||
/* first amsdu subframe */
|
||||
if (status->first_amsdu) {
|
||||
dev->rx_amsdu[q].tail = &skb_shinfo(skb)->frag_list;
|
||||
dev->rx_amsdu[q].seqno = status->seqno;
|
||||
dev->rx_amsdu[q].head = skb;
|
||||
if (status->amsdu && !phy->rx_amsdu[q].head) {
|
||||
phy->rx_amsdu[q].tail = &skb_shinfo(skb)->frag_list;
|
||||
phy->rx_amsdu[q].seqno = status->seqno;
|
||||
phy->rx_amsdu[q].head = skb;
|
||||
goto enqueue;
|
||||
}
|
||||
|
||||
/* ampdu or out-of-order amsdu subframes */
|
||||
if (!status->amsdu || status->seqno != dev->rx_amsdu[q].seqno) {
|
||||
if (!status->amsdu || status->seqno != phy->rx_amsdu[q].seqno) {
|
||||
/* release pending frames */
|
||||
if (dev->rx_amsdu[q].head)
|
||||
if (phy->rx_amsdu[q].head)
|
||||
__skb_queue_tail(&dev->rx_skb[q],
|
||||
dev->rx_amsdu[q].head);
|
||||
phy->rx_amsdu[q].head);
|
||||
nskb = skb;
|
||||
goto reset_burst;
|
||||
}
|
||||
|
||||
/* trailing amsdu subframes */
|
||||
*dev->rx_amsdu[q].tail = skb;
|
||||
*phy->rx_amsdu[q].tail = skb;
|
||||
if (!status->last_amsdu) {
|
||||
dev->rx_amsdu[q].tail = &skb->next;
|
||||
phy->rx_amsdu[q].tail = &skb->next;
|
||||
return;
|
||||
}
|
||||
|
||||
reset_burst:
|
||||
dev->rx_amsdu[q].head = NULL;
|
||||
dev->rx_amsdu[q].tail = NULL;
|
||||
phy->rx_amsdu[q].head = NULL;
|
||||
phy->rx_amsdu[q].tail = NULL;
|
||||
enqueue:
|
||||
if (nskb)
|
||||
__skb_queue_tail(&dev->rx_skb[q], nskb);
|
||||
@@ -565,7 +566,7 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb)
|
||||
}
|
||||
#endif
|
||||
|
||||
mt76_rx_release_burst(dev, q, skb);
|
||||
mt76_rx_release_burst(phy, q, skb);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76_rx);
|
||||
|
||||
|
||||
@@ -609,6 +609,12 @@ struct mt76_phy {
|
||||
|
||||
struct delayed_work mac_work;
|
||||
u8 mac_work_count;
|
||||
|
||||
struct {
|
||||
struct sk_buff *head;
|
||||
struct sk_buff **tail;
|
||||
u16 seqno;
|
||||
} rx_amsdu[__MT_RXQ_MAX];
|
||||
};
|
||||
|
||||
struct mt76_dev {
|
||||
@@ -641,11 +647,6 @@ struct mt76_dev {
|
||||
spinlock_t rx_lock;
|
||||
struct napi_struct napi[__MT_RXQ_MAX];
|
||||
struct sk_buff_head rx_skb[__MT_RXQ_MAX];
|
||||
struct {
|
||||
struct sk_buff *head;
|
||||
struct sk_buff **tail;
|
||||
u16 seqno;
|
||||
} rx_amsdu[__MT_RXQ_MAX];
|
||||
|
||||
struct list_head txwi_cache;
|
||||
struct mt76_queue *q_mcu[__MT_MCUQ_MAX];
|
||||
|
||||
Reference in New Issue
Block a user