Since mt7925_mac_sta_add publishes wcid, add publish check in mt76_sta_add to avoid reinitializing the wcid->poll_list for mt7925. Found dev->sta_poll_list corruption when using mt7925 and 7.0-rc4. According to the corruption information, prev->next was changed to itself. wlan0: disconnect from AP 90:fb:5d:94:8b:e3 for new auth to 90:fb:5d:94:8b:e2 wlan0: authenticate with 90:fb:5d:94:8b:e2 (local address=84:9e:56:9c:7e:6b) wlan0: send auth to 90:fb:5d:94:8b:e2 (try 1/3) slab kmalloc-8k start ffff8c80958a6000 pointer offset 4160 size 8192 list_add corruption. prev->next should be next (ffff8c808a7488f8), but was ffff8c80958a7040. (prev=ffff8c80958a7040). mt76_wcid_add_poll+0x95/0xd0 [mt76] mt7925_mac_add_txs.part.0+0xa5/0xe0 [mt7925_common] mt7925_rx_check+0xa7/0xc0 [mt7925_common] mt76_dma_rx_poll+0x50d/0x790 [mt76] mt792x_poll_rx+0x52/0xe0 [mt792x_lib] Signed-off-by: Jiajia Liu --- Reproduced and tested using the script below over ssh. Roam between two bssids with the same SSID on a router. #!/bin/bash set -ex while :; do num=$(sudo iw wlan0 scan | grep Polaris | wc -l) if [ $num -eq 2 ]; then break fi done for i in $(seq 1 500); do echo "index $i" wpa_cli -i wlan0 roam 90:fb:5d:94:8b:e3 sleep 5 wpa_cli -i wlan0 roam 90:fb:5d:94:8b:e2 sleep 5 done --- drivers/net/wireless/mediatek/mt76/mac80211.c | 11 ++++++++--- drivers/net/wireless/mediatek/mt76/mt76.h | 1 + drivers/net/wireless/mediatek/mt76/mt7925/main.c | 3 +++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 4ae5e4715a9c..83f4f941b890 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -1595,11 +1595,16 @@ mt76_sta_add(struct mt76_phy *phy, struct ieee80211_vif *vif, mtxq->wcid = wcid->idx; } - ewma_signal_init(&wcid->rssi); - rcu_assign_pointer(dev->wcid[wcid->idx], wcid); + if (!test_bit(MT_WCID_FLAG_DRV_PUBLISH, &wcid->flags)) { + ewma_signal_init(&wcid->rssi); + rcu_assign_pointer(dev->wcid[wcid->idx], wcid); + mt76_wcid_init(wcid, phy->band_idx); + } else { + wcid->phy_idx = phy->band_idx; + } + phy->num_sta++; - mt76_wcid_init(wcid, phy->band_idx); out: mutex_unlock(&dev->mutex); diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 527bef97e122..8bfce686bff7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -361,6 +361,7 @@ enum mt76_wcid_flags { MT_WCID_FLAG_PS, MT_WCID_FLAG_4ADDR, MT_WCID_FLAG_HDR_TRANS, + MT_WCID_FLAG_DRV_PUBLISH, }; #define MT76_N_WCIDS 1088 diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c index 73d3722739d0..35b5c718475c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c @@ -1102,6 +1102,9 @@ int mt7925_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, &msta->deflink); } + if (!err) + set_bit(MT_WCID_FLAG_DRV_PUBLISH, &msta->deflink.wcid.flags); + return err; } EXPORT_SYMBOL_GPL(mt7925_mac_sta_add); -- 2.53.0