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:

committed by
Madan Koyyalamudi

szülő
2372e5c367
commit
c4f20eca44
@@ -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));
|
||||
if (QDF_IS_STATUS_SUCCESS(status)) {
|
||||
qdf_status =
|
||||
qdf_wait_for_event_completion(&hostapd_state->
|
||||
qdf_wait_single_event(&hostapd_state->
|
||||
qdf_stop_bss_event,
|
||||
SME_CMD_STOP_BSS_TIMEOUT);
|
||||
|
||||
|
@@ -2138,8 +2138,7 @@ __iw_softap_stopbss(struct net_device *dev,
|
||||
status = wlansap_stop_bss(
|
||||
WLAN_HDD_GET_SAP_CTX_PTR(adapter));
|
||||
if (QDF_IS_STATUS_SUCCESS(status)) {
|
||||
status =
|
||||
qdf_wait_for_event_completion(&hostapd_state->
|
||||
status = qdf_wait_single_event(&hostapd_state->
|
||||
qdf_stop_bss_event,
|
||||
SME_CMD_STOP_BSS_TIMEOUT);
|
||||
|
||||
|
@@ -7570,7 +7570,7 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
|
||||
WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
|
||||
qdf_event_reset(&hostapd_state->
|
||||
qdf_stop_bss_event);
|
||||
status = qdf_wait_for_event_completion(
|
||||
status = qdf_wait_single_event(
|
||||
&hostapd_state->qdf_stop_bss_event,
|
||||
SME_CMD_STOP_BSS_TIMEOUT);
|
||||
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);
|
||||
if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx->
|
||||
sap_context)) {
|
||||
qdf_status = qdf_wait_for_event_completion(&hostapd_state->
|
||||
qdf_status = qdf_wait_single_event(&hostapd_state->
|
||||
qdf_stop_bss_event,
|
||||
SME_CMD_STOP_BSS_TIMEOUT);
|
||||
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);
|
||||
qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
|
||||
if (QDF_STATUS_SUCCESS == wlansap_stop_bss(sap_ctx)) {
|
||||
qdf_status =
|
||||
qdf_wait_for_event_completion(&hostapd_state->
|
||||
qdf_stop_bss_event,
|
||||
qdf_status = qdf_wait_single_event(
|
||||
&hostapd_state->qdf_stop_bss_event,
|
||||
SME_CMD_STOP_BSS_TIMEOUT);
|
||||
|
||||
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
|
||||
|
@@ -1603,9 +1603,8 @@ static void hdd_restart_sap_with_new_phymode(struct hdd_context *hdd_ctx,
|
||||
hdd_err("SAP Stop Bss fail");
|
||||
return;
|
||||
}
|
||||
status = qdf_wait_for_event_completion(
|
||||
&hostapd_state->qdf_stop_bss_event,
|
||||
SME_CMD_STOP_BSS_TIMEOUT);
|
||||
status = qdf_wait_single_event(&hostapd_state->qdf_stop_bss_event,
|
||||
SME_CMD_STOP_BSS_TIMEOUT);
|
||||
if (!QDF_IS_STATUS_SUCCESS(status)) {
|
||||
hdd_err("SAP Stop timeout");
|
||||
return;
|
||||
|
Reference in New Issue
Block a user