iwlwifi: mvm: flush queues without mutex held
authorJohannes Berg <johannes.berg@intel.com>
Fri, 10 Oct 2014 06:59:27 +0000 (08:59 +0200)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Wed, 29 Oct 2014 10:52:28 +0000 (12:52 +0200)
For WMM-AC we may have to be changing QoS parameters while the
queues are being flushed. This is not relevant in the "drop"
case, but matters when we wait for the device to finish the
transmissions.

To allow this, do the actual waiting without holding the mutex.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
drivers/net/wireless/iwlwifi/mvm/mac80211.c

index c087bf69d2904d734aa73dffe404ece8f6410528..14be10829510c2366944662a09a57f9ba35ba04e 100644 (file)
@@ -2997,18 +2997,24 @@ static void iwl_mvm_mac_flush(struct ieee80211_hw *hw,
        mvmvif = iwl_mvm_vif_from_mac80211(vif);
        mvmsta = iwl_mvm_sta_from_staid_protected(mvm, mvmvif->ap_sta_id);
 
-       if (WARN_ON_ONCE(!mvmsta))
-               goto done;
+       if (WARN_ON_ONCE(!mvmsta)) {
+               mutex_unlock(&mvm->mutex);
+               return;
+       }
 
        if (drop) {
                if (iwl_mvm_flush_tx_path(mvm, mvmsta->tfd_queue_msk, true))
                        IWL_ERR(mvm, "flush request fail\n");
+               mutex_unlock(&mvm->mutex);
        } else {
-               iwl_trans_wait_tx_queue_empty(mvm->trans,
-                                             mvmsta->tfd_queue_msk);
+               u32 tfd_queue_msk = mvmsta->tfd_queue_msk;
+               mutex_unlock(&mvm->mutex);
+
+               /* this can take a while, and we may need/want other operations
+                * to succeed while doing this, so do it without the mutex held
+                */
+               iwl_trans_wait_tx_queue_empty(mvm->trans, tfd_queue_msk);
        }
-done:
-       mutex_unlock(&mvm->mutex);
 }
 
 const struct ieee80211_ops iwl_mvm_hw_ops = {