Commit a9adbcb3 authored by Avinash Patil's avatar Avinash Patil Committed by Kalle Valo

mwifiex: lock main process till reinitialization of vif is over

A crash was detected while changing virtual interface type is in
progress. This was tracked to race condition in accessing bss_priority
table while change is in progress. This patch ensures that main_process
and rx_process works are locked while we change virtual interface.
Signed-off-by: default avatarCathy Luo <cluo@marvell.com>
Signed-off-by: default avatarAvinash Patil <patila@marvell.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent a3fa71c4
...@@ -717,6 +717,9 @@ mwifiex_cfg80211_init_p2p_go(struct mwifiex_private *priv) ...@@ -717,6 +717,9 @@ mwifiex_cfg80211_init_p2p_go(struct mwifiex_private *priv)
static int mwifiex_deinit_priv_params(struct mwifiex_private *priv) static int mwifiex_deinit_priv_params(struct mwifiex_private *priv)
{ {
struct mwifiex_adapter *adapter = priv->adapter;
unsigned long flags;
priv->mgmt_frame_mask = 0; priv->mgmt_frame_mask = 0;
if (mwifiex_send_cmd(priv, HostCmd_CMD_MGMT_FRAME_REG, if (mwifiex_send_cmd(priv, HostCmd_CMD_MGMT_FRAME_REG,
HostCmd_ACT_GEN_SET, 0, HostCmd_ACT_GEN_SET, 0,
...@@ -727,6 +730,25 @@ static int mwifiex_deinit_priv_params(struct mwifiex_private *priv) ...@@ -727,6 +730,25 @@ static int mwifiex_deinit_priv_params(struct mwifiex_private *priv)
} }
mwifiex_deauthenticate(priv, NULL); mwifiex_deauthenticate(priv, NULL);
spin_lock_irqsave(&adapter->main_proc_lock, flags);
adapter->main_locked = true;
if (adapter->mwifiex_processing) {
spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
flush_workqueue(adapter->workqueue);
} else {
spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
}
spin_lock_irqsave(&adapter->rx_proc_lock, flags);
adapter->rx_locked = true;
if (adapter->rx_processing) {
spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
flush_workqueue(adapter->rx_workqueue);
} else {
spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
}
mwifiex_free_priv(priv); mwifiex_free_priv(priv);
priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED; priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
...@@ -740,6 +762,9 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv, ...@@ -740,6 +762,9 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv,
struct net_device *dev, struct net_device *dev,
enum nl80211_iftype type) enum nl80211_iftype type)
{ {
struct mwifiex_adapter *adapter = priv->adapter;
unsigned long flags;
mwifiex_init_priv(priv); mwifiex_init_priv(priv);
priv->bss_mode = type; priv->bss_mode = type;
...@@ -770,6 +795,14 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv, ...@@ -770,6 +795,14 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
spin_lock_irqsave(&adapter->main_proc_lock, flags);
adapter->main_locked = false;
spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
spin_lock_irqsave(&adapter->rx_proc_lock, flags);
adapter->rx_locked = false;
spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
return 0; return 0;
} }
......
...@@ -189,7 +189,7 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter) ...@@ -189,7 +189,7 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
spin_lock_irqsave(&adapter->main_proc_lock, flags); spin_lock_irqsave(&adapter->main_proc_lock, flags);
/* Check if already processing */ /* Check if already processing */
if (adapter->mwifiex_processing) { if (adapter->mwifiex_processing || adapter->main_locked) {
adapter->more_task_flag = true; adapter->more_task_flag = true;
spin_unlock_irqrestore(&adapter->main_proc_lock, flags); spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
goto exit_main_proc; goto exit_main_proc;
......
...@@ -772,6 +772,7 @@ struct mwifiex_adapter { ...@@ -772,6 +772,7 @@ struct mwifiex_adapter {
bool rx_processing; bool rx_processing;
bool delay_main_work; bool delay_main_work;
bool rx_locked; bool rx_locked;
bool main_locked;
struct mwifiex_bss_prio_tbl bss_prio_tbl[MWIFIEX_MAX_BSS_NUM]; struct mwifiex_bss_prio_tbl bss_prio_tbl[MWIFIEX_MAX_BSS_NUM];
/* spin lock for init/shutdown */ /* spin lock for init/shutdown */
spinlock_t mwifiex_lock; spinlock_t mwifiex_lock;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment