]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: define sbuf pool
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 13 Aug 2024 07:34:28 +0000 (09:34 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 20 Aug 2024 16:12:27 +0000 (18:12 +0200)
Define a new buffer pool reserved to allocate smaller memory area. For
the moment, its usage will be restricted to QUIC, as such it is declared
in quic_stream module.

Add a new config option "tune.bufsize.small" to specify the size of the
allocated objects. A special check ensures that it is not greater than
the default bufsize to avoid unexpected effects.

doc/configuration.txt
include/haproxy/defaults.h
include/haproxy/global-t.h
src/dynbuf.c
src/haproxy.c
src/quic_stream.c

index 58037ebbf4f6ba180400ed7ccf7dbdcb4216d9ca..4307982cd2640d079c9dc25c346c002d9d1f4bfc 100644 (file)
@@ -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 <number>
   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 <number>
+  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 <number>
   Sets the maximum compression level. The compression level affects CPU
   usage during compression. This value affects CPU usage during compression.
index f19db2cebcdc9677af8c84429a6ba59a94ded793..baafe219c01e4ff87f3fa1807f25ce6c4931138a 100644 (file)
 #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
index abafd459738d987ccf27ec3bb0d60d13a36fec40..bdc2d3548699c22a93d078e65d83b7b9f8e6af92 100644 (file)
@@ -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 */
index aec966701b13fe4dd970829b2d7453f9721f2df9..f5ae52ee24bb0c52b9a0cc34213d959ab55a5b42 100644 (file)
@@ -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 }
 }};
 
index a2bd2a446909a286ac5bbdb5b0fc59ef217809bb..daae453350b6e399f780dd027a97553e94f11b06 100644 (file)
@@ -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,
index 131296bd669b5f2e0e7c2f9aabbf0d24049f0ce0..b0ad776ff2d3c27f056f41a6b7e869f7fb5d3e3f 100644 (file)
@@ -5,6 +5,7 @@
 #include <haproxy/api.h>
 #include <haproxy/buf.h>
 #include <haproxy/dynbuf.h>
+#include <haproxy/errors.h>
 #include <haproxy/list.h>
 #include <haproxy/mux_quic.h>
 #include <haproxy/pool.h>
@@ -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 <s> 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);