Browse Source

qcacld-3.0: Fix session can't be closed issue

There is race condition for a small window. The scenario
as below.

1 SAP is starting, and dfs cac begins but without finished.
2 SSR happens, wlan begins to call hdd_reset_all_adapters.
  In hdd_reset_all_adapters, sap_ctx->sessionId is reset to invalid.
3 In hdd_hostapd_sap_event_cb, adapter sessionId is set to
  sap_ctx->sessionId, after this step, adapter sessionId is changed
  from valid sessionId to 0xff.
  In hdd_reset_all_adapters->hdd_vdev_destroy, vdev is released
  but session can't be clean up as invalid sessionId. adapter->event_flags
  can't be clear which cause hdd_vdev_destroy can be called multi times.

Change as below.
1 cancel cac timer at the beginning of hdd_reset_all_adapters and
  before wlansap_set_invalid_session.
2 before send eSAP_START_BSS_EVENT, check if sap_ctx->sessionId
  is valid.

Change-Id: Ifaad62cd008f7769b059f36530455d4e734522e4
CRs-Fixed: 2293072
Jingxiang Ge 6 years ago
parent
commit
ec11359f6d
2 changed files with 9 additions and 4 deletions
  1. 2 3
      core/hdd/src/wlan_hdd_main.c
  2. 7 1
      core/sap/src/sap_fsm.c

+ 2 - 3
core/hdd/src/wlan_hdd_main.c

@@ -5494,15 +5494,14 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
 			hdd_clear_fils_connection_info(adapter);
 
 		if (adapter->device_mode == QDF_SAP_MODE) {
+			wlansap_cleanup_cac_timer(
+				WLAN_HDD_GET_SAP_CTX_PTR(adapter));
 			/*
 			 * If adapter is SAP, set session ID to invalid
 			 * since SAP session will be cleanup during SSR.
 			 */
 			wlansap_set_invalid_session(
 				WLAN_HDD_GET_SAP_CTX_PTR(adapter));
-
-			wlansap_cleanup_cac_timer(
-				WLAN_HDD_GET_SAP_CTX_PTR(adapter));
 		}
 
 		/* Delete connection peers if any to avoid peer object leaks */

+ 7 - 1
core/sap/src/sap_fsm.c

@@ -1427,6 +1427,13 @@ QDF_STATUS sap_signal_hdd_event(struct sap_context *sap_ctx,
 		sap_ap_event.sapHddEventCode = eSAP_START_BSS_EVENT;
 		bss_complete = &sap_ap_event.sapevt.sapStartBssCompleteEvent;
 
+		bss_complete->sessionId = sap_ctx->sessionId;
+		if (bss_complete->sessionId == CSR_SESSION_ID_INVALID) {
+			QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+				  FL("Invalid sessionId"));
+			return QDF_STATUS_E_INVAL;
+		}
+
 		bss_complete->status = (eSapStatus) context;
 		bss_complete->staId = sap_ctx->sap_sta_id;
 
@@ -1436,7 +1443,6 @@ QDF_STATUS sap_signal_hdd_event(struct sap_context *sap_ctx,
 
 		bss_complete->operatingChannel = (uint8_t) sap_ctx->channel;
 		bss_complete->ch_width = sap_ctx->ch_params.ch_width;
-		bss_complete->sessionId = sap_ctx->sessionId;
 		break;
 	case eSAP_DFS_CAC_START:
 	case eSAP_DFS_CAC_INTERRUPTED: