Skip to content

Commit

Permalink
[erts|kernel] New default values for the 'buffer' option
Browse files Browse the repository at this point in the history
The socket option 'buffer' has new default values; 8192.
The major difference now is that its a unique value for each
type of socket (TCP, UDP and SCTP).
  • Loading branch information
bmk committed Feb 27, 2025
1 parent ba53be4 commit 1870d55
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 17 deletions.
81 changes: 67 additions & 14 deletions erts/emulator/drivers/common/inet_drv.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
* Copyright Ericsson AB 1997-2024. All Rights Reserved.
* Copyright Ericsson AB 1997-2025. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -1032,8 +1032,17 @@ static size_t my_strnlen(const char *s, size_t maxlen)

#define INET_MAX_OPT_BUFFER (64*1024)

#define INET_DEF_BUFFER 1460 /* default buffer size */
#define INET_MIN_BUFFER 1 /* internal min buffer */
#if !defined(INET_BUFFER_TCP_DEFAULT)
#define INET_BUFFER_TCP_DEFAULT 8192
#endif
#if !defined(INET_BUFFER_UDP_DEFAULT)
#define INET_BUFFER_UDP_DEFAULT 8192
#endif
#if !defined(INET_BUFFER_SCTP_DEFAULT)
#define INET_BUFFER_SCTP_DEFAULT 8192
#endif
#define INET_BUFFER_MIN 1
#define INET_UDP_THEORETICAL_MAX_MTU (1 << 16)

#define INET_HIGH_WATERMARK (1024*8) /* 8k pending high => busy */
#define INET_LOW_WATERMARK (1024*4) /* 4k pending => allow more */
Expand Down Expand Up @@ -1877,7 +1886,11 @@ static void end_caller_ref(CallerRef *cref_p) {
#else
# define IS_SCTP(desc) 0
#endif
# define ANC_BUFF_SIZE INET_DEF_BUFFER/2 /* XXX: not very good... */
/*
* Can we "calculate" this dynamically?
* On linux: sysctl net.core.optmem_max
*/
# define ANC_BUFF_SIZE 1024


#ifdef HAVE_UDP
Expand Down Expand Up @@ -6904,7 +6917,7 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len)
("INET-DRV-DBG[%d][" SOCKET_FSTR ",%T] "
"inet_set_opts(buffer) -> %d\r\n",
__LINE__, desc->s, driver_caller(desc->port), ival) );
if (ival < INET_MIN_BUFFER) ival = INET_MIN_BUFFER;
if (ival < INET_BUFFER_MIN) ival = INET_BUFFER_MIN;
desc->bufsz = ival;
desc->flags |= INET_FLG_BUFFER_SET;
continue;
Expand Down Expand Up @@ -7268,14 +7281,39 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len)
"inet_set_opts(rcvbuf) -> %d\r\n",
__LINE__, desc->s, driver_caller(desc->port), ival) );
if (!(desc->flags & INET_FLG_BUFFER_SET)) {
/* make sure we have desc->bufsz >= SO_RCVBUF */
if (ival > (1 << 16) && desc->stype == SOCK_DGRAM && !IS_SCTP(desc))

/* BUFFER has not previously been explicitly set.
* Make sure we have desc->bufsz >= SO_RCVBUF,
* except if rcvbuf is larger than max when type = DGRAM.
*/

if ((ival > INET_UDP_THEORETICAL_MAX_MTU) &&
(desc->stype == SOCK_DGRAM) &&
!IS_SCTP(desc)) {

/* For UDP we don't want to automatically
set the buffer size to be larger than
the theoretical max MTU */
desc->bufsz = 1 << 16;
else if (ival > desc->bufsz)
* set the buffer size to be larger than
* the theoretical max MTU. */

DDBG(desc,
("INET-DRV-DBG[%d][" SOCKET_FSTR ",%T] "
"inet_set_opts(rcvbuf) -> "
"force update of 'buffer' to max-mtu (%d)\r\n",
__LINE__, desc->s, driver_caller(desc->port),
INET_UDP_THEORETICAL_MAX_MTU) );

desc->bufsz = INET_UDP_THEORETICAL_MAX_MTU;

} else if (ival > desc->bufsz) {

DDBG(desc,
("INET-DRV-DBG[%d][" SOCKET_FSTR ",%T] "
"inet_set_opts(rcvbuf) -> "
"force update of 'buffer'\r\n",
__LINE__, desc->s, driver_caller(desc->port)) );

desc->bufsz = ival;
}
}
break;

Expand Down Expand Up @@ -7999,8 +8037,8 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len)

desc->bufsz = ival;

if (desc->bufsz < INET_MIN_BUFFER)
desc->bufsz = INET_MIN_BUFFER;
if (desc->bufsz < INET_BUFFER_MIN)
desc->bufsz = INET_BUFFER_MIN;
desc->flags |= INET_FLG_BUFFER_SET;
res = 0; /* This does not affect the kernel buffer size */
}
Expand Down Expand Up @@ -9024,6 +9062,10 @@ static ErlDrvSSizeT inet_fill_opts(inet_descriptor* desc,

switch(opt) {
case INET_LOPT_BUFFER:
DDBG(desc,
("INET-DRV-DBG[%d][" SOCKET_FSTR ",%T] "
"inet_fill_opts -> buffer: %d\r\n",
__LINE__, desc->s, driver_caller(desc->port), desc->bufsz) );
*ptr++ = opt;
put_int32(desc->bufsz, ptr);
continue;
Expand Down Expand Up @@ -10749,7 +10791,18 @@ static ErlDrvData inet_start(ErlDrvPort port, int size, int protocol)
desc->dport = driver_mk_port(port);
desc->state = INET_STATE_CLOSED;
desc->prebound = 0;
desc->bufsz = INET_DEF_BUFFER;

if (protocol == IPPROTO_TCP)
desc->bufsz = INET_BUFFER_TCP_DEFAULT;
else if (protocol == IPPROTO_UDP)
desc->bufsz = INET_BUFFER_UDP_DEFAULT;
#if defined(HAVE_SCTP)
else if (protocol == IPPROTO_SCTP)
desc->bufsz = INET_BUFFER_SCTP_DEFAULT;
#endif
else /* We only support tcp, udp and SCTP so this "should not" happen... */
desc->bufsz = 9999;

desc->hsz = 0; /* list header size */
desc->htype = TCP_PB_RAW; /* default packet type */
desc->psize = 0; /* no size check */
Expand Down
6 changes: 3 additions & 3 deletions lib/kernel/src/inet_udp.erl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 1997-2024. All Rights Reserved.
%% Copyright Ericsson AB 1997-2025. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -32,7 +32,7 @@
-define(FAMILY, inet).
-define(PROTO, udp).
-define(TYPE, dgram).
-define(RECBUF, (8*1024)).
-define(RECBUF, (8*1024)). % No longer needed when opening a *new* socket


%% inet_udp port lookup
Expand All @@ -52,7 +52,7 @@ open(Port) -> open(Port, []).
-spec open(_, _) -> {ok, port()} | {error, atom()}.
open(Port, Opts) ->
case inet:udp_options(
[{port,Port}, {recbuf, ?RECBUF} | Opts],
[{port,Port} | Opts],
?MODULE) of
{error, Reason} -> exit(Reason);
{ok,
Expand Down

0 comments on commit 1870d55

Please sign in to comment.