aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp.c
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2018-04-16 13:33:35 -0400
committerDavid S. Miller <davem@davemloft.net>2018-04-16 18:26:37 -0400
commitd1361840f8c519eaee9a78ffe09e4f0a1b586846 (patch)
tree86a904ade99a93544e0817cda7dc842b12f9b833 /net/ipv4/tcp.c
parent10b19aeac1700c3ba94fb50583a766d9cdaf1e9e (diff)
tcp: fix SO_RCVLOWAT and RCVBUF autotuning
Applications might use SO_RCVLOWAT on TCP socket hoping to receive one [E]POLLIN event only when a given amount of bytes are ready in socket receive queue. Problem is that receive autotuning is not aware of this constraint, meaning sk_rcvbuf might be too small to allow all bytes to be stored. Add a new (struct proto_ops)->set_rcvlowat method so that a protocol can override the default setsockopt(SO_RCVLOWAT) behavior. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp.c')
-rw-r--r--net/ipv4/tcp.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index bccc4c270087..0abd8d1d3d1d 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1701,6 +1701,27 @@ int tcp_peek_len(struct socket *sock)
1701} 1701}
1702EXPORT_SYMBOL(tcp_peek_len); 1702EXPORT_SYMBOL(tcp_peek_len);
1703 1703
1704/* Make sure sk_rcvbuf is big enough to satisfy SO_RCVLOWAT hint */
1705int tcp_set_rcvlowat(struct sock *sk, int val)
1706{
1707 sk->sk_rcvlowat = val ? : 1;
1708 if (sk->sk_userlocks & SOCK_RCVBUF_LOCK)
1709 return 0;
1710
1711 /* val comes from user space and might be close to INT_MAX */
1712 val <<= 1;
1713 if (val < 0)
1714 val = INT_MAX;
1715
1716 val = min(val, sock_net(sk)->ipv4.sysctl_tcp_rmem[2]);
1717 if (val > sk->sk_rcvbuf) {
1718 sk->sk_rcvbuf = val;
1719 tcp_sk(sk)->window_clamp = tcp_win_from_space(sk, val);
1720 }
1721 return 0;
1722}
1723EXPORT_SYMBOL(tcp_set_rcvlowat);
1724
1704static void tcp_update_recv_tstamps(struct sk_buff *skb, 1725static void tcp_update_recv_tstamps(struct sk_buff *skb,
1705 struct scm_timestamping *tss) 1726 struct scm_timestamping *tss)
1706{ 1727{