summaryrefslogtreecommitdiff
path: root/drivers/rmnet/shs/rmnet_shs_wq.c
diff options
context:
space:
mode:
authorSubash Abhinov Kasiviswanathan <subashab@codeaurora.org>2018-10-09 15:30:41 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2018-11-14 17:34:44 -0800
commit2cf592518f41919bc55d61670cb91a6239864367 (patch)
treea193d574cbab6313e549a756f0a1d9eb003e3065 /drivers/rmnet/shs/rmnet_shs_wq.c
parent4f36ca5fa529e9774b4eb37115ff5b9a2e1cf4f2 (diff)
downloaddata-kernel-2cf592518f41919bc55d61670cb91a6239864367.tar.gz
drivers: rmnet_shs: Reduce switching OOO packets
Previously we only switch at the request of the core monitoring workqueu. This adds an option to switch in rx context based on the an instant rate measure on the core. Based on this we will mark core as loaded and move flows from that core after a delay. This reduces OOO packets by reacting quicker to lower the pending backlog and by waiting longer between a switch. Change-Id: I09b6f01fa1cda982728dc8d5e8004c6323d0612b Acked-by: Raul Martinez <mraul@qti.qualcomm.com> Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
Diffstat (limited to 'drivers/rmnet/shs/rmnet_shs_wq.c')
-rw-r--r--drivers/rmnet/shs/rmnet_shs_wq.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/drivers/rmnet/shs/rmnet_shs_wq.c b/drivers/rmnet/shs/rmnet_shs_wq.c
index 02392d8..42f316c 100644
--- a/drivers/rmnet/shs/rmnet_shs_wq.c
+++ b/drivers/rmnet/shs/rmnet_shs_wq.c
@@ -35,6 +35,11 @@ MODULE_LICENSE("GPL v2");
*/
/* Local Definitions and Declarations */
+unsigned int rmnet_shs_cpu_prio_dur __read_mostly = RMNET_SHS_WQ_DELAY_TICKS;
+module_param(rmnet_shs_cpu_prio_dur, uint, 0644);
+MODULE_PARM_DESC(rmnet_shs_cpu_prio_dur, "Priority ignore duration(ticks)");
+
+#define PRIO_BACKOFF ((!rmnet_shs_cpu_prio_dur) ? 2 : rmnet_shs_cpu_prio_dur)
unsigned int rmnet_shs_wq_frequency __read_mostly = RMNET_SHS_WQ_DELAY_TICKS;
module_param(rmnet_shs_wq_frequency, uint, 0644);
@@ -145,7 +150,6 @@ static struct workqueue_struct *rmnet_shs_wq;
static struct rmnet_shs_delay_wq_s *rmnet_shs_delayed_wq;
static struct rmnet_shs_wq_rx_flow_s rmnet_shs_rx_flow_tbl;
-
static struct list_head rmnet_shs_wq_hstat_tbl =
LIST_HEAD_INIT(rmnet_shs_wq_hstat_tbl);
static int rmnet_shs_flow_dbg_stats_idx_cnt;
@@ -351,7 +355,6 @@ struct rmnet_shs_wq_hstat_s *rmnet_shs_wq_get_new_hstat_node(void)
return NULL;
}
-
rmnet_shs_wq_hstat_reset_node(ret_node);
ret_node->is_perm = 0;
ret_node->in_use = 1;
@@ -494,7 +497,6 @@ void rmnet_shs_wq_update_hash_stats(struct rmnet_shs_wq_hstat_s *hstats_p)
hstats_p->hash, 0xDEF, hstats_p->rx_pps,
hstats_p->rx_bps, hstats_p, NULL);
-
rmnet_shs_wq_update_hstat_rps_msk(hstats_p);
hstats_p->inactive_duration = 0;
hstats_p->l_epoch = node_p->hstats->c_epoch;
@@ -598,6 +600,9 @@ static void rmnet_shs_wq_refresh_cpu_stats(u16 cpu)
cpu_p = &rmnet_shs_rx_flow_tbl.cpu_list[cpu];
new_skbs = cpu_p->rx_skbs - cpu_p->last_rx_skbs;
+ if (rmnet_shs_cpu_node_tbl[cpu].wqprio)
+ rmnet_shs_cpu_node_tbl[cpu].wqprio = (rmnet_shs_cpu_node_tbl[cpu].wqprio + 1)
+ % (PRIO_BACKOFF);
if (new_skbs == 0) {
cpu_p->l_epoch = rmnet_shs_wq_tnsec;
cpu_p->rx_bps = 0;
@@ -664,7 +669,6 @@ void rmnet_shs_wq_update_cpu_rx_tbl(struct rmnet_shs_wq_hstat_s *hstat_p)
map_idx = node_p->map_index;
cpu_num = map->cpus[map_idx];
-
skb_diff = hstat_p->rx_skb - hstat_p->last_rx_skb;
byte_diff = hstat_p->rx_bytes - hstat_p->last_rx_bytes;
@@ -839,6 +843,13 @@ u16 rmnet_shs_wq_find_cpu_to_move_flows(u16 current_cpu,
(cur_cpu_rx_pps > pps_uthresh)) {
return cpu_to_move;
}
+ /* If a core (should only be lpwr was marked prio we don't touch it
+ * for a few ticks and reset it afterwards
+ */
+
+ if (rmnet_shs_cpu_node_tbl[current_cpu].wqprio) {
+ return current_cpu;
+ }
for (cpu_num = 0; cpu_num < MAX_CPUS; cpu_num++) {
@@ -847,7 +858,8 @@ u16 rmnet_shs_wq_find_cpu_to_move_flows(u16 current_cpu,
/* We are looking for a core that is configured and that
* can handle traffic better than the current core
*/
- if ((cpu_num == current_cpu) || (!is_core_in_msk))
+ if ((cpu_num == current_cpu) || (!is_core_in_msk) ||
+ !cpu_online(current_cpu))
continue;
pps_uthresh = rmnet_shs_cpu_rx_max_pps_thresh[cpu_num];
@@ -858,9 +870,9 @@ u16 rmnet_shs_wq_find_cpu_to_move_flows(u16 current_cpu,
reqd_pps = cpu_rx_pps + cur_cpu_rx_pps;
trace_rmnet_shs_wq_low(RMNET_SHS_WQ_CPU_STATS,
- RMNET_SHS_WQ_CPU_STATS_CORE2SWITCH_FIND,
- current_cpu, cpu_num, reqd_pps,
- cpu_rx_pps, NULL, NULL);
+ RMNET_SHS_WQ_CPU_STATS_CORE2SWITCH_FIND,
+ current_cpu, cpu_num, reqd_pps,
+ cpu_rx_pps, NULL, NULL);
/* Return the first available CPU */
if ((reqd_pps > pps_lthresh) && (reqd_pps < pps_uthresh)) {
@@ -1314,7 +1326,6 @@ void rmnet_shs_wq_clean_ep_tbl(void)
void rmnet_shs_wq_exit(void)
{
-
/*If Wq is not initialized, nothing to cleanup */
if (!rmnet_shs_wq || !rmnet_shs_delayed_wq)
return;