Browse Source

qcacld-3.0: Avoid Using sme global lock in hdd calls of Connection mgr

If the connection manager command is moved from pending to active
queue after an SME initiated active command e.g SAP peer
disconnect, it's already holding the SME lock and trying to
acquire the connection manager lock.

Now if in another thread, the connection manager process is
already in progress and tries to get the SME lock,
the driver ends up in a deadlock.

Thus remove the SME global lock from the APIs called from
HDD disconnect handlers.

Change-Id: I1c8afa55163e4113e5be5232efc15681eda69473
CRs-Fixed: 3304039
Nagalakshmi 2 years ago
parent
commit
1fd7ee3421
1 changed files with 46 additions and 80 deletions
  1. 46 80
      core/sme/src/common/sme_api.c

+ 46 - 80
core/sme/src/common/sme_api.c

@@ -9724,9 +9724,7 @@ void sme_radio_tx_mem_free(void)
 QDF_STATUS sme_ll_stats_clear_req(mac_handle_t mac_handle,
 				  tSirLLStatsClearReq *pclearStatsReq)
 {
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
-	struct mac_context *mac = MAC_CONTEXT(mac_handle);
 	struct scheduler_msg message = {0};
 	tSirLLStatsClearReq *clear_stats_req;
 
@@ -9744,29 +9742,21 @@ QDF_STATUS sme_ll_stats_clear_req(mac_handle_t mac_handle,
 
 	*clear_stats_req = *pclearStatsReq;
 
-	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&mac->sme)) {
-		/* Serialize the req through MC thread */
-		message.bodyptr = clear_stats_req;
-		message.type = WMA_LINK_LAYER_STATS_CLEAR_REQ;
-		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
-				 NO_SESSION, message.type));
-		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
-						    QDF_MODULE_ID_WMA,
-						    QDF_MODULE_ID_WMA,
-						    &message);
-		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
-			sme_err("not able to post WMA_LL_STATS_CLEAR_REQ");
-			qdf_mem_free(clear_stats_req);
-			status = QDF_STATUS_E_FAILURE;
-		}
-		sme_release_global_lock(&mac->sme);
-	} else {
-		sme_err("sme_acquire_global_lock error");
+	/* Serialize the req through MC thread */
+	message.bodyptr = clear_stats_req;
+	message.type = WMA_LINK_LAYER_STATS_CLEAR_REQ;
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+			 NO_SESSION, message.type));
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_WMA,
+					    &message);
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		sme_err("not able to post WMA_LL_STATS_CLEAR_REQ");
 		qdf_mem_free(clear_stats_req);
-		status = QDF_STATUS_E_FAILURE;
 	}
 
-	return status;
+	return qdf_status;
 }
 
 /*
@@ -9780,9 +9770,7 @@ QDF_STATUS sme_ll_stats_clear_req(mac_handle_t mac_handle,
 QDF_STATUS sme_ll_stats_set_req(mac_handle_t mac_handle, tSirLLStatsSetReq
 				*psetStatsReq)
 {
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
-	struct mac_context *mac = MAC_CONTEXT(mac_handle);
 	struct scheduler_msg message = {0};
 	tSirLLStatsSetReq *set_stats_req;
 
@@ -9796,36 +9784,28 @@ QDF_STATUS sme_ll_stats_set_req(mac_handle_t mac_handle, tSirLLStatsSetReq
 
 	*set_stats_req = *psetStatsReq;
 
-	if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&mac->sme)) {
-		/* Serialize the req through MC thread */
-		message.bodyptr = set_stats_req;
-		message.type = WMA_LINK_LAYER_STATS_SET_REQ;
-		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
-				 NO_SESSION, message.type));
-		qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
-						    QDF_MODULE_ID_WMA,
-						    QDF_MODULE_ID_WMA,
-						    &message);
-		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
-			sme_err("not able to post WMA_LL_STATS_SET_REQ");
-			qdf_mem_free(set_stats_req);
-			status = QDF_STATUS_E_FAILURE;
-		}
-		sme_release_global_lock(&mac->sme);
-	} else {
-		sme_err("sme_acquire_global_lock error");
+	/* Serialize the req through MC thread */
+	message.bodyptr = set_stats_req;
+	message.type = WMA_LINK_LAYER_STATS_SET_REQ;
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+			 NO_SESSION, message.type));
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_WMA,
+					    QDF_MODULE_ID_WMA,
+					    &message);
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		sme_err("not able to post WMA_LL_STATS_SET_REQ");
 		qdf_mem_free(set_stats_req);
