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: Cathy Luo <cluo@marvell.com> Signed-off-by: Avinash Patil <patila@marvell.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
parent
a3fa71c40f
commit
a9adbcb335
drivers/net/wireless/mwifiex
|
@ -717,6 +717,9 @@ mwifiex_cfg80211_init_p2p_go(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;
|
||||
if (mwifiex_send_cmd(priv, HostCmd_CMD_MGMT_FRAME_REG,
|
||||
HostCmd_ACT_GEN_SET, 0,
|
||||
|
@ -727,6 +730,25 @@ static int mwifiex_deinit_priv_params(struct mwifiex_private *priv)
|
|||
}
|
||||
|
||||
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);
|
||||
priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
|
||||
priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
|
||||
|
@ -740,6 +762,9 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv,
|
|||
struct net_device *dev,
|
||||
enum nl80211_iftype type)
|
||||
{
|
||||
struct mwifiex_adapter *adapter = priv->adapter;
|
||||
unsigned long flags;
|
||||
|
||||
mwifiex_init_priv(priv);
|
||||
|
||||
priv->bss_mode = type;
|
||||
|
@ -770,6 +795,14 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv,
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -189,7 +189,7 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
|
|||
spin_lock_irqsave(&adapter->main_proc_lock, flags);
|
||||
|
||||
/* Check if already processing */
|
||||
if (adapter->mwifiex_processing) {
|
||||
if (adapter->mwifiex_processing || adapter->main_locked) {
|
||||
adapter->more_task_flag = true;
|
||||
spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
|
||||
goto exit_main_proc;
|
||||
|
|
|
@ -772,6 +772,7 @@ struct mwifiex_adapter {
|
|||
bool rx_processing;
|
||||
bool delay_main_work;
|
||||
bool rx_locked;
|
||||
bool main_locked;
|
||||
struct mwifiex_bss_prio_tbl bss_prio_tbl[MWIFIEX_MAX_BSS_NUM];
|
||||
/* spin lock for init/shutdown */
|
||||
spinlock_t mwifiex_lock;
|
||||
|
|
Loading…
Reference in New Issue