From 510f60ceecd6b0b78ff90d8020f37d6c4fbb7670 Mon Sep 17 00:00:00 2001 From: "Padma, Santhosh Kumar" Date: Thu, 7 Dec 2017 16:58:41 +0530 Subject: [PATCH] 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 --- core/sme/inc/csr_internal.h | 1 + core/sme/src/csr/csr_api_roam.c | 23 ++++++++++++++--------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h index e2c37e3187c3..97b1549410c3 100644 --- a/core/sme/inc/csr_internal.h +++ b/core/sme/inc/csr_internal.h @@ -1043,6 +1043,7 @@ struct csr_roamstruct { uint16_t reassocRespLen; /* length of reassociation response */ qdf_mc_timer_t packetdump_timer; qdf_list_t rssi_disallow_bssid; + spinlock_t roam_state_lock; }; #define GET_NEXT_ROAM_ID(pRoamStruct) (((pRoamStruct)->nextRoamId + 1 == 0) ? \ diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 22c137ea4855..3a590555ce01 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -1036,7 +1036,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; @@ -1168,6 +1169,7 @@ static QDF_STATUS csr_roam_open(tpAniSirGlobal pMac) sme_err("cannot allocate memory for packetdump timer"); break; } + spin_lock_init(&pMac->roam.roam_state_lock); } while (0); return status; } @@ -1386,8 +1388,9 @@ void csr_roam_substate_change(tpAniSirGlobal pMac, curSubState[sessionId])); 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); } enum csr_roam_state csr_roam_state_change(tpAniSirGlobal pMac, @@ -12416,8 +12419,14 @@ void csr_roam_wait_for_key_time_out_handler(void *pv) neighborRoamState), 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)) { /* @@ -12431,12 +12440,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); @@ -12449,6 +12452,8 @@ void csr_roam_wait_for_key_time_out_handler(void *pv) } else { sme_err("session not found"); } + } else { + spin_unlock(&pMac->roam.roam_state_lock); } }