-		status = QDF_STATUS_E_FAILURE;
 	}
 
-	return status;
+	return qdf_status;
 }
 
 QDF_STATUS sme_ll_stats_get_req(mac_handle_t mac_handle,
 				tSirLLStatsGetReq *get_stats_req,
 				void *context)
 {
-	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	QDF_STATUS status;
 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
 	struct scheduler_msg message = {0};
 	tSirLLStatsGetReq *ll_stats_get_req;
@@ -9837,22 +9817,16 @@ QDF_STATUS sme_ll_stats_get_req(mac_handle_t mac_handle,
 	*ll_stats_get_req = *get_stats_req;
 
 	mac->sme.ll_stats_context = context;
-	if (sme_acquire_global_lock(&mac->sme) == QDF_STATUS_SUCCESS) {
-		/* Serialize the req through MC thread */
-		message.bodyptr = ll_stats_get_req;
-		message.type = WMA_LINK_LAYER_STATS_GET_REQ;
-		qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
-			  NO_SESSION, message.type);
-		status = scheduler_post_message(QDF_MODULE_ID_SME,
-						QDF_MODULE_ID_WMA,
-						QDF_MODULE_ID_WMA, &message);
-		if (!QDF_IS_STATUS_SUCCESS(status)) {
-			sme_err("Not able to post WMA_LL_STATS_GET_REQ");
-			qdf_mem_free(ll_stats_get_req);
-		}
-		sme_release_global_lock(&mac->sme);
-	} else {
-		sme_err("sme_acquire_global_lock error");
+	/* Serialize the req through MC thread */
+	message.bodyptr = ll_stats_get_req;
+	message.type = WMA_LINK_LAYER_STATS_GET_REQ;
+	qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+		  NO_SESSION, message.type);
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &message);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sme_err("Not able to post WMA_LL_STATS_GET_REQ");
 		qdf_mem_free(ll_stats_get_req);
 	}
 
@@ -9943,7 +9917,6 @@ QDF_STATUS sme_ll_stats_set_thresh(mac_handle_t mac_handle,
 				   struct sir_ll_ext_stats_threshold *threshold)
 {
 	QDF_STATUS status;
-	struct mac_context *mac;
 	struct scheduler_msg message = {0};
 	struct sir_ll_ext_stats_threshold *thresh;
 
@@ -9956,7 +9929,6 @@ QDF_STATUS sme_ll_stats_set_thresh(mac_handle_t mac_handle,
 		sme_err("mac_handle is not valid");
 		return QDF_STATUS_E_INVAL;
 	}
-	mac = MAC_CONTEXT(mac_handle);
 
 	thresh = qdf_mem_malloc(sizeof(*thresh));
 	if (!thresh)
@@ -9964,25 +9936,19 @@ QDF_STATUS sme_ll_stats_set_thresh(mac_handle_t mac_handle,
 
 	*thresh = *threshold;
 
-	status = sme_acquire_global_lock(&mac->sme);
-	if (QDF_IS_STATUS_SUCCESS(status)) {
-		/* Serialize the req through MC thread */
-		message.bodyptr = thresh;
-		message.type    = WDA_LINK_LAYER_STATS_SET_THRESHOLD;
-		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
-				 NO_SESSION, message.type));
-		status = scheduler_post_message(QDF_MODULE_ID_SME,
-						QDF_MODULE_ID_WMA,
-						QDF_MODULE_ID_WMA, &message);
-		if (!QDF_IS_STATUS_SUCCESS(status)) {
-			sme_err("not able to post WDA_LL_STATS_GET_REQ");
-			qdf_mem_free(thresh);
-		}
-		sme_release_global_lock(&mac->sme);
-	} else {
-		sme_err("sme_acquire_global_lock error");
+	/* Serialize the req through MC thread */
+	message.bodyptr = thresh;
+	message.type    = WDA_LINK_LAYER_STATS_SET_THRESHOLD;
+	MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
+			 NO_SESSION, message.type));
+	status = scheduler_post_message(QDF_MODULE_ID_SME,
+					QDF_MODULE_ID_WMA,
+					QDF_MODULE_ID_WMA, &message);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sme_err("not able to post WDA_LL_STATS_GET_REQ");
 		qdf_mem_free(thresh);
 	}
+
 	return status;
 }