diff options
author | Daniel Borkmann <dborkman@redhat.com> | 2013-06-19 06:51:20 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-06-20 00:16:53 -0400 |
commit | eea86af6b1e18d6fa8dc959e3ddc0100f27aff9f (patch) | |
tree | a8f200392d1671a058311009aa360226c22b5da8 | |
parent | dc25c676f54addb10e598daa9da9b8dd4fd487ab (diff) |
net: sock: adapt SOCK_MIN_RCVBUF and SOCK_MIN_SNDBUF
The current situation is that SOCK_MIN_RCVBUF is 2048 + sizeof(struct sk_buff))
while SOCK_MIN_SNDBUF is 2048. Since in both cases, skb->truesize is used for
sk_{r,w}mem_alloc accounting, we should have both sizes adjusted via defining a
TCP_SKB_MIN_TRUESIZE.
Further, as Eric Dumazet points out, the minimal skb truesize in transmit path is
SKB_TRUESIZE(2048) after commit f07d960df33c5 ("tcp: avoid frag allocation for
small frames"), and tcp_sendmsg() tries to limit skb size to half the congestion
window, meaning we try to build two skbs at minimum. Thus, having SOCK_MIN_SNDBUF
as 2048 can hit a small regression for some applications setting to low
SO_SNDBUF / SO_RCVBUF. Note that we define a TCP_SKB_MIN_TRUESIZE, because
SKB_TRUESIZE(2048) adds SKB_DATA_ALIGN(sizeof(struct skb_shared_info)), but in
case of TCP skbs, the skb_shared_info is part of the 2048 bytes allocation for
skb->head.
The minor adaption in sk_stream_moderate_sndbuf() is to silence a warning by
using a typed max macro, as similarly done in SOCK_MIN_RCVBUF occurences, that
would appear otherwise.
Suggested-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/sock.h | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/include/net/sock.h b/include/net/sock.h index 21db792bffa5..ea6206ccc896 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -2047,18 +2047,21 @@ static inline void sk_wake_async(struct sock *sk, int how, int band) | |||
2047 | sock_wake_async(sk->sk_socket, how, band); | 2047 | sock_wake_async(sk->sk_socket, how, band); |
2048 | } | 2048 | } |
2049 | 2049 | ||
2050 | #define SOCK_MIN_SNDBUF 2048 | 2050 | /* Since sk_{r,w}mem_alloc sums skb->truesize, even a small frame might |
2051 | /* | 2051 | * need sizeof(sk_buff) + MTU + padding, unless net driver perform copybreak. |
2052 | * Since sk_rmem_alloc sums skb->truesize, even a small frame might need | 2052 | * Note: for send buffers, TCP works better if we can build two skbs at |
2053 | * sizeof(sk_buff) + MTU + padding, unless net driver perform copybreak | 2053 | * minimum. |
2054 | */ | 2054 | */ |
2055 | #define SOCK_MIN_RCVBUF (2048 + sizeof(struct sk_buff)) | 2055 | #define TCP_SKB_MIN_TRUESIZE (2048 + sizeof(struct sk_buff)) |
2056 | |||
2057 | #define SOCK_MIN_SNDBUF (TCP_SKB_MIN_TRUESIZE * 2) | ||
2058 | #define SOCK_MIN_RCVBUF TCP_SKB_MIN_TRUESIZE | ||
2056 | 2059 | ||
2057 | static inline void sk_stream_moderate_sndbuf(struct sock *sk) | 2060 | static inline void sk_stream_moderate_sndbuf(struct sock *sk) |
2058 | { | 2061 | { |
2059 | if (!(sk->sk_userlocks & SOCK_SNDBUF_LOCK)) { | 2062 | if (!(sk->sk_userlocks & SOCK_SNDBUF_LOCK)) { |
2060 | sk->sk_sndbuf = min(sk->sk_sndbuf, sk->sk_wmem_queued >> 1); | 2063 | sk->sk_sndbuf = min(sk->sk_sndbuf, sk->sk_wmem_queued >> 1); |
2061 | sk->sk_sndbuf = max(sk->sk_sndbuf, SOCK_MIN_SNDBUF); | 2064 | sk->sk_sndbuf = max_t(u32, sk->sk_sndbuf, SOCK_MIN_SNDBUF); |
2062 | } | 2065 | } |
2063 | } | 2066 | } |
2064 | 2067 | ||