diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/rmnet/shs/rmnet_shs_wq.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/rmnet/shs/rmnet_shs_wq.c b/drivers/rmnet/shs/rmnet_shs_wq.c index 620a41f..5944f16 100644 --- a/drivers/rmnet/shs/rmnet_shs_wq.c +++ b/drivers/rmnet/shs/rmnet_shs_wq.c @@ -28,6 +28,8 @@ MODULE_LICENSE("GPL v2"); #define RMNET_SHS_NSEC_TO_SEC(x) ((x)/1000000000) #define RMNET_SHS_BYTE_TO_BIT(x) ((x)*8) #define RMNET_SHS_MIN_HSTAT_NODES_REQD 16 +#define RMNET_SHS_FILTER_PKT_LIMIT 200 +#define RMNET_SHS_FILTER_FLOW_RATE 100 #define PERIODIC_CLEAN 0 /* FORCE_CLEAN should only used during module de-ini.*/ @@ -88,6 +90,10 @@ unsigned int rmnet_shs_cpu_rx_flows[MAX_CPUS]; module_param_array(rmnet_shs_cpu_rx_flows, uint, 0, 0444); MODULE_PARM_DESC(rmnet_shs_cpu_rx_flows, "Num flows processed per core"); +unsigned int rmnet_shs_cpu_rx_filter_flows[MAX_CPUS]; +module_param_array(rmnet_shs_cpu_rx_filter_flows, uint, 0, 0644); +MODULE_PARM_DESC(rmnet_shs_cpu_rx_filter_flows, "Num filtered flows per core"); + unsigned long long rmnet_shs_cpu_rx_bytes[MAX_CPUS]; module_param_array(rmnet_shs_cpu_rx_bytes, ullong, 0, 0444); MODULE_PARM_DESC(rmnet_shs_cpu_rx_bytes, "SHS stamp bytes per CPU"); @@ -1901,6 +1907,29 @@ void rmnet_shs_update_cfg_mask(void) } } +void rmnet_shs_wq_filter(void) +{ + int cpu; + int temp; + struct rmnet_shs_wq_hstat_s *hnode = NULL; + + for (cpu = 0; cpu < MAX_CPUS; cpu++) + rmnet_shs_cpu_rx_filter_flows[cpu] = 0; + + /* Filter out flows with low pkt count */ + list_for_each_entry(hnode, &rmnet_shs_wq_hstat_tbl, hstat_node_id) { + + if (hnode->in_use == 0) + continue; + if (hnode->avg_pps > RMNET_SHS_FILTER_FLOW_RATE && + hnode->rx_skb > RMNET_SHS_FILTER_PKT_LIMIT) + if (hnode->current_cpu < MAX_CPUS){ + temp = hnode->current_cpu; + rmnet_shs_cpu_rx_filter_flows[temp]++; + } + } +} + void rmnet_shs_wq_update_stats(void) { struct timespec time; @@ -1955,6 +1984,7 @@ void rmnet_shs_wq_update_stats(void) /*Invoke after both the locks are released*/ rmnet_shs_wq_cleanup_hash_tbl(PERIODIC_CLEAN); rmnet_shs_wq_debug_print_flows(); + rmnet_shs_wq_filter(); } void rmnet_shs_wq_process_wq(struct work_struct *work) @@ -2042,8 +2072,13 @@ void rmnet_shs_wq_init_cpu_rx_flow_tbl(void) void rmnet_shs_wq_pause(void) { + int cpu; + if (rmnet_shs_wq && rmnet_shs_delayed_wq) cancel_delayed_work_sync(&rmnet_shs_delayed_wq->wq); + + for (cpu = 0; cpu < MAX_CPUS; cpu++) + rmnet_shs_cpu_rx_filter_flows[cpu] = 0; } void rmnet_shs_wq_restart(void) |