Browse Source

qcacld-3.0: Use different wait queues for threads

Currently DP RX threads are using the same wait_q for all operations.
The problem with this is that when there is traffic for only one
threads, we end up waking up other threads as well moementarily.
This wastes power and is in-efficient.

Use different wait queues for different threads.

CRs-Fixed: 2495719
Change-Id: I689659b7aa0ab93b7e2f009d2dc7fe741b66ee78
Mohit Khanna 5 years ago
parent
commit
ba8b3fe3a8
2 changed files with 7 additions and 35 deletions
  1. 6 8
      core/dp/txrx3.0/dp_rx_thread.c
  2. 1 27
      core/dp/txrx3.0/dp_rx_thread.h

+ 6 - 8
core/dp/txrx3.0/dp_rx_thread.c

@@ -161,7 +161,7 @@ static QDF_STATUS dp_rx_tm_thread_enqueue(struct dp_rx_thread *rx_thread,
 		return QDF_STATUS_E_FAILURE;
 	}
 
-	wait_q_ptr = dp_rx_thread_get_wait_queue(tm_handle_cmn);
+	wait_q_ptr = &rx_thread->wait_q;
 
 	if (reo_ring_num >= DP_RX_TM_MAX_REO_RINGS) {
 		dp_alert("incorrect ring %u", reo_ring_num);
@@ -226,7 +226,7 @@ static QDF_STATUS dp_rx_tm_thread_gro_flush_ind(struct dp_rx_thread *rx_thread)
 	qdf_wait_queue_head_t *wait_q_ptr;
 
 	tm_handle_cmn = rx_thread->rtm_handle_cmn;
-	wait_q_ptr = dp_rx_thread_get_wait_queue(tm_handle_cmn);
+	wait_q_ptr = &rx_thread->wait_q;
 
 	qdf_atomic_set(&rx_thread->gro_flush_ind, 1);
 
@@ -447,7 +447,7 @@ static int dp_rx_thread_loop(void *arg)
 		dp_debug("sleeping");
 		status =
 		    qdf_wait_queue_interruptible
-				(DP_RX_THREAD_GET_WAIT_QUEUE_OBJ(tm_handle_cmn),
+				(rx_thread->wait_q,
 				 qdf_atomic_test_bit(RX_POST_EVENT,
 						     &rx_thread->event_flag) ||
 				 qdf_atomic_test_bit(RX_SUSPEND_EVENT,
@@ -539,6 +539,7 @@ static QDF_STATUS dp_rx_tm_thread_init(struct dp_rx_thread *rx_thread,
 	qdf_event_create(&rx_thread->resume_event);
 	qdf_event_create(&rx_thread->shutdown_event);
 	qdf_atomic_init(&rx_thread->gro_flush_ind);
+	qdf_init_waitqueue_head(&rx_thread->wait_q);
 	qdf_scnprintf(thread_name, sizeof(thread_name), "dp_rx_thread_%u", id);
 	dp_info("%s %u", thread_name, id);
 
@@ -609,8 +610,6 @@ QDF_STATUS dp_rx_tm_init(struct dp_rx_tm_handle *rx_tm_hdl,
 		goto ret;
 	}
 
-	qdf_init_waitqueue_head(&rx_tm_hdl->wait_q);
-
 	for (i = 0; i < rx_tm_hdl->num_dp_rx_threads; i++) {
 		rx_tm_hdl->rx_thread[i] =
 			(struct dp_rx_thread *)
@@ -652,10 +651,9 @@ QDF_STATUS dp_rx_tm_suspend(struct dp_rx_tm_handle *rx_tm_hdl)
 			continue;
 		qdf_set_bit(RX_SUSPEND_EVENT,
 			    &rx_tm_hdl->rx_thread[i]->event_flag);
+		qdf_wake_up_interruptible(&rx_tm_hdl->rx_thread[i]->wait_q);
 	}
 
-	qdf_wake_up_interruptible(&rx_tm_hdl->wait_q);
-
 	for (i = 0; i < rx_tm_hdl->num_dp_rx_threads; i++) {
 		rx_thread = rx_tm_hdl->rx_thread[i];
 		if (!rx_thread)
@@ -720,9 +718,9 @@ static QDF_STATUS dp_rx_tm_shutdown(struct dp_rx_tm_handle *rx_tm_hdl)
 			    &rx_tm_hdl->rx_thread[i]->event_flag);
 		qdf_set_bit(RX_POST_EVENT,
 			    &rx_tm_hdl->rx_thread[i]->event_flag);
+		qdf_wake_up_interruptible(&rx_tm_hdl->rx_thread[i]->wait_q);
 	}
 
-	qdf_wake_up_interruptible(&rx_tm_hdl->wait_q);
 
 	for (i = 0; i < rx_tm_hdl->num_dp_rx_threads; i++) {
 		if (!rx_tm_hdl->rx_thread[i])

+ 1 - 27
core/dp/txrx3.0/dp_rx_thread.h

@@ -29,13 +29,6 @@
 /* Number of DP RX threads supported */
 #define DP_MAX_RX_THREADS DP_RX_TM_MAX_REO_RINGS
 
-/*
- * Macro to get to wait_queue structure. Needed since wait_q is an object.
- * API qdf_wait_queue_interruptible needs the object be passed to it and not a
- * pointer
- */
-#define DP_RX_THREAD_GET_WAIT_QUEUE_OBJ(rx_tm_handle_cmn) \
-		(((struct dp_rx_tm_handle *)rx_tm_handle_cmn)->wait_q)
 /*
  * struct dp_rx_tm_handle_cmn - Opaque handle for rx_threads to store
  * rx_tm_handle. This handle will be common for all the threads.
@@ -101,6 +94,7 @@ struct dp_rx_thread {
 	struct dp_rx_thread_stats stats;
 	struct dp_rx_tm_handle_cmn *rtm_handle_cmn;
 	struct napi_struct napi;
+	qdf_wait_queue_head_t wait_q;
 	struct net_device netdev;
 };
 
@@ -123,14 +117,12 @@ enum dp_rx_thread_state {
  * struct dp_rx_tm_handle - DP RX thread infrastructure handle
  * @num_dp_rx_threads: number of DP RX threads initialized
  * @txrx_handle_cmn: opaque txrx handle to get to pdev and soc
- * wait_q: wait_queue for the rx_threads to wait on and expect an event
  * @state: state of the rx_threads. All of them should be in the same state.
  * @rx_thread: array of pointers of type struct dp_rx_thread
  */
 struct dp_rx_tm_handle {
 	uint8_t num_dp_rx_threads;
 	struct dp_txrx_handle_cmn *txrx_handle_cmn;
-	qdf_wait_queue_head_t wait_q;
 	enum dp_rx_thread_state state;
 	struct dp_rx_thread **rx_thread;
 };
@@ -209,24 +201,6 @@ dp_rx_thread_get_txrx_handle(struct dp_rx_tm_handle_cmn *rx_tm_handle_cmn)
 	return (((struct dp_rx_tm_handle *)rx_tm_handle_cmn)->txrx_handle_cmn);
 }
 
-/**
- * dp_rx_thread_get_wait_queue() - get wait_q from dp_rx_tm_handle
- * @rx_tm_handle_cmn: opaque pointer to dp_rx_tm_handle_cmn struct
- *
- * The function is needed since dp_rx_thread does not have access to the real
- * dp_rx_tm_handle structure, but only an opaque dp_rx_tm_handle_cmn handle
- *
- * Return: pointer to dp_txrx_handle_cmn handle
- */
-static inline qdf_wait_queue_head_t*
-dp_rx_thread_get_wait_queue(struct dp_rx_tm_handle_cmn *rx_tm_handle_cmn)
-{
-	struct dp_rx_tm_handle *rx_tm_handle;
-
-	rx_tm_handle = (struct dp_rx_tm_handle *)rx_tm_handle_cmn;
-	return &rx_tm_handle->wait_q;
-}
-
 /**
  * dp_rx_tm_get_napi_context() - get NAPI context for a RX CTX ID
  * @soc: ol_txrx_soc_handle object