[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20210111222411.232916-3-hcaldwel@akamai.com>
Date: Mon, 11 Jan 2021 17:24:09 -0500
From: Heath Caldwell <hcaldwel@...mai.com>
To: <netdev@...r.kernel.org>
CC: Eric Dumazet <edumazet@...gle.com>,
Yuchung Cheng <ycheng@...gle.com>,
Josh Hunt <johunt@...mai.com>, Ji Li <jli@...mai.com>,
Heath Caldwell <hcaldwel@...mai.com>
Subject: [PATCH net-next 2/4] net: tcp: consistently account for overhead for SO_RCVBUF for TCP
When setting SO_RCVBUF for TCP sockets, account for overhead in accord with
sysctl_tcp_adv_win_scale. This makes the receive buffer overhead
accounting for SO_RCVBUF consistent with how it is accounted elsewhere for
TCP sockets.
Signed-off-by: Heath Caldwell <hcaldwel@...mai.com>
---
include/net/tcp.h | 17 +++++++++++++++++
net/core/sock.c | 6 ++++++
2 files changed, 23 insertions(+)
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 78d13c88720f..9961de3fbf09 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1408,6 +1408,23 @@ static inline int tcp_win_from_space(const struct sock *sk, int space)
space - (space>>tcp_adv_win_scale);
}
+/* Calculate the amount of buffer space which would allow for the advertisement
+ * of a window size of win, accounting for overhead.
+ *
+ * This is the inverse of tcp_win_from_space().
+ */
+static inline int tcp_space_from_win(const struct sock *sk, int win)
+{
+ int tcp_adv_win_scale = sock_net(sk)->ipv4.sysctl_tcp_adv_win_scale;
+
+ return tcp_adv_win_scale <= 0 ?
+ win<<(-tcp_adv_win_scale) :
+ /* Division by zero is avoided because the above expression is
+ * used when tcp_adv_win_scale == 0.
+ */
+ (win<<tcp_adv_win_scale) / ((1<<tcp_adv_win_scale) - 1);
+}
+
/* Note: caller must be prepared to deal with negative returns */
static inline int tcp_space(const struct sock *sk)
{
diff --git a/net/core/sock.c b/net/core/sock.c
index 0a9c19f52989..e919f62d5d34 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -783,6 +783,9 @@ EXPORT_SYMBOL(sock_set_keepalive);
*/
static inline int sock_buf_size_to_available(struct sock *sk, int buf_size)
{
+ if (sk->sk_protocol == IPPROTO_TCP)
+ return tcp_win_from_space(sk, buf_size);
+
return buf_size / 2;
}
@@ -792,6 +795,9 @@ static inline int sock_buf_size_to_available(struct sock *sk, int buf_size)
*/
static inline int sock_available_to_buf_size(struct sock *sk, int available)
{
+ if (sk->sk_protocol == IPPROTO_TCP)
+ return tcp_space_from_win(sk, available);
+
return available * 2;
}
--
2.28.0
Powered by blists - more mailing lists