diff options
author | Padma, Santhosh Kumar <skpadma@codeaurora.org> | 2017-12-07 16:36:34 +0530 |
---|---|---|
committer | snandini <snandini@codeaurora.org> | 2017-12-13 02:46:45 -0800 |
commit | 39f0c4ca863ad1b61820a9a288cc9babcaa927e0 (patch) | |
tree | 80c5719a59507304f03f8d5c11278f700fad2721 /core/sme/src/csr/csr_api_roam.c | |
parent | f77b5d8016d2899ea21118007cff76eb321366c5 (diff) | |
download | qcacld-39f0c4ca863ad1b61820a9a288cc9babcaa927e0.tar.gz |
qcacld-3.0: Fix active cmd timeout issue
qcacld-2.0 to qcacld-3.0 propagation
There can be a possible race in updation of roam substate
between csrRoamWaitForKeyTimeOutHandler and upper layer
disconnect in csrRoamIssueDeauth. Race can be as follows.
Driver roam substate is eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY by
the time csrRoamWaitForKeyTimeOutHandler is invoked. This
can allow check CSR_IS_WAIT_FOR_KEY to pass. If MC thread
gets preempted and if driver processes upper layer disconnect,
then driver changes roam substate to eCSR_ROAM_SUBSTATE_DEAUTH_REQ
in csrRoamIssueDeauth. When MC thread resumes processing of
csrRoamWaitForKeyTimeOutHandler, then driver changes roam
substate to eCSR_ROAM_SUBSTATE_NONE. This can result in
unhandling of eWNI_SME_DEAUTH_RSP as roam substate is not in
eCSR_ROAM_SUBSTATE_DEAUTH_REQ and can result in active command
timeout. Hence, update roam substate atomically in same context
if CSR_IS_WAIT_FOR_KEY passes in csrRoamWaitForKeyTimeOutHandler.
Change-Id: I05cfc8de54fe4196df941c2fd48db8bedc7df779
CRs-Fixed: 2155141
Diffstat (limited to 'core/sme/src/csr/csr_api_roam.c')
-rw-r--r-- | core/sme/src/csr/csr_api_roam.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 700a6198cc..8005672622 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -1097,7 +1097,8 @@ QDF_STATUS csr_stop(tpAniSirGlobal pMac, tHalStopType stopType) for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) { csr_roam_state_change(pMac, eCSR_ROAMING_STATE_STOP, sessionId); - pMac->roam.curSubState[sessionId] = eCSR_ROAM_SUBSTATE_NONE; + csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE, + sessionId); } return QDF_STATUS_SUCCESS; @@ -1244,6 +1245,7 @@ static QDF_STATUS csr_roam_open(tpAniSirGlobal pMac) sme_err("cannot allocate memory for summary Statistics timer"); return QDF_STATUS_E_FAILURE; } + spin_lock_init(&pMac->roam.roam_state_lock); } while (0); return status; } @@ -1560,7 +1562,9 @@ void csr_roam_substate_change(tpAniSirGlobal pMac, eCsrRoamSubState NewSubstate, if (pMac->roam.curSubState[sessionId] == NewSubstate) return; + spin_lock(&pMac->roam.roam_state_lock); pMac->roam.curSubState[sessionId] = NewSubstate; + spin_unlock(&pMac->roam.roam_state_lock); } eCsrRoamState csr_roam_state_change(tpAniSirGlobal pMac, @@ -12498,7 +12502,14 @@ void csr_roam_wait_for_key_time_out_handler(void *pv) mac_trace_getcsr_roam_sub_state(pMac->roam. curSubState[pInfo->sessionId])); + spin_lock(&pMac->roam.roam_state_lock); if (CSR_IS_WAIT_FOR_KEY(pMac, pInfo->sessionId)) { + /* Change the substate so command queue is unblocked. */ + if (CSR_ROAM_SESSION_MAX > pInfo->sessionId) + pMac->roam.curSubState[pInfo->sessionId] = + eCSR_ROAM_SUBSTATE_NONE; + spin_unlock(&pMac->roam.roam_state_lock); + if (csr_neighbor_roam_is_handoff_in_progress(pMac, pInfo->sessionId)) { /* @@ -12512,12 +12523,6 @@ void csr_roam_wait_for_key_time_out_handler(void *pv) } sme_debug("SME pre-auth state timeout"); - /* Change the substate so command queue is unblocked. */ - if (CSR_ROAM_SESSION_MAX > pInfo->sessionId) { - csr_roam_substate_change(pMac, eCSR_ROAM_SUBSTATE_NONE, - pInfo->sessionId); - } - if (csr_is_conn_state_connected_infra(pMac, pInfo->sessionId)) { csr_roam_link_up(pMac, pSession->connectedProfile.bssid); @@ -12530,8 +12535,9 @@ void csr_roam_wait_for_key_time_out_handler(void *pv) } } else sme_err("%s: session not found", __func__); + } else { + spin_unlock(&pMac->roam.roam_state_lock); } - } #ifdef WLAN_FEATURE_ROAM_OFFLOAD |