Jelajahi Sumber

qcacld-3.0: Resume DP threads during SSR

During SSR, DP RX threads need to be resumed so that they can be later
shutdown by posting RX_SHUTDOWN_EVENT to the threads. DP Threads
shutdown procedure waits on a completion event, which is completed by
the threads. In case the threads are not up, the caller may
be stuck waiting for DP threads to shutdown.

Check state before DP RX thread suspend/resume to avoid repetitive
suspend/resume requests.

Change-Id: Idb689e0dae7cf487e0bea45ef2dade369ae2f9f6
CRs-Fixed: 2529673
Mohit Khanna 5 tahun lalu
induk
melakukan
7a2116a8a7

+ 16 - 5
core/dp/txrx3.0/dp_rx_thread.c

@@ -587,6 +587,7 @@ QDF_STATUS dp_rx_tm_init(struct dp_rx_tm_handle *rx_tm_hdl,
 	}
 
 	rx_tm_hdl->num_dp_rx_threads = num_dp_rx_threads;
+	rx_tm_hdl->state = DP_RX_THREADS_INVALID;
 
 	dp_info("initializing %u threads", num_dp_rx_threads);
 
@@ -618,6 +619,8 @@ QDF_STATUS dp_rx_tm_init(struct dp_rx_tm_handle *rx_tm_hdl,
 ret:
 	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
 		dp_rx_tm_deinit(rx_tm_hdl);
+	else
+		rx_tm_hdl->state = DP_RX_THREADS_RUNNING;
 
 	return qdf_status;
 }
@@ -635,6 +638,11 @@ QDF_STATUS dp_rx_tm_suspend(struct dp_rx_tm_handle *rx_tm_hdl)
 	QDF_STATUS qdf_status;
 	struct dp_rx_thread *rx_thread;
 
+	if (rx_tm_hdl->state == DP_RX_THREADS_SUSPENDED) {
+		dp_info("already in suspend state! Ignoring.");
+		return QDF_STATUS_E_INVAL;
+	}
+
 	for (i = 0; i < rx_tm_hdl->num_dp_rx_threads; i++) {
 		if (!rx_tm_hdl->rx_thread[i])
 			continue;
@@ -659,7 +667,7 @@ QDF_STATUS dp_rx_tm_suspend(struct dp_rx_tm_handle *rx_tm_hdl)
 			dp_err("thread:%d failed while waiting for suspend",
 			       rx_thread->id);
 	}
-	rx_tm_hdl->state = DP_RX_THREAD_SUSPENDED;
+	rx_tm_hdl->state = DP_RX_THREADS_SUSPENDED;
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -669,15 +677,15 @@ QDF_STATUS dp_rx_tm_suspend(struct dp_rx_tm_handle *rx_tm_hdl)
  * @rx_tm_hdl: dp_rx_tm_handle containing the overall thread
  *            infrastructure
  *
- * Return: QDF_STATUS_SUCCESS
+ * Return: QDF_STATUS_SUCCESS on resume success. QDF error otherwise.
  */
 QDF_STATUS dp_rx_tm_resume(struct dp_rx_tm_handle *rx_tm_hdl)
 {
 	int i;
 
-	if (rx_tm_hdl->state != DP_RX_THREAD_SUSPENDED) {
-		dp_err("resume callback received without suspend");
-		return QDF_STATUS_E_FAULT;
+	if (rx_tm_hdl->state != DP_RX_THREADS_SUSPENDED) {
+		dp_info("resume callback received w/o suspend! Ignoring.");
+		return QDF_STATUS_E_INVAL;
 	}
 
 	for (i = 0; i < rx_tm_hdl->num_dp_rx_threads; i++) {
@@ -687,6 +695,8 @@ QDF_STATUS dp_rx_tm_resume(struct dp_rx_tm_handle *rx_tm_hdl)
 		qdf_event_set(&rx_tm_hdl->rx_thread[i]->resume_event);
 	}
 
+	rx_tm_hdl->state = DP_RX_THREADS_RUNNING;
+
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -718,6 +728,7 @@ static QDF_STATUS dp_rx_tm_shutdown(struct dp_rx_tm_handle *rx_tm_hdl)
 		qdf_wait_single_event(&rx_tm_hdl->rx_thread[i]->shutdown_event,
 				      0);
 	}
+	rx_tm_hdl->state = DP_RX_THREADS_INVALID;
 	return QDF_STATUS_SUCCESS;
 }
 

+ 7 - 9
core/dp/txrx3.0/dp_rx_thread.h

@@ -99,18 +99,16 @@ struct dp_rx_thread {
 };
 
 /**
- * enum dp_rx_thread_state - enum to keep track of the state of the rx thread
- * @DP_RX_THREAD_INVALID: initial invalid state
- * @DP_RX_THREAD_INIT: state after being initialized
- * @DP_RX_THREAD_RUNNING: rx thread is functional(NOT suspended, processing
+ * enum dp_rx_thread_state - enum to keep track of the state of the rx threads
+ * @DP_RX_THREADS_INVALID: initial invalid state
+ * @DP_RX_THREADS_RUNNING: rx threads functional(NOT suspended, processing
  *			  packets or waiting on a wait_queue)
- * @DP_RX_THREAD_SUSPENDED: rx_thread operation is suspeded from cfg8011 suspend
+ * @DP_RX_THREADS_SUSPENDED: rx_threads suspended from cfg8011 suspend
  */
 enum dp_rx_thread_state {
-	DP_RX_THREAD_INVALID,
-	DP_RX_THREAD_INIT,
-	DP_RX_THREAD_RUNNING,
-	DP_RX_THREAD_SUSPENDED
+	DP_RX_THREADS_INVALID,
+	DP_RX_THREADS_RUNNING,
+	DP_RX_THREADS_SUSPENDED
 };
 
 /**

+ 2 - 0
core/hdd/src/wlan_hdd_power.c

@@ -1279,6 +1279,8 @@ QDF_STATUS hdd_wlan_shutdown(void)
 
 	wlan_hdd_rx_thread_resume(hdd_ctx);
 
+	dp_txrx_resume(cds_get_context(QDF_MODULE_ID_SOC));
+
 	/*
 	 * After SSR, FW clear its txrx stats. In host,
 	 * as adapter is intact so those counts are still