iwlwifi: mvm: Fix wrongfully flushing frames in the roc/off channel queue
authorMatti Gottlieb <matti.gottlieb@intel.com>
Mon, 30 Mar 2015 13:50:07 +0000 (16:50 +0300)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Thu, 2 Apr 2015 06:26:47 +0000 (09:26 +0300)
Sending multiple action frames off channel, one after the other can create
a race that will result in a timeout:

1. Start sending action frame off channel.
2. Once the frame is sent or the time event is over, the flow will
eventually call ieee80211_start_next_roc to start the next roc frame &
iwl_mvm_roc_finished schedules to schedule a work to flush the queue.
3. Start sending new roc frame and write it to the queue before the
flush work has started.
4. The work is called and it flushes the new packet that was placed on the
on the queue so the packet is lost.

This causes the frame to be removed & not sent, that causes a timeout in
userspace.

Flush the work queue that flushes the roc/off channel queue before starting
to send a new frame off channel, in order to avoid a race between the new
frame that is transmitted off channel & the flushing of the queue.

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

index 0dd999ceed36a6681a8fae42ebedad0aed96ad00..0bd3373315ec1e78298dfe50be59bd76623462b7 100644 (file)
@@ -3080,6 +3080,8 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,
        IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value,
                           duration, type);
 
+       flush_work(&mvm->roc_done_wk);
+
        mutex_lock(&mvm->mutex);
 
        switch (vif->type) {