[PATCH net-next] net: set net.core.rmem_max and net.core.wmem_max to 4 MB

Eric Dumazet
2025-08-19T17:40:33Z

SO_RCVBUF and SO_SNDBUF have limited range today, unless
distros or system admins change rmem_max and wmem_max.

Even iproute2 uses 1 MB SO_RCVBUF which is capped by
the kernel.

Decouple [rw]mem_max and [rw]mem_default and increase
[rw]mem_max to 4 MB.

Before:

$ sysctl net.core.rmem_default net.core.rmem_max net.core.wmem_default net.core.wmem_max
net.core.rmem_default = 212992
net.core.rmem_max = 212992
net.core.wmem_default = 212992
net.core.wmem_max = 212992

After:

$ sysctl net.core.rmem_default net.core.rmem_max net.core.wmem_default net.core.wmem_max
net.core.rmem_default = 212992
net.core.rmem_max = 4194304
net.core.wmem_default = 212992
net.core.wmem_max = 4194304

Signed-off-by: Eric Dumazet <edumazet@google.com>
---
Documentation/admin-guide/sysctl/net.rst | 4 ++++
Documentation/networking/ip-sysctl.rst | 6 +++---
include/net/sock.h | 4 ++--
net/core/sock.c | 8 ++++----
net/ipv4/arp.c | 2 +-
net/ipv6/ndisc.c | 2 +-
6 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/Documentation/admin-guide/sysctl/net.rst b/Documentation/admin-guide/sysctl/net.rst
index 7b0c4291c6861e5694c36f89ddbb19d0397e4190..2ef50828aff16b01baf32f5ded9b75a6e699b184 100644
--- a/Documentation/admin-guide/sysctl/net.rst
+++ b/Documentation/admin-guide/sysctl/net.rst
@@ -222,6 +222,8 @@ rmem_max

The maximum receive socket buffer size in bytes.

+Default: 4194304
+
rps_default_mask
----------------

@@ -247,6 +249,8 @@ wmem_max

The maximum send socket buffer size in bytes.

+Default: 4194304
+
message_burst and message_cost
------------------------------

diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst
index 9756d16e3df1400626ce24726feceaeefa5da523..cb0fce8512bfa3ed6c61654787eca1b2bd9312d8 100644
--- a/Documentation/networking/ip-sysctl.rst
+++ b/Documentation/networking/ip-sysctl.rst
@@ -209,7 +209,7 @@ neigh/default/unres_qlen_bytes - INTEGER

Setting negative value is meaningless and will return error.

- Default: SK_WMEM_MAX, (same as net.core.wmem_default).
+ Default: SK_WMEM_DEFAULT, (same as net.core.wmem_default).

Exact value depends on architecture and kernel options,
but should be enough to allow queuing 256 packets
@@ -805,8 +805,8 @@ tcp_rmem - vector of 3 INTEGERs: min, default, max
This value results in initial window of 65535.

max: maximal size of receive buffer allowed for automatically
- selected receiver buffers for TCP socket. This value does not override
- net.core.rmem_max. Calling setsockopt() with SO_RCVBUF disables
+ selected receiver buffers for TCP socket.
+ Calling setsockopt() with SO_RCVBUF disables
automatic tuning of that socket's receive buffer size, in which
case this value is ignored.
Default: between 131072 and 32MB, depending on RAM size.
diff --git a/include/net/sock.h b/include/net/sock.h
index c8a4b283df6fc4b931270502ddbb5df7ae1e4aa2..4a9169a8d92493db64315b09c2fc105a6d55966d 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -2924,8 +2924,8 @@ void sk_get_meminfo(const struct sock *sk, u32 *meminfo);
*/
#define _SK_MEM_PACKETS 256
#define _SK_MEM_OVERHEAD SKB_TRUESIZE(256)
-#define SK_WMEM_MAX (_SK_MEM_OVERHEAD * _SK_MEM_PACKETS)
-#define SK_RMEM_MAX (_SK_MEM_OVERHEAD * _SK_MEM_PACKETS)
+#define SK_WMEM_DEFAULT (_SK_MEM_OVERHEAD * _SK_MEM_PACKETS)
+#define SK_RMEM_DEFAULT (_SK_MEM_OVERHEAD * _SK_MEM_PACKETS)

extern __u32 sysctl_wmem_max;
extern __u32 sysctl_rmem_max;
diff --git a/net/core/sock.c b/net/core/sock.c
index 7c26ec8dce630f0d24a622a418c15e6594d1babb..66c65f4a03f38850b9f42e82188a9df1c3485ce1 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -281,12 +281,12 @@ static struct lock_class_key af_elock_keys[AF_MAX];
static struct lock_class_key af_kern_callback_keys[AF_MAX];

/* Run time adjustable parameters. */
-__u32 sysctl_wmem_max __read_mostly = SK_WMEM_MAX;
+__u32 sysctl_wmem_max __read_mostly = 4 << 20;
EXPORT_SYMBOL(sysctl_wmem_max);
-__u32 sysctl_rmem_max __read_mostly = SK_RMEM_MAX;
+__u32 sysctl_rmem_max __read_mostly = 4 << 20;
EXPORT_SYMBOL(sysctl_rmem_max);
-__u32 sysctl_wmem_default __read_mostly = SK_WMEM_MAX;
-__u32 sysctl_rmem_default __read_mostly = SK_RMEM_MAX;
+__u32 sysctl_wmem_default __read_mostly = SK_WMEM_DEFAULT;
+__u32 sysctl_rmem_default __read_mostly = SK_RMEM_DEFAULT;

DEFINE_STATIC_KEY_FALSE(memalloc_socks_key);
EXPORT_SYMBOL_GPL(memalloc_socks_key);
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 5cfc1c9396732171b79ce0aac2b0ee11ddfcbd05..833f2cf97178ee6a50fb3c99d02ed5b17ab5a879 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -170,7 +170,7 @@ struct neigh_table arp_tbl = {
[NEIGH_VAR_DELAY_PROBE_TIME] = 5 * HZ,
[NEIGH_VAR_INTERVAL_PROBE_TIME_MS] = 5 * HZ,
[NEIGH_VAR_GC_STALETIME] = 60 * HZ,
- [NEIGH_VAR_QUEUE_LEN_BYTES] = SK_WMEM_MAX,
+ [NEIGH_VAR_QUEUE_LEN_BYTES] = SK_WMEM_DEFAULT,
[NEIGH_VAR_PROXY_QLEN] = 64,
[NEIGH_VAR_ANYCAST_DELAY] = 1 * HZ,
[NEIGH_VAR_PROXY_DELAY] = (8 * HZ) / 10,
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 7d5abb3158ec9640a45d4f36fbbfdfce070c0dd0..57aaa7ae8ac3109d808dd46e8cfe54b57e48b214 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -130,7 +130,7 @@ struct neigh_table nd_tbl = {
[NEIGH_VAR_DELAY_PROBE_TIME] = 5 * HZ,
[NEIGH_VAR_INTERVAL_PROBE_TIME_MS] = 5 * HZ,
[NEIGH_VAR_GC_STALETIME] = 60 * HZ,
- [NEIGH_VAR_QUEUE_LEN_BYTES] = SK_WMEM_MAX,
+ [NEIGH_VAR_QUEUE_LEN_BYTES] = SK_WMEM_DEFAULT,
[NEIGH_VAR_PROXY_QLEN] = 64,
[NEIGH_VAR_ANYCAST_DELAY] = 1 * HZ,
[NEIGH_VAR_PROXY_DELAY] = (8 * HZ) / 10,
--
2.51.0.rc1.193.gad69d77794-goog