Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -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;
}

+1 −1
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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;