net: rmnet_data: Skip UL aggregation for ping packets
ICMP packets could be potentially stuck behind aggregated traffic if UL aggregation is enabled on rmnet_data. This results in increased latencies during ping tests as the workqueues for these packets are scheduled at non deterministic times. CRs-Fixed: 2131879 Change-Id: I19208301b5674749aa2f1dee65a9226eda364c85 Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
This commit is contained in:
parent
e73251670e
commit
bf783bade0
3 changed files with 35 additions and 10 deletions
|
|
@ -597,6 +597,9 @@ static int rmnet_map_egress_handler(struct sk_buff *skb,
|
|||
|
||||
if ((config->egress_data_format & RMNET_EGRESS_FORMAT_AGGREGATION) &&
|
||||
!non_linear_skb) {
|
||||
if (rmnet_ul_aggregation_skip(skb, required_headroom))
|
||||
return RMNET_MAP_SUCCESS;
|
||||
|
||||
rmnet_map_aggregate(skb, config);
|
||||
return RMNET_MAP_CONSUMED;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
|
@ -146,5 +146,5 @@ int rmnet_map_checksum_downlink_packet(struct sk_buff *skb);
|
|||
int rmnet_map_checksum_uplink_packet(struct sk_buff *skb,
|
||||
struct net_device *orig_dev,
|
||||
u32 egress_data_format);
|
||||
|
||||
int rmnet_ul_aggregation_skip(struct sk_buff *skb, int offset);
|
||||
#endif /* _RMNET_MAP_H_ */
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
|
@ -234,16 +234,9 @@ void rmnet_map_aggregate(struct sk_buff *skb,
|
|||
|
||||
if (!skb || !config)
|
||||
return;
|
||||
size = config->egress_agg_size - skb->len;
|
||||
|
||||
if (size < 2000) {
|
||||
LOGL("Invalid length %d", size);
|
||||
return;
|
||||
}
|
||||
|
||||
new_packet:
|
||||
spin_lock_irqsave(&config->agg_lock, flags);
|
||||
|
||||
memcpy(&last, &config->agg_last, sizeof(struct timespec));
|
||||
getnstimeofday(&config->agg_last);
|
||||
|
||||
|
|
@ -265,6 +258,7 @@ new_packet:
|
|||
return;
|
||||
}
|
||||
|
||||
size = config->egress_agg_size - skb->len;
|
||||
config->agg_skb = skb_copy_expand(skb, 0, size, GFP_ATOMIC);
|
||||
if (!config->agg_skb) {
|
||||
config->agg_skb = 0;
|
||||
|
|
@ -748,3 +742,31 @@ sw_checksum:
|
|||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rmnet_ul_aggregation_skip(struct sk_buff *skb, int offset)
|
||||
{
|
||||
unsigned char *packet_start = skb->data + offset;
|
||||
int is_icmp = 0;
|
||||
|
||||
if ((skb->data[offset]) >> 4 == 0x04) {
|
||||
struct iphdr *ip4h = (struct iphdr *)(packet_start);
|
||||
|
||||
if (ip4h->protocol == IPPROTO_ICMP)
|
||||
is_icmp = 1;
|
||||
} else {
|
||||
struct ipv6hdr *ip6h = (struct ipv6hdr *)(packet_start);
|
||||
|
||||
if (ip6h->nexthdr == NEXTHDR_FRAGMENT) {
|
||||
struct frag_hdr *frag;
|
||||
|
||||
frag = (struct frag_hdr *)(packet_start
|
||||
+ sizeof(struct ipv6hdr));
|
||||
if (frag->nexthdr == IPPROTO_ICMPV6)
|
||||
is_icmp = 1;
|
||||
} else if (ip6h->nexthdr == IPPROTO_ICMPV6) {
|
||||
is_icmp = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return is_icmp;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue