mwifiex: factor out mwifiex_cancel_pending_scan_cmd
authorAndreas Fenkart <afenkart@gmail.com>
Thu, 10 Mar 2016 08:44:10 +0000 (09:44 +0100)
committerKalle Valo <kvalo@codeaurora.org>
Fri, 15 Apr 2016 18:34:50 +0000 (21:34 +0300)
Releasing the scan_pending lock in mwifiex_check_next_scan_command
introduces a short window where pending scan commands can be removed
or added before removing them all in mwifiex_cancel_pending_scan_cmd.
I think this is safe, since the worst thing to happen is that a
pending scan cmd is removed by the command handler. Adding new scan
commands is not possible while one is pending, see scan_processing flag.
Since all commands are removed from the queue anyway, we don't care if
some commands are removed by a different code path earlier, the final
state remains the same.
I assume, that the critical section needed for the check has been
extended over clearing the pending scan queue out of convenience. The
lock was already held and releasing it and grab it again was just
more work. It doesn't seem to be necessary because of concurrency.

Signed-off-by: Andreas Fenkart <afenkart@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/marvell/mwifiex/cmdevt.c
drivers/net/wireless/marvell/mwifiex/main.h
drivers/net/wireless/marvell/mwifiex/scan.c
drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c

index 6f04706464837800c622e43927e6747e6c5f51fb..f5af525485f6489061b6f1a9d825e8587f77c311 100644 (file)
@@ -991,6 +991,23 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
                adapter->if_ops.card_reset(adapter);
 }
 
+void
+mwifiex_cancel_pending_scan_cmd(struct mwifiex_adapter *adapter)
+{
+       struct cmd_ctrl_node *cmd_node = NULL, *tmp_node;
+       unsigned long flags;
+
+       /* Cancel all pending scan command */
+       spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+       list_for_each_entry_safe(cmd_node, tmp_node,
+                                &adapter->scan_pending_q, list) {
+               list_del(&cmd_node->list);
+               cmd_node->wait_q_enabled = false;
+               mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+       }
+       spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+}
+
 /*
  * This function cancels all the pending commands.
  *
@@ -1029,16 +1046,7 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
        spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
        spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
 
-       /* Cancel all pending scan command */
-       spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
-       list_for_each_entry_safe(cmd_node, tmp_node,
-                                &adapter->scan_pending_q, list) {
-               list_del(&cmd_node->list);
-
-               cmd_node->wait_q_enabled = false;
-               mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
-       }
-       spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+       mwifiex_cancel_pending_scan_cmd(adapter);
 
        if (adapter->scan_processing) {
                spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
@@ -1070,9 +1078,8 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
 void
 mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
 {
-       struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL;
+       struct cmd_ctrl_node *cmd_node = NULL;
        unsigned long cmd_flags;
-       unsigned long scan_pending_q_flags;
        struct mwifiex_private *priv;
        int i;
 
@@ -1094,17 +1101,7 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
                mwifiex_recycle_cmd_node(adapter, cmd_node);
        }
 
-       /* Cancel all pending scan command */
-       spin_lock_irqsave(&adapter->scan_pending_q_lock,
-                         scan_pending_q_flags);
-       list_for_each_entry_safe(cmd_node, tmp_node,
-                                &adapter->scan_pending_q, list) {
-               list_del(&cmd_node->list);
-               cmd_node->wait_q_enabled = false;
-               mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
-       }
-       spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
-                              scan_pending_q_flags);
+       mwifiex_cancel_pending_scan_cmd(adapter);
 
        if (adapter->scan_processing) {
                spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
index a159fbef20cd7999736a57a7cf7a27b9e98f21b6..6306654d27998412016acbc10c9778f6f1412699 100644 (file)
@@ -1042,6 +1042,7 @@ int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter);
 int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter);
 void mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter);
 void mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter);
+void mwifiex_cancel_pending_scan_cmd(struct mwifiex_adapter *adapter);
 
 void mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter,
                                  struct cmd_ctrl_node *cmd_node);
index 753d92a731af01fd5f0b0b2fcec7ccae2dd9c754..36cc9cca95fc980f51dc621f2ae6c5318c222fbd 100644 (file)
@@ -619,8 +619,6 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
        int ret = 0;
        struct mwifiex_chan_scan_param_set *tmp_chan_list;
        struct mwifiex_chan_scan_param_set *start_chan;
-       struct cmd_ctrl_node *cmd_node, *tmp_node;
-       unsigned long flags;
        u32 tlv_idx, rates_size, cmd_no;
        u32 total_scan_time;
        u32 done_early;
@@ -777,16 +775,7 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
                            sizeof(struct mwifiex_ie_types_header) + rates_size;
 
                if (ret) {
-                       spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
-                       list_for_each_entry_safe(cmd_node, tmp_node,
-                                                &adapter->scan_pending_q,
-                                                list) {
-                               list_del(&cmd_node->list);
-                               cmd_node->wait_q_enabled = false;
-                               mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
-                       }
-                       spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
-                                              flags);
+                       mwifiex_cancel_pending_scan_cmd(adapter);
                        break;
                }
        }
@@ -1949,12 +1938,13 @@ mwifiex_active_scan_req_for_passive_chan(struct mwifiex_private *priv)
 static void mwifiex_check_next_scan_command(struct mwifiex_private *priv)
 {
        struct mwifiex_adapter *adapter = priv->adapter;
-       struct cmd_ctrl_node *cmd_node, *tmp_node;
+       struct cmd_ctrl_node *cmd_node;
        unsigned long flags;
 
        spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
        if (list_empty(&adapter->scan_pending_q)) {
                spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+
                spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
                adapter->scan_processing = false;
                spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
@@ -1976,13 +1966,10 @@ static void mwifiex_check_next_scan_command(struct mwifiex_private *priv)
                }
        } else if ((priv->scan_aborting && !priv->scan_request) ||
                   priv->scan_block) {
-               list_for_each_entry_safe(cmd_node, tmp_node,
-                                        &adapter->scan_pending_q, list) {
-                       list_del(&cmd_node->list);
-                       mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
-               }
                spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
 
+               mwifiex_cancel_pending_scan_cmd(adapter);
+
                spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
                adapter->scan_processing = false;
                spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
index 434b9776db45af8ef8d36b0f06c550bb995e6431..d18c7979d723bfa972ed6ebb5ea091e6841b1596 100644 (file)
@@ -44,7 +44,6 @@ static void
 mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
                              struct host_cmd_ds_command *resp)
 {
-       struct cmd_ctrl_node *cmd_node = NULL, *tmp_node;
        struct mwifiex_adapter *adapter = priv->adapter;
        struct host_cmd_ds_802_11_ps_mode_enh *pm;
        unsigned long flags;
@@ -71,17 +70,7 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
                break;
        case HostCmd_CMD_802_11_SCAN:
        case HostCmd_CMD_802_11_SCAN_EXT:
-               /* Cancel all pending scan command */
-               spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
-               list_for_each_entry_safe(cmd_node, tmp_node,
-                                        &adapter->scan_pending_q, list) {
-                       list_del(&cmd_node->list);
-                       spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
-                                              flags);
-                       mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
-                       spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
-               }
-               spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+               mwifiex_cancel_pending_scan_cmd(adapter);
 
                spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
                adapter->scan_processing = false;