]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
iwlwifi: mvm: do more useful queue sync accounting
authorJohannes Berg <johannes.berg@intel.com>
Wed, 9 Dec 2020 21:16:31 +0000 (23:16 +0200)
committerLuca Coelho <luciano.coelho@intel.com>
Wed, 9 Dec 2020 22:14:18 +0000 (00:14 +0200)
We're currently doing accounting on the queue sync with an
atomic variable that counts down the number of remaining
notifications that we still need.

As we've been hitting issues in this area, modify this to
track a bitmap of queues, not just the number of queues,
and print out the remaining bitmap in the warning.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20201209231352.0a3fa177cd6b.I7c69ff999419368266279ec27dd618eb450908b3@changeid
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/ops.c
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c

index 2ca57ca200af8f72b1bc5ea05479abbf4b3c74c2..1f0176bb83893d611b272f346f850302b8343e7f 100644 (file)
@@ -5100,8 +5100,7 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
 
        if (notif->sync) {
                notif->cookie = mvm->queue_sync_cookie;
-               atomic_set(&mvm->queue_sync_counter,
-                          mvm->trans->num_rx_queues);
+               mvm->queue_sync_state = (1 << mvm->trans->num_rx_queues) - 1;
        }
 
        ret = iwl_mvm_notify_rx_queue(mvm, qmask, notif, size, !notif->sync);
@@ -5113,14 +5112,16 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
        if (notif->sync) {
                lockdep_assert_held(&mvm->mutex);
                ret = wait_event_timeout(mvm->rx_sync_waitq,
-                                        atomic_read(&mvm->queue_sync_counter) == 0 ||
+                                        READ_ONCE(mvm->queue_sync_state) == 0 ||
                                         iwl_mvm_is_radio_killed(mvm),
                                         HZ);
-               WARN_ON_ONCE(!ret && !iwl_mvm_is_radio_killed(mvm));
+               WARN_ONCE(!ret && !iwl_mvm_is_radio_killed(mvm),
+                         "queue sync: failed to sync, state is 0x%lx\n",
+                         mvm->queue_sync_state);
        }
 
 out:
-       atomic_set(&mvm->queue_sync_counter, 0);
+       mvm->queue_sync_state = 0;
        if (notif->sync)
                mvm->queue_sync_cookie++;
 }
index de43ffff0a5dfd260253648595a774869e3f48f3..afa04952107e16bfe3018836aca06fa454b68d66 100644 (file)
@@ -842,7 +842,7 @@ struct iwl_mvm {
        unsigned long status;
 
        u32 queue_sync_cookie;
-       atomic_t queue_sync_counter;
+       unsigned long queue_sync_state;
        /*
         * for beacon filtering -
         * currently only one interface can be supported
index e54c48af191346a5d835ae97d2a9d922f564f355..2a497fb77e3a4769d8f12ab0b21a887ec41842e3 100644 (file)
@@ -703,7 +703,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
 
        init_waitqueue_head(&mvm->rx_sync_waitq);
 
-       atomic_set(&mvm->queue_sync_counter, 0);
+       mvm->queue_sync_state = 0;
 
        SET_IEEE80211_DEV(mvm->hw, mvm->trans->dev);
 
index ef5bd58ef74284d41186de17bb6466ddf00cc5fc..d4465164457d45e0a397228e057f08fdaefd4da2 100644 (file)
@@ -827,9 +827,13 @@ void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct napi_struct *napi,
                WARN_ONCE(1, "Invalid identifier %d", internal_notif->type);
        }
 
-       if (internal_notif->sync &&
-           !atomic_dec_return(&mvm->queue_sync_counter))
-               wake_up(&mvm->rx_sync_waitq);
+       if (internal_notif->sync) {
+               WARN_ONCE(!test_and_clear_bit(queue, &mvm->queue_sync_state),
+                         "queue sync: queue %d responded a second time!\n",
+                         queue);
+               if (READ_ONCE(mvm->queue_sync_state) == 0)
+                       wake_up(&mvm->rx_sync_waitq);
+       }
 }
 
 static void iwl_mvm_oldsn_workaround(struct iwl_mvm *mvm,