tcp: fix SO_RCVLOWAT hangs with fat skbs
authorEric Dumazet <edumazet@google.com>
Tue, 12 May 2020 13:54:30 +0000 (06:54 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 20 May 2020 06:20:10 +0000 (08:20 +0200)
commit23300d6a39d7a1fa3cd6f8421d70e406cf1b85d0
treee4ec04e3385207d060b2275abc3e9dcc476dbe8a
parentcb4f789860659186b55955e5629141612a574aee
tcp: fix SO_RCVLOWAT hangs with fat skbs

[ Upstream commit 24adbc1676af4e134e709ddc7f34cf2adc2131e4 ]

We autotune rcvbuf whenever SO_RCVLOWAT is set to account for 100%
overhead in tcp_set_rcvlowat()

This works well when skb->len/skb->truesize ratio is bigger than 0.5

But if we receive packets with small MSS, we can end up in a situation
where not enough bytes are available in the receive queue to satisfy
RCVLOWAT setting.
As our sk_rcvbuf limit is hit, we send zero windows in ACK packets,
preventing remote peer from sending more data.

Even autotuning does not help, because it only triggers at the time
user process drains the queue. If no EPOLLIN is generated, this
can not happen.

Note poll() has a similar issue, after commit
c7004482e8dc ("tcp: Respect SO_RCVLOWAT in tcp_poll().")

Fixes: 03f45c883c6f ("tcp: avoid extra wakeups for SO_RCVLOWAT users")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: Soheil Hassas Yeganeh <soheil@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
include/net/tcp.h
net/ipv4/tcp.c
net/ipv4/tcp_input.c