summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorHarout Hedeshian <harouth@codeaurora.org>2014-12-17 09:34:36 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-22 11:05:25 -0700
commit8fcebfae02c88e69ec1a43d3f67a16329d740d32 (patch)
tree920b931bdc6d2d55f12b5d3e3e311edec24d0736 /net
parentaf786e544f4269724b04ed3da24c9383554ffb4b (diff)
net: rmnet_data: Optimize UL aggregation accumulation logic
Accumulation logic now respects max packet count as well as buffer size. Additionally, packets will get shipped if they have been sitting around for more than 1ms. This parameter is tunable from the module parameters location. CRs-Fixed: 772705 Change-Id: I1b5cb597ef6adfe19df590582f9a6cae091c5977 Signed-off-by: Harout Hedeshian <harouth@codeaurora.org>
Diffstat (limited to 'net')
-rw-r--r--net/rmnet_data/rmnet_data_config.h3
-rw-r--r--net/rmnet_data/rmnet_map_data.c23
2 files changed, 23 insertions, 3 deletions
diff --git a/net/rmnet_data/rmnet_data_config.h b/net/rmnet_data/rmnet_data_config.h
index f947cf164149..6bacad45980e 100644
--- a/net/rmnet_data/rmnet_data_config.h
+++ b/net/rmnet_data/rmnet_data_config.h
@@ -15,6 +15,7 @@
*/
#include <linux/types.h>
+#include <linux/time.h>
#include <linux/spinlock.h>
#ifndef _RMNET_DATA_CONFIG_H_
@@ -57,6 +58,7 @@ struct rmnet_logical_ep_conf_s {
* Smaller of the two parameters above are chosen for
* aggregation
* @tail_spacing: Guaranteed padding (bytes) when de-aggregating ingress frames
+ * @agg_time: Wall clock time when aggregated frame was created
*/
struct rmnet_phys_ep_conf_s {
struct net_device *dev;
@@ -73,6 +75,7 @@ struct rmnet_phys_ep_conf_s {
uint8_t agg_state;
uint8_t agg_count;
uint8_t tail_spacing;
+ struct timespec agg_time;
};
int rmnet_config_init(void);
diff --git a/net/rmnet_data/rmnet_map_data.c b/net/rmnet_data/rmnet_map_data.c
index ad843ce03061..3b3bc20dda87 100644
--- a/net/rmnet_data/rmnet_map_data.c
+++ b/net/rmnet_data/rmnet_map_data.c
@@ -21,6 +21,7 @@
#include <linux/rmnet_data.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
+#include <linux/time.h>
#include <linux/net_map.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
@@ -39,6 +40,12 @@
RMNET_LOG_MODULE(RMNET_DATA_LOGMASK_MAPD);
/* ***************** Local Definitions ************************************** */
+
+long agg_time_limit __read_mostly = 1000000L;
+module_param(agg_time_limit, long, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(agg_time_limit, "Maximum time packets sit in the agg buf");
+
+
struct agg_work {
struct delayed_work work;
struct rmnet_phys_ep_conf_s *config;
@@ -184,6 +191,8 @@ static void rmnet_map_flush_packet_queue(struct work_struct *work)
skb = config->agg_skb;
agg_count = config->agg_count;
config->agg_skb = 0;
+ config->agg_count = 0;
+ memset(&(config->agg_time), 0, sizeof(struct timespec));
}
config->agg_state = RMNET_MAP_AGG_IDLE;
} else {
@@ -216,6 +225,7 @@ void rmnet_map_aggregate(struct sk_buff *skb,
struct agg_work *work;
unsigned long flags;
struct sk_buff *agg_skb;
+ struct timespec t, diff;
int size, rc, agg_count = 0;
@@ -235,6 +245,7 @@ new_packet:
if (!config->agg_skb) {
config->agg_skb = 0;
config->agg_count = 0;
+ memset(&(config->agg_time), 0, sizeof(struct timespec));
spin_unlock_irqrestore(&config->agg_lock, flags);
rmnet_stats_agg_pkts(1);
trace_rmnet_map_aggregate(skb, 0);
@@ -244,20 +255,26 @@ new_packet:
return;
}
config->agg_count = 1;
+ getnstimeofday(&(config->agg_time));
trace_rmnet_start_aggregation(skb);
rmnet_kfree_skb(skb, RMNET_STATS_SKBFREE_AGG_CPY_EXPAND);
goto schedule;
}
+ getnstimeofday(&t);
+ diff = timespec_sub(t, config->agg_time);
- if (skb->len > (config->egress_agg_size - config->agg_skb->len)) {
+ if (skb->len > (config->egress_agg_size - config->agg_skb->len)
+ || (config->agg_count >= config->egress_agg_count)
+ || (diff.tv_sec > 0) || (diff.tv_nsec > agg_time_limit)) {
rmnet_stats_agg_pkts(config->agg_count);
- if (config->agg_count > 1)
- LOGL("Agg count: %d", config->agg_count);
agg_skb = config->agg_skb;
agg_count = config->agg_count;
config->agg_skb = 0;
config->agg_count = 0;
+ memset(&(config->agg_time), 0, sizeof(struct timespec));
spin_unlock_irqrestore(&config->agg_lock, flags);
+ LOGL("delta t: %ld.%09lu\tcount: %d", diff.tv_sec,
+ diff.tv_nsec, agg_count);
trace_rmnet_map_aggregate(skb, agg_count);
rc = dev_queue_xmit(agg_skb);
rmnet_stats_queue_xmit(rc,