Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 89098ef4 authored by Harout Hedeshian's avatar Harout Hedeshian
Browse files

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: default avatarHarout Hedeshian <harouth@codeaurora.org>
parent 512860c2
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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);
+20 −3
Original line number Diff line number Diff line
@@ -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,