From: Charlie-cy Wu dev->token_count is always updated with token_lock held (mt76_token_consume(), mt76_token_release() and the tx token cleanup paths), but mt76_connac_skip_fw_pmctrl() reads it without the lock, which races with the tx and tx-free paths. Read token_count under token_lock. All callers hold pm->mutex and run in process context, and token_lock is never nested with pm->wake.lock, so spin_lock_bh() is safe here. Signed-off-by: Charlie-cy Wu --- drivers/net/wireless/mediatek/mt76/mt76_connac.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac.h index 9af25eb48531..4e373dadf640 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac.h +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac.h @@ -415,7 +415,10 @@ mt76_connac_skip_fw_pmctrl(struct mt76_phy *phy, struct mt76_connac_pm *pm) struct mt76_dev *dev = phy->dev; bool ret; - if (dev->token_count) + spin_lock_bh(&dev->token_lock); + ret = !!dev->token_count; + spin_unlock_bh(&dev->token_lock); + if (ret) return true; spin_lock_bh(&pm->wake.lock); -- 2.18.0