diff --git a/core/cds/inc/cds_sched.h b/core/cds/inc/cds_sched.h
index b610f297ad647..0c3d160d11994 100644
--- a/core/cds/inc/cds_sched.h
+++ b/core/cds/inc/cds_sched.h
@@ -135,6 +135,10 @@ typedef struct _cds_sched_context {
/* high throughput required */
bool high_throughput_required;
+
+ /* affinity requied during uplink traffic*/
+ bool rx_affinity_required;
+ uint8_t conf_rx_thread_ul_affinity;
#endif
} cds_sched_context, *p_cds_sched_context;
@@ -219,6 +223,25 @@ struct cds_context {
int cds_sched_handle_cpu_hot_plug(void);
int cds_sched_handle_throughput_req(bool high_tput_required);
+/**
+ * cds_sched_handle_rx_thread_affinity_req - rx thread affinity req handler
+ * @high_tput_required: high throughput is required or not
+ *
+ * rx thread affinity handler will find online cores and
+ * will assign proper core based on perf requirement
+ *
+ * Return: None
+ */
+void cds_sched_handle_rx_thread_affinity_req(bool high_throughput);
+
+/**
+ * cds_set_rx_thread_ul_cpu_mask() - Rx_thread affinity for UL from INI
+ * @cpu_affinity_mask: CPU affinity bitmap
+ *
+ * Return:None
+ */
+void cds_set_rx_thread_ul_cpu_mask(uint8_t cpu_affinity_mask);
+
/**
* cds_set_rx_thread_cpu_mask() - Rx_thread affinity from INI
* @cpu_affinity_mask: CPU affinity bitmap
@@ -296,6 +319,26 @@ void cds_free_ol_rx_pkt(p_cds_sched_context pSchedContext,
-------------------------------------------------------------------------*/
void cds_free_ol_rx_pkt_freeq(p_cds_sched_context pSchedContext);
#else
+/**
+ * cds_sched_handle_rx_thread_affinity_req - rx thread affinity req handler
+ * @high_tput_required: high throughput is required or not
+ *
+ * rx thread affinity handler will find online cores and
+ * will assign proper core based on perf requirement
+ *
+ * Return: None
+ */
+static inline void cds_sched_handle_rx_thread_affinity_req(
+ bool high_throughput) {}
+
+/**
+ * cds_set_rx_thread_ul_cpu_mask() - Rx_thread affinity for UL from INI
+ * @cpu_affinity_mask: CPU affinity bitmap
+ *
+ * Return:None
+ */
+static inline void cds_set_rx_thread_ul_cpu_mask(uint8_t cpu_affinity_mask) {}
+
/**
* cds_set_rx_thread_cpu_mask() - Rx_thread affinity from INI
* @cpu_affinity_mask: CPU affinity bitmap
diff --git a/core/cds/src/cds_sched.c b/core/cds/src/cds_sched.c
index 1f9c866a88933..6e2ef2691850d 100644
--- a/core/cds/src/cds_sched.c
+++ b/core/cds/src/cds_sched.c
@@ -93,6 +93,17 @@ void cds_set_rx_thread_cpu_mask(uint8_t cpu_affinity_mask)
sched_context->conf_rx_thread_cpu_mask = cpu_affinity_mask;
}
+void cds_set_rx_thread_ul_cpu_mask(uint8_t cpu_affinity_mask)
+{
+ p_cds_sched_context sched_context = get_cds_sched_ctxt();
+
+ if (!sched_context) {
+ qdf_err("invalid context");
+ return;
+ }
+ sched_context->conf_rx_thread_ul_affinity = cpu_affinity_mask;
+}
+
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
/**
* cds_rx_thread_log_cpu_affinity_change - Log Rx thread affinity change
@@ -236,6 +247,62 @@ int cds_sched_handle_cpu_hot_plug(void)
return 0;
}
+void cds_sched_handle_rx_thread_affinity_req(bool high_throughput)
+{
+ p_cds_sched_context pschedcontext = get_cds_sched_ctxt();
+ unsigned long cpus;
+ qdf_cpu_mask new_mask;
+ unsigned char core_affine_count = 0;
+
+ if (!pschedcontext || !pschedcontext->ol_rx_thread)
+ return;
+
+ if (cds_is_load_or_unload_in_progress()) {
+ cds_err("load or unload in progress");
+ return;
+ }
+
+ if (pschedcontext->rx_affinity_required == high_throughput)
+ return;
+
+ pschedcontext->rx_affinity_required = high_throughput;
+ qdf_cpumask_clear(&new_mask);
+ if (!high_throughput) {
+ /* Attach to all cores, let scheduler decide */
+ qdf_cpumask_setall(&new_mask);
+ goto affine_thread;
+ }
+ for_each_online_cpu(cpus) {
+ if (topology_physical_package_id(cpus) >
+ CDS_MAX_CPU_CLUSTERS) {
+ cds_err("can handle max %d clusters ",
+ CDS_MAX_CPU_CLUSTERS);
+ return;
+ }
+ if (pschedcontext->conf_rx_thread_ul_affinity &&
+ (pschedcontext->conf_rx_thread_ul_affinity &
+ (1 << cpus)))
+ qdf_cpumask_set_cpu(cpus, &new_mask);
+
+ core_affine_count++;
+ }
+
+affine_thread:
+ cds_rx_thread_log_cpu_affinity_change(
+ core_affine_count,
+ (int)pschedcontext->rx_affinity_required,
+ &pschedcontext->rx_thread_cpu_mask,
+ &new_mask);
+
+ mutex_lock(&pschedcontext->affinity_lock);
+ if (!cpumask_equal(&pschedcontext->rx_thread_cpu_mask, &new_mask)) {
+ cpumask_copy(&pschedcontext->rx_thread_cpu_mask, &new_mask);
+ cds_set_cpus_allowed_ptr_with_mask(pschedcontext->ol_rx_thread,
+ &new_mask);
+ }
+ mutex_unlock(&pschedcontext->affinity_lock);
+}
+
/**
* cds_sched_handle_throughput_req - cpu throughput requirement handler
* @high_tput_required: high throughput is required or not
@@ -438,6 +505,7 @@ QDF_STATUS cds_sched_open(void *p_cds_context,
cds_cpu_before_offline_cb);
mutex_init(&pSchedContext->affinity_lock);
pSchedContext->high_throughput_required = false;
+ pSchedContext->rx_affinity_required = false;
#endif
gp_cds_sched_context = pSchedContext;
diff --git a/core/hdd/inc/hdd_dp_cfg.h b/core/hdd/inc/hdd_dp_cfg.h
index ef099139694fd..7cf3c0ae1aa5a 100644
--- a/core/hdd/inc/hdd_dp_cfg.h
+++ b/core/hdd/inc/hdd_dp_cfg.h
@@ -865,6 +865,31 @@
"CPU mask to affine Rx_thread")
#endif
+/*
+ *
+ * RX_THREAD_UL_CPU_AFFINITY_MASK - CPU mask to affine Rx_thread
+ *
+ * @Min: 0
+ * @Max: 0xFF
+ * @Default: 0x0
+ *
+ * This ini is used to set Rx_thread CPU affinity for uplink traffic
+ *
+ * Supported Feature: Rx_thread
+ *
+ * Usage: Internal
+ *
+ *
+ */
+#define CFG_DP_RX_THREAD_UL_CPU_MASK \
+ CFG_INI_UINT( \
+ "RX_THREAD_UL_CPU_AFFINITY_MASK", \
+ 0, \
+ 0xFF, \
+ 0x0, \
+ CFG_VALUE_OR_DEFAULT, \
+ "CPU mask to affine Rx_thread for uplink traffic")
+
/*
*
* rpsRxQueueCpuMapList - RPS map for different RX queues
@@ -1354,6 +1379,7 @@
#define CFG_HDD_DP_ALL \
CFG(CFG_DP_NAPI_CE_CPU_MASK) \
CFG(CFG_DP_RX_THREAD_CPU_MASK) \
+ CFG(CFG_DP_RX_THREAD_UL_CPU_MASK) \
CFG(CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST) \
CFG(CFG_DP_TX_ORPHAN_ENABLE) \
CFG(CFG_DP_RX_MODE) \
diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
index 8059bb9925eb0..cb9c7cfcaa28f 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -195,6 +195,7 @@ struct hdd_config {
#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
uint32_t napi_cpu_affinity_mask;
/* CPU affinity mask for rx_thread */
+ uint32_t rx_thread_ul_affinity_mask;
uint32_t rx_thread_affinity_mask;
uint8_t cpu_map_list[CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST_LEN];
bool multicast_replay_filter;
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index ae4cf4acb3a71..840a206a1beb8 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -3265,6 +3265,10 @@ int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit)
cds_set_rx_thread_cpu_mask(
hdd_ctx->config->rx_thread_affinity_mask);
+ if (hdd_ctx->config->rx_thread_ul_affinity_mask)
+ cds_set_rx_thread_ul_cpu_mask(
+ hdd_ctx->config->rx_thread_ul_affinity_mask);
+
/* initialize components configurations after psoc open */
ret = hdd_update_components_config(hdd_ctx);
if (ret) {
@@ -8393,6 +8397,17 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx,
hdd_set_rps_cpu_mask(hdd_ctx);
}
+ if (hdd_ctx->config->rx_thread_ul_affinity_mask) {
+ if (next_vote_level == PLD_BUS_WIDTH_HIGH &&
+ tx_packets >
+ hdd_ctx->config->bus_bw_high_threshold &&
+ rx_packets >
+ hdd_ctx->config->bus_bw_low_threshold)
+ cds_sched_handle_rx_thread_affinity_req(true);
+ else if (next_vote_level != PLD_BUS_WIDTH_HIGH)
+ cds_sched_handle_rx_thread_affinity_req(false);
+ }
+
if (hdd_ctx->config->napi_cpu_affinity_mask)
hdd_napi_apply_throughput_policy(hdd_ctx,
tx_packets,
diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c
index 1997fac7281db..53a1119eda3f1 100644
--- a/core/hdd/src/wlan_hdd_tx_rx.c
+++ b/core/hdd/src/wlan_hdd_tx_rx.c
@@ -3183,6 +3183,8 @@ void hdd_dp_cfg_update(struct wlan_objmgr_psoc *psoc,
config->napi_cpu_affinity_mask =
cfg_get(psoc, CFG_DP_NAPI_CE_CPU_MASK);
+ config->rx_thread_ul_affinity_mask =
+ cfg_get(psoc, CFG_DP_RX_THREAD_UL_CPU_MASK);
config->rx_thread_affinity_mask =
cfg_get(psoc, CFG_DP_RX_THREAD_CPU_MASK);
qdf_uint8_array_parse(cfg_get(psoc, CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST),