TDLS: Ensure acquisition of tdls and sme lock are independent.
Acquisition of tdls lock after sme lock would result in a
deadlock if the corresponding threads contend for each other.
Hence make the tdls lock acquisition independent of sme lock.
Change-Id: Idbf82e0a4f1ec87389b3da8207b26bd308873d97
CRs-fixed: 584668
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index e3a0273..3c19d80 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -2903,10 +2903,10 @@
pHddCtx->change_iface = type;
memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
hdd_set_station_ops( pAdapter->dev );
- status = hdd_init_station_mode( pAdapter );
#ifdef FEATURE_WLAN_TDLS
mutex_unlock(&pHddCtx->tdls_lock);
#endif
+ status = hdd_init_station_mode( pAdapter );
if( VOS_STATUS_SUCCESS != status )
return -EOPNOTSUPP;
/* In case of JB, for P2P-GO, only change interface will be called,
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 21151e6..63a20e6 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -5765,11 +5765,11 @@
NL80211_IFTYPE_STATION;
pAdapter->device_mode = session_type;
-
- status = hdd_init_station_mode( pAdapter );
#ifdef FEATURE_WLAN_TDLS
mutex_unlock(&pHddCtx->tdls_lock);
#endif
+
+ status = hdd_init_station_mode( pAdapter );
if( VOS_STATUS_SUCCESS != status )
goto err_free_netdev;
diff --git a/CORE/HDD/src/wlan_hdd_tdls.c b/CORE/HDD/src/wlan_hdd_tdls.c
index 1b565f7..1a466ab 100644
--- a/CORE/HDD/src/wlan_hdd_tdls.c
+++ b/CORE/HDD/src/wlan_hdd_tdls.c
@@ -580,6 +580,16 @@
int i;
v_U8_t staIdx;
+ if (NULL == pHddCtx)
+ return -1;
+
+ if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: unable to lock list", __func__);
+ return -1;
+ }
+
if ((FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport) ||
(FALSE == sme_IsFeatureSupportedByFW(TDLS)))
{
@@ -588,6 +598,7 @@
hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS not enabled (%d) or FW doesn't support (%d)!",
__func__, pHddCtx->cfg_ini->fEnableTDLSSupport,
sme_IsFeatureSupportedByFW(TDLS));
+ mutex_unlock(&pHddCtx->tdls_lock);
return 0;
}
/* TDLS is supported only in STA / P2P Client modes,
@@ -602,6 +613,7 @@
*/
if (0 == WLAN_HDD_IS_TDLS_SUPPORTED_ADAPTER(pAdapter))
{
+ mutex_unlock(&pHddCtx->tdls_lock);
return 0;
}
/* Check for the valid pHddTdlsCtx. If valid do not further
@@ -617,6 +629,7 @@
if (NULL == pHddTdlsCtx) {
hddLog(VOS_TRACE_LEVEL_ERROR, "%s malloc failed!", __func__);
pAdapter->sessionCtx.station.pHddTdlsCtx = NULL;
+ mutex_unlock(&pHddCtx->tdls_lock);
return -1;
}
/* initialize TDLS pAdater context */
@@ -691,6 +704,7 @@
}
INIT_WORK(&pHddTdlsCtx->implicit_setup, wlan_hdd_tdls_pre_setup);
INIT_DELAYED_WORK(&pHddCtx->tdls_scan_ctxt.tdls_scan_work, wlan_hdd_tdls_schedule_scan);
+ mutex_unlock(&pHddCtx->tdls_lock);
return 0;
}