qcacld-3.0: Fix race condition when disconnecting

When an attempt of connection failed and followed by a disconnection
initiated from user space, randomly it would take more than 10 seconds
to complete the disconnection due to disconnect_comp_var is not
completed in some race condition and it has to wait till timeout.

To fix this race condition, in hdd_association_completion_handler, also
need to complete disconnect_comp_var for the case when hddDisconInProgress
is true and roam_status is eCSR_ROAM_ASSOCIATION_FAILURE or
eCSR_ROAM_CANCELLED, it will also cover the following scenario besides
the one mentioned above:

Connection is in progress. But the connect command is in pending queue
and is removed from pending queue as part of csr_roam_disconnect.

Change-Id: Ib6a30057469d60efcc905d97b5234ea5a0e097a8
CRs-Fixed: 2547320
This commit is contained in:
Min Liu
2019-10-17 11:38:18 +08:00
committed by nshrivas
parent bcd5634dae
commit 602c1b19a6
2 changed files with 15 additions and 5 deletions

View File

@@ -3661,7 +3661,19 @@ hdd_association_completion_handler(struct hdd_adapter *adapter,
* waiting on disconnect_comp_var so unblock anyone waiting for
* disconnect to complete.
*/
if ((roam_result == eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE) &&
/*
* Also add eCSR_ROAM_ASSOCIATION_FAILURE and
* eCSR_ROAM_CANCELLED here to handle the following scenarios:
*
* 1. Connection is in progress, but completes with failure
* before we check the CSR state.
* 2. Connection is in progress. But the connect command is in
* pending queue and is removed from pending queue as part
* of csr_roam_disconnect.
*/
if ((roam_result == eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE ||
roam_status == eCSR_ROAM_ASSOCIATION_FAILURE ||
roam_status == eCSR_ROAM_CANCELLED) &&
hddDisconInProgress)
complete(&adapter->disconnect_comp_var);
}

View File

@@ -20057,12 +20057,11 @@ int wlan_hdd_try_disconnect(struct hdd_adapter *adapter)
(eConnectionState_IbssConnected == sta_ctx->conn_info.conn_state)) {
eConnectionState prev_conn_state;
INIT_COMPLETION(adapter->disconnect_comp_var);
prev_conn_state = sta_ctx->conn_info.conn_state;
hdd_conn_set_connection_state(adapter,
eConnectionState_Disconnecting);
/* Issue disconnect to CSR */
INIT_COMPLETION(adapter->disconnect_comp_var);
status = sme_roam_disconnect(mac_handle,
adapter->vdev_id,
eCSR_DISCONNECT_REASON_UNSPECIFIED);
@@ -20517,6 +20516,7 @@ int wlan_hdd_disconnect(struct hdd_adapter *adapter, u16 reason)
}
}
INIT_COMPLETION(adapter->disconnect_comp_var);
prev_conn_state = sta_ctx->conn_info.conn_state;
/*stop tx queues */
hdd_info("Disabling queues");
@@ -20525,8 +20525,6 @@ int wlan_hdd_disconnect(struct hdd_adapter *adapter, u16 reason)
hdd_debug("Set HDD conn_state to eConnectionState_Disconnecting");
hdd_conn_set_connection_state(adapter, eConnectionState_Disconnecting);
INIT_COMPLETION(adapter->disconnect_comp_var);
/* issue disconnect */
status = sme_roam_disconnect(mac_handle,