From ba8b3fe3a82191b5899b24f58ae689ba4c98a145 Mon Sep 17 00:00:00 2001 From: Mohit Khanna Date: Mon, 29 Jul 2019 00:24:24 -0700 Subject: [PATCH] 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 --- core/dp/txrx3.0/dp_rx_thread.c | 14 ++++++-------- core/dp/txrx3.0/dp_rx_thread.h | 28 +--------------------------- 2 files changed, 7 insertions(+), 35 deletions(-) diff --git a/core/dp/txrx3.0/dp_rx_thread.c b/core/dp/txrx3.0/dp_rx_thread.c index f320375c33b7..f8b47d6e4a61 100644 --- a/core/dp/txrx3.0/dp_rx_thread.c +++ b/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]) diff --git a/core/dp/txrx3.0/dp_rx_thread.h b/core/dp/txrx3.0/dp_rx_thread.h index f116809582ea..981df028d510 100644 --- a/core/dp/txrx3.0/dp_rx_thread.h +++ b/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