qcacld-3.0: Make sure sap stop_bss_event cannot be forcedly reset by PLD_FW_DOWN

In some stress test, like doing random on/off sap and random SSR, sometimes we
can hit below test situation:
1. trigger SSR first by calling hdd_crash_inject, then immediately off SAP, the
two actions almost happen at the same time.
2. the action of off SAP calls __wlan_hdd_del_virtual_intf to delete SAP interface
and is waiting for qdf_stop_bss_event completion event.
3. at the moment, sys error interrupt happened, CNSS layer would send PLD_FW_DOWN
event to host driver first. Due to PLD_FW_DOWN event call qdf_complete_wait_events()
to forcedly reset all completion wait event, this action may cause
__wlan_hdd_del_virtual_intf to do vdev destroy before vdev resp mlme state machine
is processed. Once vdev destroy is executed, it will set vdev obj_state to
WLAN_OBJ_STATE_LOGICALLY_DELETED, then vdev resp will not have chances to be flushed,
and then cause peer reference count leakage.

Fix solution: use qdf_wait_single_event instead of qdf_wait_for_event_completion to
avoid stop_bss_event forcedly reset before stop_bss_event is done or timeout.

Change-Id: I45b662fd17ec56bb8fc4453627bdcb41dedf79e0
CRs-Fixed: 2987511
This commit is contained in:
Qun Zhang
2021-08-31 14:53:33 +08:00
committed by Madan Koyyalamudi
parent 2372e5c367
commit c4f20eca44
4 changed files with 8 additions and 11 deletions

View File

@@ -6122,7 +6122,7 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
status = wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(adapter)); status = wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(adapter));
if (QDF_IS_STATUS_SUCCESS(status)) { if (QDF_IS_STATUS_SUCCESS(status)) {
qdf_status = qdf_status =
qdf_wait_for_event_completion(&hostapd_state-> qdf_wait_single_event(&hostapd_state->
qdf_stop_bss_event, qdf_stop_bss_event,
SME_CMD_STOP_BSS_TIMEOUT); SME_CMD_STOP_BSS_TIMEOUT);

View File

@@ -2138,8 +2138,7 @@ __iw_softap_stopbss(struct net_device *dev,
status = wlansap_stop_bss( status = wlansap_stop_bss(
WLAN_HDD_GET_SAP_CTX_PTR(adapter)); WLAN_HDD_GET_SAP_CTX_PTR(adapter));
if (QDF_IS_STATUS_SUCCESS(status)) { if (QDF_IS_STATUS_SUCCESS(status)) {
status = status = qdf_wait_single_event(&hostapd_state->
qdf_wait_for_event_completion(&hostapd_state->
qdf_stop_bss_event, qdf_stop_bss_event,
SME_CMD_STOP_BSS_TIMEOUT); SME_CMD_STOP_BSS_TIMEOUT);

View File

@@ -7570,7 +7570,7 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter); WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
qdf_event_reset(&hostapd_state-> qdf_event_reset(&hostapd_state->
qdf_stop_bss_event); qdf_stop_bss_event);
status = qdf_wait_for_event_completion( status = qdf_wait_single_event(
&hostapd_state->qdf_stop_bss_event, &hostapd_state->qdf_stop_bss_event,
SME_CMD_STOP_BSS_TIMEOUT); SME_CMD_STOP_BSS_TIMEOUT);
if (QDF_IS_STATUS_ERROR(status)) { if (QDF_IS_STATUS_ERROR(status)) {
@@ -15790,7 +15790,7 @@ void wlan_hdd_stop_sap(struct hdd_adapter *ap_adapter)
qdf_event_reset(&hostapd_state->qdf_stop_bss_event); qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx-> if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx->
sap_context)) { sap_context)) {
qdf_status = qdf_wait_for_event_completion(&hostapd_state-> qdf_status = qdf_wait_single_event(&hostapd_state->
qdf_stop_bss_event, qdf_stop_bss_event,
SME_CMD_STOP_BSS_TIMEOUT); SME_CMD_STOP_BSS_TIMEOUT);
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
@@ -18200,9 +18200,8 @@ void hdd_restart_sap(struct hdd_adapter *ap_adapter)
hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter); hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
qdf_event_reset(&hostapd_state->qdf_stop_bss_event); qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
if (QDF_STATUS_SUCCESS == wlansap_stop_bss(sap_ctx)) { if (QDF_STATUS_SUCCESS == wlansap_stop_bss(sap_ctx)) {
qdf_status = qdf_status = qdf_wait_single_event(
qdf_wait_for_event_completion(&hostapd_state-> &hostapd_state->qdf_stop_bss_event,
qdf_stop_bss_event,
SME_CMD_STOP_BSS_TIMEOUT); SME_CMD_STOP_BSS_TIMEOUT);
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {

View File

@@ -1603,9 +1603,8 @@ static void hdd_restart_sap_with_new_phymode(struct hdd_context *hdd_ctx,
hdd_err("SAP Stop Bss fail"); hdd_err("SAP Stop Bss fail");
return; return;
} }
status = qdf_wait_for_event_completion( status = qdf_wait_single_event(&hostapd_state->qdf_stop_bss_event,
&hostapd_state->qdf_stop_bss_event, SME_CMD_STOP_BSS_TIMEOUT);
SME_CMD_STOP_BSS_TIMEOUT);
if (!QDF_IS_STATUS_SUCCESS(status)) { if (!QDF_IS_STATUS_SUCCESS(status)) {
hdd_err("SAP Stop timeout"); hdd_err("SAP Stop timeout");
return; return;