diff --git a/doc/configuration.txt b/doc/configuration.txt index 58037ebbf..4307982cd 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -1460,6 +1460,7 @@ The following keywords are supported in the "global" section : - tune.buffers.limit - tune.buffers.reserve - tune.bufsize + - tune.bufsize.small - tune.comp.maxlevel - tune.disable-fast-forward - tune.disable-zero-copy-forwarding @@ -3340,6 +3341,17 @@ tune.bufsize value set using this parameter will automatically be rounded up to the next multiple of 8 on 32-bit machines and 16 on 64-bit machines. +tune.bufsize.small + Sets the size in bytes for small buffers. The defaults value is 1024. + + These buffers are designed to be used in some specific contexts where memory + consumption is restrained but it seems unnecessary to allocate a full buffer. + If however a small buffer is not sufficient, a reallocation is automatically + done to switch to a standard size buffer. + + For the moment, it is used only by HTTP/3 protocol to emit the response + headers. + tune.comp.maxlevel Sets the maximum compression level. The compression level affects CPU usage during compression. This value affects CPU usage during compression. diff --git a/include/haproxy/defaults.h b/include/haproxy/defaults.h index f19db2ceb..baafe219c 100644 --- a/include/haproxy/defaults.h +++ b/include/haproxy/defaults.h @@ -71,6 +71,10 @@ #define BUFSIZE 16384 #endif +#ifndef BUFSIZE_SMALL +#define BUFSIZE_SMALL 1024 +#endif + // number of per-thread emergency buffers for low-memory conditions #ifndef RESERVED_BUFS #define RESERVED_BUFS 4 diff --git a/include/haproxy/global-t.h b/include/haproxy/global-t.h index abafd4597..bdc2d3548 100644 --- a/include/haproxy/global-t.h +++ b/include/haproxy/global-t.h @@ -165,6 +165,7 @@ struct global { int runqueue_depth;/* max number of tasks to run at once */ int recv_enough; /* how many input bytes at once are "enough" */ int bufsize; /* buffer size in bytes, defaults to BUFSIZE */ + int bufsize_small; /* small buffer size in bytes */ int maxrewrite; /* buffer max rewrite size in bytes, defaults to MAXREWRITE */ int reserved_bufs; /* how many buffers can only be allocated for response */ int buf_limit; /* if not null, how many total buffers may only be allocated */ diff --git a/src/dynbuf.c b/src/dynbuf.c index aec966701..f5ae52ee2 100644 --- a/src/dynbuf.c +++ b/src/dynbuf.c @@ -188,6 +188,34 @@ static int cfg_parse_tune_buffers_reserve(char **args, int section_type, struct return 0; } +/* config parse for global "tune.bufsize.small" */ +static int cfg_parse_tune_bufsize_small(char **args, int section_type, + struct proxy *curpx, const struct proxy *defpx, + const char *file, int line, char **err) +{ + int size; + + if (too_many_args(1, args, err, NULL)) + goto err; + + if (*(args[1]) == 0) { + memprintf(err, "'%s' expects an integer argument.\n", args[0]); + goto err; + } + + size = atol(args[1]); + if (size <= 0) { + memprintf(err, "'%s' expects a positive integer argument.\n", args[0]); + goto err; + } + + global.tune.bufsize_small = size; + return 0; + + err: + return -1; +} + /* allocate emergency buffers for the thread */ static int alloc_emergency_buffers_per_thread(void) { @@ -227,6 +255,7 @@ static void free_emergency_buffers_per_thread(void) static struct cfg_kw_list cfg_kws = {ILH, { { CFG_GLOBAL, "tune.buffers.limit", cfg_parse_tune_buffers_limit }, { CFG_GLOBAL, "tune.buffers.reserve", cfg_parse_tune_buffers_reserve }, + { CFG_GLOBAL, "tune.bufsize.small", cfg_parse_tune_bufsize_small }, { 0, NULL, NULL } }}; diff --git a/src/haproxy.c b/src/haproxy.c index a2bd2a446..daae45335 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -179,6 +179,7 @@ struct global global = { .tune = { .options = GTUNE_LISTENER_MQ_OPT, .bufsize = (BUFSIZE + 2*sizeof(void *) - 1) & -(2*sizeof(void *)), + .bufsize_small = BUFSIZE_SMALL, .maxrewrite = MAXREWRITE, .reserved_bufs = RESERVED_BUFS, .pattern_cache = DEFAULT_PAT_LRU_SIZE, diff --git a/src/quic_stream.c b/src/quic_stream.c index 131296bd6..b0ad776ff 100644 --- a/src/quic_stream.c +++ b/src/quic_stream.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -16,6 +17,7 @@ DECLARE_STATIC_POOL(pool_head_quic_stream_desc, "qc_stream_desc", DECLARE_STATIC_POOL(pool_head_quic_stream_buf, "qc_stream_buf", sizeof(struct qc_stream_buf)); +static struct pool_head *pool_head_sbuf; /* Returns true if nothing to ack yet for stream including FIN bit. */ static inline int qc_stream_desc_done(const struct qc_stream_desc *s) @@ -300,3 +302,23 @@ void qc_stream_buf_release(struct qc_stream_desc *stream) stream->buf = NULL; stream->buf_offset = 0; } + +static int create_sbuf_pool(void) +{ + if (global.tune.bufsize_small > global.tune.bufsize) { + ha_warning("invalid small buffer size %d bytes which is greater to default bufsize %d bytes.\n", + global.tune.bufsize_small, global.tune.bufsize); + return ERR_FATAL|ERR_ABORT; + } + + pool_head_sbuf = create_pool("sbuf", global.tune.bufsize_small, + MEM_F_SHARED|MEM_F_EXACT); + if (!pool_head_sbuf) { + ha_warning("error on small buffer pool allocation.\n"); + return ERR_FATAL|ERR_ABORT; + } + + return ERR_NONE; +} + +REGISTER_POST_CHECK(create_sbuf_pool);