Re: [PATCH v2] wifi: mt76: add wcid publish check in mt76_sta_add
From: Thorsten Leemhuis
Date: Tue Jun 30 2026 - 08:04:06 EST
On 5/28/26 05:38, Jiajia Liu wrote:
> Since mt7925_mac_sta_add publishes wcid, add publish check in mt76_sta_add
> to avoid reinitializing the wcid->poll_list.
>
> Found dev->sta_poll_list corruption when using mt7925 and 7.1-rc4.
Jiajia Liu, Felox: given that the problem seems to be in 7.1, should we
ask the stable team to pick this regression fix up, as this change was
mainlined (as 20b126920a259d ("wifi: mt76: add wcid publish check in
mt76_sta_add") [v7.2-rc1]), but lacks both a Fixes and a Stable tag?
Ciao, Thorsten
> 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 <liujiajia@xxxxxxxxxx>
> ---
>
> Changes in v2:
> - use dev->wcid table instead of adding MT_WCID_FLAG_DRV_PUBLSH for
> wcid publish check suggested by Sean
> - subject and commit message update
>
> ---
> drivers/net/wireless/mediatek/mt76/mac80211.c | 15 ++++++++++++---
> 1 file 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..b78b4cd206e0 100644
> --- a/drivers/net/wireless/mediatek/mt76/mac80211.c
> +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
> @@ -1576,6 +1576,7 @@ mt76_sta_add(struct mt76_phy *phy, struct ieee80211_vif *vif,
> {
> struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
> struct mt76_dev *dev = phy->dev;
> + struct mt76_wcid *published;
> int ret;
> int i;
>
> @@ -1595,11 +1596,19 @@ 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);
> + published = rcu_dereference_protected(dev->wcid[wcid->idx],
> + lockdep_is_held(&dev->mutex));
> + if (published != wcid) {
> + WARN_ON_ONCE(published);
> + 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);
>