TDLS: Move tdls_lock to HDD Context
Concurrent access to the data structures betweeen the TDLS
and other modules require an access to mutex lock.Hence move the
tdls_lock to the HDD context which is currently accessed only
by the tdls module.
Change-Id: Ia38d8117d9e8cd2f60bbec08e618af398e897afd
CRs-fixed: 553670
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index cde55bf..68d55aa 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -1108,6 +1108,8 @@
/* TDLS peer connected count */
tANI_U16 connected_peer_count;
tdls_scan_context_t tdls_scan_ctxt;
+ /* Lock to avoid race condition during TDLS operations*/
+ struct mutex tdls_lock;
#endif
hdd_traffic_monitor_t traffic_monitor;
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 6cee911..71bfa8f 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -7161,6 +7161,9 @@
}
mutex_init(&pHddCtx->sap_lock);
+#ifdef FEATURE_WLAN_TDLS
+ mutex_init(&pHddCtx->tdls_lock);
+#endif
pHddCtx->isLoadUnloadInProgress = FALSE;
diff --git a/CORE/HDD/src/wlan_hdd_tdls.c b/CORE/HDD/src/wlan_hdd_tdls.c
index 51bb3ca..87e5723 100644
--- a/CORE/HDD/src/wlan_hdd_tdls.c
+++ b/CORE/HDD/src/wlan_hdd_tdls.c
@@ -39,7 +39,6 @@
#include "wlan_hdd_cfg80211.h"
-static struct mutex tdls_lock;
static tANI_S32 wlan_hdd_get_tdls_discovery_peer_cnt(tdlsCtx_t *pHddTdlsCtx);
static tANI_S32 wlan_hdd_tdls_peer_reset_discovery_processed(tdlsCtx_t *pHddTdlsCtx);
static void wlan_hdd_tdls_timers_destroy(tdlsCtx_t *pHddTdlsCtx);
@@ -85,29 +84,28 @@
v_U32_t discoveryExpiry)
{
hdd_station_ctx_t *pHddStaCtx;
+ hdd_context_t *pHddCtx;
+
+ if ((NULL == pHddTdlsCtx))
+ return;
+
+ if ((NULL == pHddTdlsCtx->pAdapter) )
+ return;
+
+ pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
+
+ if (NULL == pHddCtx)
+ return;
if ( mutexLock )
{
- if (mutex_lock_interruptible(&tdls_lock))
+ if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
"%s: unable to lock list: %d", __func__, __LINE__);
return;
}
}
- if (NULL == pHddTdlsCtx)
- {
- if ( mutexLock )
- mutex_unlock(&tdls_lock);
- return;
- }
-
- if (NULL == pHddTdlsCtx->pAdapter)
- {
- if ( mutexLock )
- mutex_unlock(&tdls_lock);
- return;
- }
pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pHddTdlsCtx->pAdapter);
#ifdef FEATURE_WLAN_TDLS_INTERNAL
@@ -119,7 +117,7 @@
pHddTdlsCtx->ap_rssi);
if ( mutexLock )
- mutex_unlock(&tdls_lock);
+ mutex_unlock(&pHddCtx->tdls_lock);
return;
}
@@ -132,30 +130,31 @@
struct list_head *pos;
hddTdlsPeer_t *curr_peer;
hdd_station_ctx_t *pHddStaCtx;
+ hdd_context_t *pHddCtx;
tdlsCtx_t *pHddTdlsCtx = (tdlsCtx_t *)userData;
int discover_req_sent = 0;
v_U32_t discover_expiry = TDLS_SUB_DISCOVERY_PERIOD;
tANI_BOOLEAN doMutexLock = eANI_BOOLEAN_TRUE;
- if (mutex_lock_interruptible(&tdls_lock))
+ if ((NULL == pHddTdlsCtx))
+ return;
+
+ if (NULL == pHddTdlsCtx->pAdapter)
+ return;
+
+ pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
+
+ if (NULL == pHddCtx)
+ return;
+
+
+ if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
"%s: unable to lock list : %d", __func__, __LINE__);
return;
}
- if (NULL == pHddTdlsCtx)
- {
- mutex_unlock(&tdls_lock);
- return;
- }
-
- if (NULL == pHddTdlsCtx->pAdapter)
- {
- mutex_unlock(&tdls_lock);
- return;
- }
-
pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pHddTdlsCtx->pAdapter);
VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ", __func__);
@@ -228,7 +227,7 @@
wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx);
- mutex_unlock(&tdls_lock);
+ mutex_unlock(&pHddCtx->tdls_lock);
/* Commenting out the following function as it was introducing
* a race condition when pHddTdlsCtx is deleted. Also , this
@@ -244,7 +243,7 @@
wlan_hdd_tdls_start_peer_discover_timer(pHddTdlsCtx, doMutexLock, discover_expiry);
if ( !doMutexLock )
- mutex_unlock(&tdls_lock);
+ mutex_unlock(&pHddCtx->tdls_lock);
return;
}
#endif
@@ -255,26 +254,26 @@
struct list_head *head;
struct list_head *pos;
hddTdlsPeer_t *curr_peer;
- tdlsCtx_t *pHddTdlsCtx;
+ tdlsCtx_t *pHddTdlsCtx = (tdlsCtx_t *)userData;
+ hdd_context_t *pHddCtx;
- if (mutex_lock_interruptible(&tdls_lock))
+ if ((NULL == pHddTdlsCtx))
+ return;
+
+ if (NULL == pHddTdlsCtx->pAdapter)
+ return;
+
+ pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
+
+ if (NULL == pHddCtx)
+ return;
+
+ if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
"%s: unable to lock list", __func__);
return;
}
- pHddTdlsCtx = (tdlsCtx_t *)userData;
- if (NULL == pHddTdlsCtx)
- {
- mutex_unlock(&tdls_lock);
- return;
- }
-
- if (NULL == pHddTdlsCtx->pAdapter)
- {
- mutex_unlock(&tdls_lock);
- return;
- }
for (i = 0; i < 256; i++) {
head = &pHddTdlsCtx->peer_list[i];
@@ -401,13 +400,15 @@
wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
&pHddTdlsCtx->peerUpdateTimer,
pHddTdlsCtx->threshold_config.tx_period_t);
- mutex_unlock(&tdls_lock);
+ mutex_unlock(&pHddCtx->tdls_lock);
}
static v_VOID_t wlan_hdd_tdls_idle_cb( v_PVOID_t userData )
{
#ifdef CONFIG_TDLS_IMPLICIT
hddTdlsPeer_t *curr_peer = (hddTdlsPeer_t *)userData;
+ tdlsCtx_t *pHddTdlsCtx;
+ hdd_context_t *pHddCtx;
if (NULL == curr_peer)
{
@@ -415,6 +416,16 @@
"%s: Invalid tdls idle timer expired", __func__);
return;
}
+ pHddTdlsCtx = curr_peer->pHddTdlsCtx;
+
+ if ((NULL == pHddTdlsCtx) || (NULL == pHddTdlsCtx->pAdapter) )
+ return;
+
+ pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
+
+ if (NULL == pHddCtx)
+ return;
+
VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
"%s: Tx/Rx Idle " MAC_ADDRESS_STR " tx_pkt: %d, rx_pkt: %d, idle_packet_n: %d\n",
@@ -423,7 +434,7 @@
curr_peer->rx_pkt,
curr_peer->pHddTdlsCtx->threshold_config.idle_packet_n);
- if (mutex_lock_interruptible(&tdls_lock))
+ if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
"%s: unable to lock list", __func__);
@@ -451,7 +462,7 @@
curr_peer,
eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
}
- mutex_unlock(&tdls_lock);
+ mutex_unlock(&pHddCtx->tdls_lock);
#endif
}
@@ -462,20 +473,24 @@
hddTdlsPeer_t *tmp;
struct list_head *pos, *q;
tdlsCtx_t *pHddTdlsCtx;
+ hdd_context_t *pHddCtx;
- if (mutex_lock_interruptible(&tdls_lock))
+ pHddTdlsCtx = (tdlsCtx_t *)userData;
+
+ if ((NULL == pHddTdlsCtx) || (NULL == pHddTdlsCtx->pAdapter) )
+ return;
+
+ pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
+
+ if (NULL == pHddCtx)
+ return;
+
+ if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
"%s: unable to lock list", __func__);
return ;
}
- pHddTdlsCtx = (tdlsCtx_t *)userData;
-
- if ( NULL == pHddTdlsCtx )
- {
- mutex_unlock(&tdls_lock);
- return ;
- }
for (i = 0; i < 256; i++) {
head = &pHddTdlsCtx->peer_list[i];
@@ -494,7 +509,7 @@
pHddTdlsCtx->discovery_sent_cnt = 0;
wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
- mutex_unlock(&tdls_lock);
+ mutex_unlock(&pHddCtx->tdls_lock);
wlan_hdd_tdls_check_bmps(pHddTdlsCtx->pAdapter);
@@ -545,8 +560,6 @@
int i;
v_U8_t staIdx;
- mutex_init(&tdls_lock);
-
if ((FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport) ||
(FALSE == sme_IsFeatureSupportedByFW(TDLS)))
{
@@ -665,24 +678,23 @@
tdlsCtx_t *pHddTdlsCtx;
hdd_context_t *pHddCtx;
- if (mutex_lock_interruptible(&tdls_lock))
+ pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
+ if (NULL == pHddCtx)
+ {
+ return;
+ }
+
+ if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
"%s: unable to lock list", __func__);
return;
}
- pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
- if (NULL == pHddCtx)
- {
- mutex_unlock(&tdls_lock);
- return;
- }
-
pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
if (NULL == pHddTdlsCtx)
{
- mutex_unlock(&tdls_lock);
+ mutex_unlock(&pHddCtx->tdls_lock);
hddLog(VOS_TRACE_LEVEL_WARN, "%s TDLS not enabled, exiting!", __func__);
return;
}
@@ -696,7 +708,7 @@
vos_mem_free(pHddTdlsCtx);
pHddTdlsCtx = NULL;
- mutex_unlock(&tdls_lock);
+ mutex_unlock(&pHddCtx->tdls_lock);
}
/* stop all monitoring timers per Adapter */
@@ -793,6 +805,9 @@
hddTdlsPeer_t *peer;
u8 key;
tdlsCtx_t *pHddTdlsCtx;
+ hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+
+ if ((NULL == pHddCtx)) return NULL;
/* if already there, just update */
peer = wlan_hdd_tdls_find_peer(pAdapter, mac);
@@ -808,7 +823,7 @@
return NULL;
}
- if (mutex_lock_interruptible(&tdls_lock))
+ if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
"%s: unable to lock list", __func__);
@@ -820,7 +835,7 @@
if (NULL == pHddTdlsCtx)
{
vos_mem_free(peer);
- mutex_unlock(&tdls_lock);
+ mutex_unlock(&pHddCtx->tdls_lock);
return NULL;
}
@@ -842,7 +857,7 @@
peer);
list_add_tail(&peer->node, head);
- mutex_unlock(&tdls_lock);
+ mutex_unlock(&pHddCtx->tdls_lock);
return peer;
}
@@ -1205,9 +1220,11 @@
struct list_head *head;
hddTdlsPeer_t *curr_peer;
tdlsCtx_t *pHddTdlsCtx;
+ hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+ if ((NULL == pHddCtx)) return NULL;
- if (mutex_lock_interruptible(&tdls_lock))
+ if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
"%s: unable to lock list", __func__);
@@ -1216,7 +1233,7 @@
pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
if (NULL == pHddTdlsCtx)
{
- mutex_unlock(&tdls_lock);
+ mutex_unlock(&pHddCtx->tdls_lock);
return NULL;
}
@@ -1229,12 +1246,12 @@
if (!memcmp(mac, curr_peer->peerMac, 6)) {
VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
"findTdlsPeer: found staId %d", curr_peer->staId);
- mutex_unlock(&tdls_lock);
+ mutex_unlock(&pHddCtx->tdls_lock);
return curr_peer;
}
}
- mutex_unlock(&tdls_lock);
+ mutex_unlock(&pHddCtx->tdls_lock);
return NULL;
}
@@ -1369,6 +1386,12 @@
struct list_head *pos;
hddTdlsPeer_t *curr_peer;
tdlsCtx_t *pHddTdlsCtx;
+ hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+
+ if ((NULL == pHddCtx)) {
+ len = snprintf(buf, buflen, "NULL HddCtx\n");
+ return len;
+ }
init_len = buflen;
@@ -1381,7 +1404,7 @@
buf += len;
buflen -= len;
- if (mutex_lock_interruptible(&tdls_lock))
+ if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
"%s: unable to lock list", __func__);
@@ -1389,7 +1412,7 @@
}
pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
if (NULL == pHddTdlsCtx) {
- mutex_unlock(&tdls_lock);
+ mutex_unlock(&pHddCtx->tdls_lock);
len = scnprintf(buf, buflen, "TDLS not enabled\n");
return len;
}
@@ -1412,28 +1435,24 @@
buflen -= len;
}
}
- mutex_unlock(&tdls_lock);
+ mutex_unlock(&pHddCtx->tdls_lock);
return init_len-buflen;
}
void wlan_hdd_tdls_connection_callback(hdd_adapter_t *pAdapter)
{
- hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
+ hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
- if (mutex_lock_interruptible(&tdls_lock))
+ if ((NULL == pHddCtx) || (NULL == pHddTdlsCtx)) return;
+
+ if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
"%s: unable to lock list", __func__);
return;
}
- if (NULL == pHddCtx || NULL == pHddTdlsCtx)
- {
- mutex_unlock(&tdls_lock);
- return;
- }
-
VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
"%s, update %d discover %d", __func__,
pHddTdlsCtx->threshold_config.tx_period_t,
@@ -1454,17 +1473,20 @@
&pHddTdlsCtx->peerUpdateTimer,
pHddTdlsCtx->threshold_config.tx_period_t);
}
- mutex_unlock(&tdls_lock);
+ mutex_unlock(&pHddCtx->tdls_lock);
}
void wlan_hdd_tdls_disconnection_callback(hdd_adapter_t *pAdapter)
{
tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
+ hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+
+ if ((NULL == pHddCtx) || (NULL == pHddTdlsCtx)) return;
VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s", __func__);
- if (mutex_lock_interruptible(&tdls_lock))
+ if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
"%s: unable to lock list", __func__);
@@ -1472,7 +1494,7 @@
}
if (NULL == pHddTdlsCtx)
{
- mutex_unlock(&tdls_lock);
+ mutex_unlock(&pHddCtx->tdls_lock);
return;
}
pHddTdlsCtx->discovery_sent_cnt = 0;
@@ -1482,7 +1504,7 @@
wlan_hdd_tdls_peer_timers_destroy(pHddTdlsCtx);
wlan_hdd_tdls_free_list(pHddTdlsCtx);
- mutex_unlock(&tdls_lock);
+ mutex_unlock(&pHddCtx->tdls_lock);
}
void wlan_hdd_tdls_mgmt_completion_callback(hdd_adapter_t *pAdapter, tANI_U32 statusCode)
@@ -1585,23 +1607,26 @@
hddTdlsPeer_t *curr_peer;
struct list_head *pos;
tdlsCtx_t *pHddTdlsCtx;
+ hdd_context_t *pHddCtx;
+
+ pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
+ if (NULL == pHddTdlsCtx)
+ return NULL;
+
+ pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
+
+ if (NULL == pHddCtx)
+ return NULL;
if (mutexLock)
{
- if (mutex_lock_interruptible(&tdls_lock))
+ if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
"%s: unable to lock list", __func__);
return NULL;
}
}
- pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
- if (NULL == pHddTdlsCtx)
- {
- if (mutexLock)
- mutex_unlock(&tdls_lock);
- return NULL;
- }
for (i = 0; i < 256; i++) {
head = &pHddTdlsCtx->peer_list[i];
@@ -1618,7 +1643,7 @@
"%s:" MAC_ADDRESS_STR " eTDLS_LINK_CONNECTING",
__func__, MAC_ADDR_ARRAY(curr_peer->peerMac));
if (mutexLock)
- mutex_unlock(&tdls_lock);
+ mutex_unlock(&pHddCtx->tdls_lock);
return curr_peer;
}
}
@@ -1626,7 +1651,7 @@
}
if (mutexLock)
- mutex_unlock(&tdls_lock);
+ mutex_unlock(&pHddCtx->tdls_lock);
return NULL;
}
@@ -1689,24 +1714,21 @@
tdlsCtx_t *pHddTdlsCtx;
VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s mode %d", __func__, (int)tdls_mode);
+ if (NULL == pHddCtx)
+ return;
- if (mutex_lock_interruptible(&tdls_lock))
+ if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
"%s: unable to lock list", __func__);
return;
}
- if (NULL == pHddCtx)
- {
- mutex_unlock(&tdls_lock);
- return;
- }
if (pHddCtx->tdls_mode == tdls_mode)
{
hddLog(TDLS_LOG_LEVEL, "%s already in mode %d", __func__, (int)tdls_mode);
- mutex_unlock(&tdls_lock);
+ mutex_unlock(&pHddCtx->tdls_lock);
return;
}
@@ -1737,7 +1759,7 @@
}
pHddCtx->tdls_mode = tdls_mode;
- mutex_unlock(&tdls_lock);
+ mutex_unlock(&pHddCtx->tdls_lock);
}
static void wlan_hdd_tdls_pre_setup(struct work_struct *work)