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

parent
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));
|
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);
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
@@ -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)) {
|
||||||
|
@@ -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;
|
||||||
|
Reference in New Issue
Block a user