Skip to content

Commit a2113cc

Browse files
ngoldstelucacoelho
authored andcommitted
iwlwifi: mvm: fix race in sync rx queue notification
Consider the following flow: 1. Driver starts to sync the rx queues due to a delba. mvm->queue_sync_cookie=1. This rx-queues-sync is synchronous, so it doesn't increment the cookie until all rx queues handle the notification from FW. 2. During this time, driver starts to sync rx queues due to nssn sync required. The cookie's value is still 1, but it doesn't matter since this rx-queue-sync is non-synchronous so in the notification handler the cookie is ignored. What _does_ matter is that this flow increments the cookie to 2 immediately. Remember though that the FW won't start servicing this command until it's done with the previous one. 3. FW is still handling the first command, so it sends a notification with internal_notif->sync=1, and internal_notif->cookie=0, which triggers a WARN_ONCE. The solution for this race is to only use the mvm->queue_sync_cookie in case of a synchronous sync-rx-queues. This way in step 2 the cookie's value won't change so we avoid the WARN. The commit in the "fixes" field is the first commit to introduce non-synchronous sending of this command to FW. Fixes: 3c514bf ("iwlwifi: mvm: add a loose synchronization of the NSSN across Rx queues") Signed-off-by: Naftali Goldstein <[email protected]> Signed-off-by: Luca Coelho <[email protected]>
1 parent a458472 commit a2113cc

File tree

1 file changed

+5
-4
lines changed

1 file changed

+5
-4
lines changed

drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4881,11 +4881,11 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
48814881
if (!iwl_mvm_has_new_rx_api(mvm))
48824882
return;
48834883

4884-
notif->cookie = mvm->queue_sync_cookie;
4885-
4886-
if (notif->sync)
4884+
if (notif->sync) {
4885+
notif->cookie = mvm->queue_sync_cookie;
48874886
atomic_set(&mvm->queue_sync_counter,
48884887
mvm->trans->num_rx_queues);
4888+
}
48894889

48904890
ret = iwl_mvm_notify_rx_queue(mvm, qmask, (u8 *)notif,
48914891
size, !notif->sync);
@@ -4905,7 +4905,8 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
49054905

49064906
out:
49074907
atomic_set(&mvm->queue_sync_counter, 0);
4908-
mvm->queue_sync_cookie++;
4908+
if (notif->sync)
4909+
mvm->queue_sync_cookie++;
49094910
}
49104911

49114912
static void iwl_mvm_sync_rx_queues(struct ieee80211_hw *hw)

0 commit comments

Comments
 (0)