aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2018-09-07 19:04:01 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2018-09-07 19:04:01 +0000
commitf4f88270955c2fc5aa470b8174333ddeb1cabb66 (patch)
tree313ee7a92721b989d17ab936de376fc95d1df4ad
parente4d1ce4f4533d105ee47ceeb1564f70da04a6a6a (diff)
parent83c65cd436718667e87e61d235f88c073ffd20f7 (diff)
downloadv4.4-oreo-mr1-1.2-iot-release.tar.gz
Snap for 4998801 from 83c65cd436718667e87e61d235f88c073ffd20f7 to oc-mr1-1.2-iot-releaseandroid-o-mr1-iot-release-smart-display-r4android-o-mr1-iot-release-smart-display-r3oreo-mr1-1.2-iot-release
Change-Id: I13ce6e6e0f0aaee7f0b5d1f4e5894630bb47fd4b
-rw-r--r--net/ipv4/tcp_input.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index b6d99c308bef..c5fa41a8d1cd 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4780,6 +4780,7 @@ restart:
static void tcp_collapse_ofo_queue(struct sock *sk)
{
struct tcp_sock *tp = tcp_sk(sk);
+ u32 range_truesize, sum_tiny = 0;
struct sk_buff *skb = skb_peek(&tp->out_of_order_queue);
struct sk_buff *head;
u32 start, end;
@@ -4789,6 +4790,7 @@ static void tcp_collapse_ofo_queue(struct sock *sk)
start = TCP_SKB_CB(skb)->seq;
end = TCP_SKB_CB(skb)->end_seq;
+ range_truesize = skb->truesize;
head = skb;
for (;;) {
@@ -4803,14 +4805,24 @@ static void tcp_collapse_ofo_queue(struct sock *sk)
if (!skb ||
after(TCP_SKB_CB(skb)->seq, end) ||
before(TCP_SKB_CB(skb)->end_seq, start)) {
- tcp_collapse(sk, &tp->out_of_order_queue,
- head, skb, start, end);
+ /* Do not attempt collapsing tiny skbs */
+ if (range_truesize != head->truesize ||
+ end - start >= SKB_WITH_OVERHEAD(SK_MEM_QUANTUM)) {
+ tcp_collapse(sk, &tp->out_of_order_queue,
+ head, skb, start, end);
+ } else {
+ sum_tiny += range_truesize;
+ if (sum_tiny > sk->sk_rcvbuf >> 3)
+ return;
+ }
+
head = skb;
if (!skb)
break;
/* Start new segment */
start = TCP_SKB_CB(skb)->seq;
end = TCP_SKB_CB(skb)->end_seq;
+ range_truesize = skb->truesize;
} else {
if (before(TCP_SKB_CB(skb)->seq, start))
start = TCP_SKB_CB(skb)->seq;
@@ -4866,6 +4878,9 @@ static int tcp_prune_queue(struct sock *sk)
else if (tcp_under_memory_pressure(sk))
tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U * tp->advmss);
+ if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf)
+ return 0;
+
tcp_collapse_ofo_queue(sk);
if (!skb_queue_empty(&sk->sk_receive_queue))
tcp_collapse(sk, &sk->sk_receive_queue,