mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-15 17:24:14 -04:00
qcacld-3.0: Refine RX GRO flush when detach the vdev device
There might be race condition when doing RX GRO flush between dp_rx_thread and vdev detach thread. Only doing RX GRO flush in the dp_rx_thread context, and use the events to sync with dp_rx_thread and vdev detach thread. Change-Id: I2dbf92c2c11e950ca790dd7429c8bb235c239d0c CRs-Fixed: 2601826
This commit is contained in:
parent
b3b2194db6
commit
0da98c48ee
3 changed files with 41 additions and 7 deletions
|
|
@ -45,6 +45,7 @@
|
|||
#define MC_SUSPEND_EVENT 0x002
|
||||
#define RX_POST_EVENT 0x001
|
||||
#define RX_SUSPEND_EVENT 0x002
|
||||
#define RX_VDEV_DEL_EVENT 0x004
|
||||
#define RX_SHUTDOWN_EVENT 0x010
|
||||
|
||||
#ifdef QCA_CONFIG_SMP
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ static void dp_rx_tm_thread_dump_stats(struct dp_rx_thread *rx_thread)
|
|||
if (!total_queued)
|
||||
return;
|
||||
|
||||
dp_info("thread:%u - qlen:%u queued:(total:%u %s) dequeued:%u stack:%u gro_flushes: %u rx_flushes: %u max_len:%u invalid(peer:%u vdev:%u rx-handle:%u others:%u)",
|
||||
dp_info("thread:%u - qlen:%u queued:(total:%u %s) dequeued:%u stack:%u gro_flushes: %u gro_flushes_by_vdev_del: %u rx_flushes: %u max_len:%u invalid(peer:%u vdev:%u rx-handle:%u others:%u)",
|
||||
rx_thread->id,
|
||||
qdf_nbuf_queue_head_qlen(&rx_thread->nbuf_queue),
|
||||
total_queued,
|
||||
|
|
@ -112,6 +112,7 @@ static void dp_rx_tm_thread_dump_stats(struct dp_rx_thread *rx_thread)
|
|||
rx_thread->stats.nbuf_dequeued,
|
||||
rx_thread->stats.nbuf_sent_to_stack,
|
||||
rx_thread->stats.gro_flushes,
|
||||
rx_thread->stats.gro_flushes_by_vdev_del,
|
||||
rx_thread->stats.rx_flushed,
|
||||
rx_thread->stats.nbufq_max_len,
|
||||
rx_thread->stats.dropped_invalid_peer,
|
||||
|
|
@ -384,11 +385,19 @@ static int dp_rx_thread_sub_loop(struct dp_rx_thread *rx_thread, bool *shutdown)
|
|||
|
||||
dp_rx_thread_process_nbufq(rx_thread);
|
||||
|
||||
if (qdf_atomic_read(&rx_thread->gro_flush_ind)) {
|
||||
if (qdf_atomic_read(&rx_thread->gro_flush_ind) |
|
||||
qdf_atomic_test_bit(RX_VDEV_DEL_EVENT,
|
||||
&rx_thread->event_flag)) {
|
||||
dp_rx_thread_gro_flush(rx_thread);
|
||||
qdf_atomic_set(&rx_thread->gro_flush_ind, 0);
|
||||
}
|
||||
|
||||
if (qdf_atomic_test_and_clear_bit(RX_VDEV_DEL_EVENT,
|
||||
&rx_thread->event_flag)) {
|
||||
rx_thread->stats.gro_flushes_by_vdev_del++;
|
||||
qdf_event_set(&rx_thread->vdev_del_event);
|
||||
}
|
||||
|
||||
if (qdf_atomic_test_and_clear_bit(RX_SUSPEND_EVENT,
|
||||
&rx_thread->event_flag)) {
|
||||
dp_debug("received suspend ind (%s) id %d pid %d",
|
||||
|
|
@ -441,6 +450,8 @@ static int dp_rx_thread_loop(void *arg)
|
|||
qdf_atomic_test_bit(RX_POST_EVENT,
|
||||
&rx_thread->event_flag) ||
|
||||
qdf_atomic_test_bit(RX_SUSPEND_EVENT,
|
||||
&rx_thread->event_flag) ||
|
||||
qdf_atomic_test_bit(RX_VDEV_DEL_EVENT,
|
||||
&rx_thread->event_flag));
|
||||
dp_debug("woken up");
|
||||
|
||||
|
|
@ -528,6 +539,7 @@ static QDF_STATUS dp_rx_tm_thread_init(struct dp_rx_thread *rx_thread,
|
|||
qdf_event_create(&rx_thread->suspend_event);
|
||||
qdf_event_create(&rx_thread->resume_event);
|
||||
qdf_event_create(&rx_thread->shutdown_event);
|
||||
qdf_event_create(&rx_thread->vdev_del_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);
|
||||
|
|
@ -567,6 +579,7 @@ static QDF_STATUS dp_rx_tm_thread_deinit(struct dp_rx_thread *rx_thread)
|
|||
qdf_event_destroy(&rx_thread->suspend_event);
|
||||
qdf_event_destroy(&rx_thread->resume_event);
|
||||
qdf_event_destroy(&rx_thread->shutdown_event);
|
||||
qdf_event_destroy(&rx_thread->vdev_del_event);
|
||||
|
||||
if (cdp_cfg_get(dp_rx_tm_get_soc_handle(rx_thread->rtm_handle_cmn),
|
||||
cfg_dp_gro_enable))
|
||||
|
|
@ -680,6 +693,10 @@ QDF_STATUS dp_rx_tm_suspend(struct dp_rx_tm_handle *rx_tm_hdl)
|
|||
* to be flushed out
|
||||
* @vdev_id: vdev id for which packets are to be flushed
|
||||
*
|
||||
* The function will flush the RX packets by vdev_id in a particular
|
||||
* RX thead queue. And will notify and wait the TX thread to flush the
|
||||
* packets in the NAPI RX GRO hash list
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static inline
|
||||
|
|
@ -688,6 +705,7 @@ void dp_rx_thread_flush_by_vdev_id(struct dp_rx_thread *rx_thread,
|
|||
{
|
||||
qdf_nbuf_t nbuf_list, tmp_nbuf_list;
|
||||
uint32_t num_list_elements = 0;
|
||||
QDF_STATUS qdf_status;
|
||||
|
||||
qdf_nbuf_queue_head_lock(&rx_thread->nbuf_queue);
|
||||
QDF_NBUF_QUEUE_WALK_SAFE(&rx_thread->nbuf_queue, nbuf_list,
|
||||
|
|
@ -704,10 +722,20 @@ void dp_rx_thread_flush_by_vdev_id(struct dp_rx_thread *rx_thread,
|
|||
}
|
||||
qdf_nbuf_queue_head_unlock(&rx_thread->nbuf_queue);
|
||||
|
||||
if (qdf_atomic_read(&rx_thread->gro_flush_ind))
|
||||
qdf_atomic_set(&rx_thread->gro_flush_ind, 0);
|
||||
qdf_set_bit(RX_VDEV_DEL_EVENT, &rx_thread->event_flag);
|
||||
qdf_wake_up_interruptible(&rx_thread->wait_q);
|
||||
|
||||
dp_rx_thread_gro_flush(rx_thread);
|
||||
qdf_status = qdf_wait_single_event(&rx_thread->vdev_del_event,
|
||||
DP_RX_THREAD_WAIT_TIMEOUT);
|
||||
if (QDF_IS_STATUS_SUCCESS(qdf_status))
|
||||
dp_debug("thread:%d napi gro flush successfully",
|
||||
rx_thread->id);
|
||||
else if (qdf_status == QDF_STATUS_E_TIMEOUT)
|
||||
dp_err("thread:%d timed out waiting for napi gro flush",
|
||||
rx_thread->id);
|
||||
else
|
||||
dp_err("thread:%d failed while waiting for napi gro flush",
|
||||
rx_thread->id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2014-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
|
|
@ -44,6 +44,7 @@ struct dp_rx_tm_handle_cmn;
|
|||
* @nbuf_sent_to_stack: packets sent to the stack. some dequeued packets may be
|
||||
* dropped due to no peer or vdev, hence this stat.
|
||||
* @gro_flushes: number of GRO flushes
|
||||
* @gro_flushes_by_vdev_del: number of GRO flushes triggered by vdev del.
|
||||
* @nbufq_max_len: maximum number of nbuf_lists queued for the thread
|
||||
* @dropped_invalid_vdev: packets(nbuf_list) dropped due to no vdev
|
||||
* @rx_flushed: packets flushed after vdev delete
|
||||
|
|
@ -56,6 +57,7 @@ struct dp_rx_thread_stats {
|
|||
unsigned int nbuf_dequeued;
|
||||
unsigned int nbuf_sent_to_stack;
|
||||
unsigned int gro_flushes;
|
||||
unsigned int gro_flushes_by_vdev_del;
|
||||
unsigned int nbufq_max_len;
|
||||
unsigned int dropped_invalid_vdev;
|
||||
unsigned int rx_flushed;
|
||||
|
|
@ -72,6 +74,8 @@ struct dp_rx_thread_stats {
|
|||
* @suspend_event: handle of Event for DP Rx thread to signal suspend
|
||||
* @resume_event: handle of Event for DP Rx thread to signal resume
|
||||
* @shutdown_event: handle of Event for DP Rx thread to signal shutdown
|
||||
* @vdev_del_event: handle of Event for vdev del thread to signal completion
|
||||
* for gro flush
|
||||
* @event_flag: event flag to post events to DP Rx thread
|
||||
* @nbuf_queue:nbuf queue used to store RX packets
|
||||
* @nbufq_len: length of the nbuf queue
|
||||
|
|
@ -89,6 +93,7 @@ struct dp_rx_thread {
|
|||
qdf_event_t suspend_event;
|
||||
qdf_event_t resume_event;
|
||||
qdf_event_t shutdown_event;
|
||||
qdf_event_t vdev_del_event;
|
||||
qdf_atomic_t gro_flush_ind;
|
||||
unsigned long event_flag;
|
||||
qdf_nbuf_queue_head_t nbuf_queue;
|
||||
|
|
|
|||
Loading…
Reference in a new issue