소스 검색

qcacld-3.0: Fix invoke roam race condition

There is race condition is in-between "nud failure
sme_roam_invoke_nud_fail" and "bmiss disconnecting process".
Thread 1: Nud failure will check the roam state -
    "MLME_IS_ROAM_INITIALIZED"
Thread 2: bmiss disconnecting will set roam offload state to
    "deinit" and set the "roam_invoke_in_progress" false.
Thread 1: trigger roaming cmd to fw and set
    "roam_invoke_in_progress" = true
Then drv couldn’t get "roam_invoke_in_progress" cleared and
get all the scan blocked.

The thread 2 (scheduler thread) has acquired the sme lock
during handling BMISS.
Fix by add sme lock in sme_roam_invoke_nud_fail to protect
the roam state check and set roam_invoke_in_progress = true.

Change-Id: Ibb73c19e06e248b63795c9bfc6db0d99bc702b44
CRs-Fixed: 2829101
Liangwei Dong 4 년 전
부모
커밋
e00ffbd00c
1개의 변경된 파일9개의 추가작업 그리고 0개의 파일을 삭제
  1. 9 0
      core/sme/src/common/sme_api.c

+ 9 - 0
core/sme/src/common/sme_api.c

@@ -13778,12 +13778,16 @@ QDF_STATUS sme_roam_invoke_nud_fail(mac_handle_t mac_handle, uint8_t vdev_id)
 		sme_err("session %d not found", vdev_id);
 		return QDF_STATUS_E_FAILURE;
 	}
+	status = sme_acquire_global_lock(&mac_ctx->sme);
+	if (!QDF_IS_STATUS_SUCCESS(status))
+		return status;
 
 	control_bitmap = mlme_get_operations_bitmap(mac_ctx->psoc, vdev_id);
 	if (control_bitmap ||
 	    !MLME_IS_ROAM_INITIALIZED(mac_ctx->psoc, vdev_id)) {
 		sme_debug("ROAM: RSO Disabled internaly: vdev[%d] bitmap[0x%x]",
 			  vdev_id, control_bitmap);
+		sme_release_global_lock(&mac_ctx->sme);
 		return QDF_STATUS_E_FAILURE;
 	}
 
@@ -13792,6 +13796,7 @@ QDF_STATUS sme_roam_invoke_nud_fail(mac_handle_t mac_handle, uint8_t vdev_id)
 
 	if (!vdev) {
 		sme_err("vdev is NULL, aborting roam invoke");
+		sme_release_global_lock(&mac_ctx->sme);
 		return QDF_STATUS_E_NULL_VALUE;
 	}
 
@@ -13800,6 +13805,7 @@ QDF_STATUS sme_roam_invoke_nud_fail(mac_handle_t mac_handle, uint8_t vdev_id)
 	if (!vdev_roam_params) {
 		sme_err("Invalid vdev roam params, aborting roam invoke");
 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
+		sme_release_global_lock(&mac_ctx->sme);
 		return QDF_STATUS_E_NULL_VALUE;
 	}
 
@@ -13807,12 +13813,14 @@ QDF_STATUS sme_roam_invoke_nud_fail(mac_handle_t mac_handle, uint8_t vdev_id)
 		sme_debug("Roaming already initiated by %d source",
 			  vdev_roam_params->source);
 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
+		sme_release_global_lock(&mac_ctx->sme);
 		return QDF_STATUS_E_BUSY;
 	}
 
 	roam_invoke_params = qdf_mem_malloc(sizeof(*roam_invoke_params));
 	if (!roam_invoke_params) {
 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
+		sme_release_global_lock(&mac_ctx->sme);
 		return QDF_STATUS_E_NOMEM;
 	}
 	roam_invoke_params->vdev_id = vdev_id;
@@ -13834,6 +13842,7 @@ QDF_STATUS sme_roam_invoke_nud_fail(mac_handle_t mac_handle, uint8_t vdev_id)
 	}
 
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
+	sme_release_global_lock(&mac_ctx->sme);
 
 	return status;
 }