From d248c5bd216327282a79f1d3046f04ba3e35ea63 Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Tue, 5 Aug 2025 11:12:17 +0200 Subject: [PATCH] MINOR: quic: rename max Tx mem setting QUIC global memory can be limited across the entire process via a global tune setting. Previously, this setting used to misleading "frontend" prefix. As this is applied as a sum between all QUIC connections, both from frontend and backend sides, remove the prefix. The new option name is "tune.quic.mem.tx-max". The older option name is deprecated and will be removed in 3.5. --- doc/configuration.txt | 24 ++++++++++++------- include/haproxy/global-t.h | 1 - include/haproxy/quic_tune-t.h | 1 + src/cfgparse-quic.c | 45 ++++++++++++++++++++++++----------- src/haproxy.c | 1 - src/quic_cc.c | 9 +++---- 6 files changed, 52 insertions(+), 29 deletions(-) diff --git a/doc/configuration.txt b/doc/configuration.txt index 7edb9d2e3..682cb0a56 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -1909,11 +1909,12 @@ The following keywords are supported in the "global" section : - tune.quic.frontend.max-data-size - tune.quic.frontend.max-idle-timeout - tune.quic.frontend.max-streams-bidi - - tune.quic.frontend.max-tx-mem + - tune.quic.frontend.max-tx-mem (deprecated) - tune.quic.frontend.stream-data-ratio - tune.quic.frontend.default-max-window-size - tune.quic.listen - tune.quic.max-frame-loss (deprecated) + - tune.quic.mem.tx-max - tune.quic.reorder-ratio (deprecated) - tune.quic.retry-threshold - tune.quic.socket-owner @@ -4849,14 +4850,6 @@ tune.quic.frontend.max-streams-bidi See also: "tune.quic.frontend.max-data-size", "tune.quic.frontend.stream-data-ratio" -tune.quic.frontend.max-tx-mem - Sets the maximum amount of memory usable by QUIC stack at the transport layer - for emission. This serves both as a limit of in flight bytes and multiplexer - output buffers. Note that to prevent threads contention this limit is not - strictly enforced so it can be exceeded on some occasions. Also, each - connection will always be able to use a window of at least 2 datagrams, so a - proper maxconn should be used in conjunction. - tune.quic.frontend.stream-data-ratio <0..100, in percent> This setting allows to configure the hard limit of the number of data bytes in flight over each stream. It is expressed as a percentage relative to @@ -4900,6 +4893,19 @@ tune.quic.listen { on | off } See also "quic_enabled" sample fetch. +tune.quic.mem.tx-max + Sets the maximum amount of memory usable by QUIC stack at the transport layer + for emission. This serves both as a limit of in flight bytes and multiplexer + output buffers. Note that to prevent threads contention this limit is not + strictly enforced so it can be exceeded on some occasions. Also, each + connection will always be able to use a window of at least 2 datagrams, so a + proper maxconn should be used in conjunction. + +tune.quic.frontend.max-tx-mem (deprecated) + This keyword has been deprecated in 3.3 and will be removed in 3.5. It is + part of the streamlining process apply on QUIC configuration. If used, this + setting will only be applied on frontend connections. + tune.quic.retry-threshold Dynamically enables the Retry feature for all the configured QUIC listeners as soon as this number of half open connections is reached. A half open diff --git a/include/haproxy/global-t.h b/include/haproxy/global-t.h index 53293103a..d0a817023 100644 --- a/include/haproxy/global-t.h +++ b/include/haproxy/global-t.h @@ -219,7 +219,6 @@ struct global { unsigned int quic_frontend_max_idle_timeout; unsigned int quic_frontend_max_data; unsigned int quic_frontend_max_streams_bidi; - uint64_t quic_frontend_max_tx_mem; size_t quic_frontend_max_window_size; unsigned int quic_frontend_stream_data_ratio; unsigned int quic_retry_threshold; diff --git a/include/haproxy/quic_tune-t.h b/include/haproxy/quic_tune-t.h index cb84bf7ac..a12902e1c 100644 --- a/include/haproxy/quic_tune-t.h +++ b/include/haproxy/quic_tune-t.h @@ -39,6 +39,7 @@ struct quic_tune { uint fb_opts; /* QUIC_TUNE_FB_* options shared by both side */ } be; + uint64_t mem_tx_max; uint options; }; diff --git a/src/cfgparse-quic.c b/src/cfgparse-quic.c index 143483434..ccfe0aae0 100644 --- a/src/cfgparse-quic.c +++ b/src/cfgparse-quic.c @@ -34,6 +34,7 @@ struct quic_tune quic_tune = { .cc_reorder_ratio = QUIC_DFLT_CC_REORDER_RATIO, .fb_opts = QUIC_TUNE_FB_TX_PACING|QUIC_TUNE_FB_TX_UDP_GSO, }, + .mem_tx_max = QUIC_MAX_TX_MEM, }; static int bind_parse_quic_force_retry(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err) @@ -309,8 +310,19 @@ static int cfg_parse_quic_tune_setting(char **args, int section_type, } suffix = args[0] + prefix_len; - if (strcmp(suffix, "be.cc.cubic-min-losses") == 0 || - strcmp(suffix, "fe.cc.cubic-min-losses") == 0) { + if (strcmp(suffix, "mem.tx-max") == 0) { + ullong mem_max; + + if ((errptr = parse_size_err(args[1], &mem_max))) { + memprintf(err, "'%s': unexpected character '%c' in size argument '%s'.", + args[0], *errptr, args[1]); + return -1; + } + + quic_tune.mem_tx_max = mem_max; + } + else if (strcmp(suffix, "be.cc.cubic-min-losses") == 0 || + strcmp(suffix, "fe.cc.cubic-min-losses") == 0) { uint *ptr = (suffix[0] == 'b') ? &quic_tune.be.cc_cubic_min_losses : &quic_tune.fe.cc_cubic_min_losses; *ptr = arg - 1; @@ -344,17 +356,6 @@ static int cfg_parse_quic_tune_setting(char **args, int section_type, } else if (strcmp(suffix, "frontend.max-streams-bidi") == 0) global.tune.quic_frontend_max_streams_bidi = arg; - else if (strcmp(suffix, "frontend.max-tx-mem") == 0) { - ullong max_mem; - - if ((errptr = parse_size_err(args[1], &max_mem))) { - memprintf(err, "'%s': unexpected character '%c' in size argument '%s'.", - args[0], *errptr, args[1]); - return -1; - } - - global.tune.quic_frontend_max_tx_mem = max_mem; - } else if (strcmp(suffix, "frontend.default-max-window-size") == 0) { unsigned long cwnd; char *end_opt; @@ -392,6 +393,21 @@ static int cfg_parse_quic_tune_setting(char **args, int section_type, quic_tune.fe.sec_glitches_threshold = arg; ret = 1; } + else if (strcmp(suffix, "frontend.max-tx-mem") == 0) { + ullong max_mem; + + memprintf(err, "'%s' is deprecated in 3.3 and will be removed in 3.5. " + "Please use the newer keyword syntax 'tune.quic.mem.tx-max'.", args[0]); + + if ((errptr = parse_size_err(args[1], &max_mem))) { + memprintf(err, "'%s': unexpected character '%c' in size argument '%s'.", + args[0], *errptr, args[1]); + return -1; + } + + quic_tune.mem_tx_max = max_mem; + ret = 1; + } else if (strcmp(suffix, "max-frame-loss") == 0) { memprintf(err, "'%s' is deprecated in 3.3 and will be removed in 3.5. " "Please use the newer keyword syntax 'tune.quic.fe.cc.max-frame-loss'.", args[0]); @@ -527,11 +543,11 @@ static int cfg_parse_quic_tune_on_off(char **args, int section_type, struct prox static struct cfg_kw_list cfg_kws = {ILH, { { CFG_GLOBAL, "tune.quic.listen", cfg_parse_quic_tune_on_off }, + { CFG_GLOBAL, "tune.quic.mem.tx-max", cfg_parse_quic_tune_setting }, { CFG_GLOBAL, "tune.quic.socket-owner", cfg_parse_quic_tune_socket_owner }, { CFG_GLOBAL, "tune.quic.frontend.max-data-size", cfg_parse_quic_tune_setting }, { CFG_GLOBAL, "tune.quic.frontend.max-streams-bidi", cfg_parse_quic_tune_setting }, { CFG_GLOBAL, "tune.quic.frontend.max-idle-timeout", cfg_parse_quic_time }, - { CFG_GLOBAL, "tune.quic.frontend.max-tx-mem", cfg_parse_quic_tune_setting }, { CFG_GLOBAL, "tune.quic.frontend.default-max-window-size", cfg_parse_quic_tune_setting }, { CFG_GLOBAL, "tune.quic.frontend.stream-data-ratio", cfg_parse_quic_tune_setting }, { CFG_GLOBAL, "tune.quic.retry-threshold", cfg_parse_quic_tune_setting }, @@ -559,6 +575,7 @@ static struct cfg_kw_list cfg_kws = {ILH, { { CFG_GLOBAL, "tune.quic.disable-tx-pacing", cfg_parse_quic_tune_setting0 }, { CFG_GLOBAL, "tune.quic.disable-udp-gso", cfg_parse_quic_tune_setting0 }, { CFG_GLOBAL, "tune.quic.frontend.glitches-threshold", cfg_parse_quic_tune_setting }, + { CFG_GLOBAL, "tune.quic.frontend.max-tx-mem", cfg_parse_quic_tune_setting }, { CFG_GLOBAL, "tune.quic.max-frame-loss", cfg_parse_quic_tune_setting }, { CFG_GLOBAL, "tune.quic.reorder-ratio", cfg_parse_quic_tune_setting }, diff --git a/src/haproxy.c b/src/haproxy.c index d1a746b3b..ad57ce865 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -203,7 +203,6 @@ struct global global = { .quic_frontend_max_idle_timeout = QUIC_TP_DFLT_FRONT_MAX_IDLE_TIMEOUT, .quic_frontend_max_data = 0, .quic_frontend_max_streams_bidi = QUIC_TP_DFLT_FRONT_MAX_STREAMS_BIDI, - .quic_frontend_max_tx_mem = QUIC_MAX_TX_MEM, .quic_frontend_max_window_size = QUIC_DFLT_MAX_WINDOW_SIZE, .quic_frontend_stream_data_ratio = QUIC_DFLT_FRONT_STREAM_DATA_RATIO, .quic_retry_threshold = QUIC_DFLT_RETRY_THRESHOLD, diff --git a/src/quic_cc.c b/src/quic_cc.c index 332f8aa71..98ef0a754 100644 --- a/src/quic_cc.c +++ b/src/quic_cc.c @@ -24,6 +24,7 @@ #include #include #include +#include #include struct quic_cc_algo *default_quic_cc_algo = &quic_cc_algo_cubic; @@ -85,11 +86,11 @@ static int quic_cc_max_win_ratio(void) uint64_t tot, free = 0; int ratio = 100; - if (global.tune.quic_frontend_max_tx_mem) { + if (quic_tune.mem_tx_max) { tot = cshared_read(&quic_mem_diff); - if (global.tune.quic_frontend_max_tx_mem > tot) - free = global.tune.quic_frontend_max_tx_mem - tot; - ratio = free * 100 / global.tune.quic_frontend_max_tx_mem; + if (quic_tune.mem_tx_max > tot) + free = quic_tune.mem_tx_max - tot; + ratio = free * 100 / quic_tune.mem_tx_max; } return ratio;