diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2018-09-07 19:04:01 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2018-09-07 19:04:01 +0000 |
commit | f4f88270955c2fc5aa470b8174333ddeb1cabb66 (patch) | |
tree | 313ee7a92721b989d17ab936de376fc95d1df4ad | |
parent | e4d1ce4f4533d105ee47ceeb1564f70da04a6a6a (diff) | |
parent | 83c65cd436718667e87e61d235f88c073ffd20f7 (diff) | |
download | v4.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.c | 19 |
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, |