]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: define max-stream-data configuration as a ratio
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 20 Mar 2025 09:41:53 +0000 (10:41 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 25 Mar 2025 15:30:35 +0000 (16:30 +0100)
doc/configuration.txt
include/haproxy/global-t.h
include/haproxy/mux_quic.h
include/haproxy/quic_conn-t.h
include/haproxy/quic_tp-t.h
src/cfgparse-quic.c
src/haproxy.c
src/quic_tp.c

index b928fa3dbcc8a6912a05b682a9c0109c73a3f4c1..bc5104b793c47731648b0e623906be01ce8364c6 100644 (file)
@@ -1694,6 +1694,7 @@ 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.stream-data-ratio
    - tune.quic.frontend.default-max-window-size
    - tune.quic.max-frame-loss
    - tune.quic.reorder-ratio
@@ -4349,6 +4350,9 @@ tune.quic.frontend.max-data-size <size>
   This can be increased for example if a backend application relies on massive
   uploads over high latency networks.
 
+  See also: "tune.quic.frontend.max-streams-bidi",
+            "tune.quic.frontend.stream-data-ratio"
+
 tune.quic.frontend.max-idle-timeout <timeout>
   Sets the QUIC max_idle_timeout transport parameters in milliseconds for
   frontends which determines the period of time after which a connection silently
@@ -4366,7 +4370,32 @@ tune.quic.frontend.max-streams-bidi <number>
   will be authorized to open. This determines the number of concurrent client
   requests.
 
-  The default value is 100.
+  The default value is 100. Note that if you reduces it, it can restrict the
+  buffering capabilities of streams on receive, which would result in poor
+  upload throughput. It can be corrected by increasing
+  tune.quic.frontend.max-data-size setting.
+
+  See also: "tune.quic.frontend.max-data-size",
+            "tune.quic.frontend.stream-data-ratio"
+
+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
+  "tune.quic.frontend.max-data-size" setting, with the result rounded up to
+  bufsize.
+
+  The default value is 90. This is suitable with the most frequent web
+  scenario, where uploads is performed only for one or a few streams, whereas
+  the rest are used for download only. If max-data-size connection limit
+  remains at a reasonable level, it ensures that only a portion of opened
+  streams can allocate to their maximum capacity.
+
+  In the case of an application using many uploading streams in parallel and
+  suffering from unfairness between these streams, it can make sense to reduce
+  this ratio, to increase fairness and reduce the per-stream bandwidth.
+
+  See also: "tune.quic.frontend.max-data-size",
+            "tune.quic.frontend.max-streams-bidi"
 
 tune.quic.frontend.default-max-window-size <size>
   Sets the default maximum window size for the congestion controller of a
index 3aa2c1edfeed9de730b4800956672c669f8c46ae..e54a388a1bc0f1d15ccf872d729caa66647e86a4 100644 (file)
@@ -216,6 +216,7 @@ struct global {
                unsigned int quic_frontend_max_data;
                unsigned int quic_frontend_max_streams_bidi;
                size_t quic_frontend_max_window_size;
+               unsigned int quic_frontend_stream_data_ratio;
                unsigned int quic_retry_threshold;
                unsigned int quic_reorder_ratio;
                unsigned int quic_max_frame_loss;
index b39fdfd9c615f2208a494b7789e6dde55b228352..a2a1ecfb8fecfe8aa88220eabaa9b03b4ff6864a 100644 (file)
@@ -51,9 +51,6 @@ static inline int qmux_stream_rx_bufsz(void)
        return global.tune.bufsize - NCB_RESERVED_SZ;
 }
 
-/* Number of buffers usable on Rx per QCS instance. */
-#define QMUX_STREAM_RX_BUF_FACTOR    90
-
 /* Bit shift to get the stream sub ID for internal use which is obtained
  * shifting the stream IDs by this value, knowing that the
  * QCS_ID_TYPE_SHIFT less significant bits identify the stream ID
index 7ed7156106f30afb0bbc6e8e306fbda02d5f662c..92dd60ae675f44d288452d6920b4a460a73a9658 100644 (file)
@@ -100,6 +100,9 @@ typedef unsigned long long ull;
 /* Default congestion window size. 480 kB, equivalent to the legacy value which was 30*bufsize */
 #define QUIC_DFLT_MAX_WINDOW_SIZE  491520
 
+/* Default ratio applied for max-stream-data-bidi-remote derived from max-data */
+#define QUIC_DFLT_FRONT_STREAM_DATA_RATIO 90
+
 /*
  *  0                   1                   2                   3
  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
index 4897441827a490a8762f4635010fd85249c95d12..61cd5b41e3712a031e0bfbc5ec503017237a3ea4 100644 (file)
@@ -44,6 +44,7 @@ struct tp_version_information {
 #define QUIC_TP_DFLT_FRONT_MAX_IDLE_TIMEOUT      30000 /* milliseconds */
 #define QUIC_TP_DFLT_FRONT_MAX_STREAMS_BIDI        100
 #define QUIC_TP_DFLT_BACK_MAX_IDLE_TIMEOUT       30000 /* milliseconds */
+#define QUIC_TP_DFLT_FRONT_STREAM_DATA_RATIO        90
 
 /* Types of QUIC transport parameters */
 #define QUIC_TP_ORIGINAL_DESTINATION_CONNECTION_ID  0x00
index 01ff6dd69863d8baf300552c3525c809ffe0befa..3b7c6df2e39801bbd8ea536696fd6b028ed283b2 100644 (file)
@@ -330,6 +330,13 @@ static int cfg_parse_quic_tune_setting(char **args, int section_type,
 
                global.tune.quic_frontend_max_window_size = cwnd;
        }
+       else if (strcmp(suffix, "frontend.stream-data-ratio") == 0) {
+               if (arg < 1 || arg > 100) {
+                       memprintf(err, "'%s' expects an integer argument between 1 and 100.", args[0]);
+                       return -1;
+               }
+               global.tune.quic_frontend_stream_data_ratio = arg;
+       }
        else if (strcmp(suffix, "max-frame-loss") == 0)
                global.tune.quic_max_frame_loss = arg;
        else if (strcmp(suffix, "reorder-ratio") == 0) {
@@ -424,6 +431,7 @@ static struct cfg_kw_list cfg_kws = {ILH, {
        { 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.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.max-frame-loss", cfg_parse_quic_tune_setting },
        { CFG_GLOBAL, "tune.quic.reorder-ratio", cfg_parse_quic_tune_setting },
        { CFG_GLOBAL, "tune.quic.retry-threshold", cfg_parse_quic_tune_setting },
index 6b1c6ce55226e5bb0031ad61d5eec998b358614c..8b59bb6af9a8b198a40c3f77683f65535ca2dc6a 100644 (file)
@@ -199,6 +199,7 @@ struct global global = {
                .quic_frontend_max_data = 0,
                .quic_frontend_max_streams_bidi = QUIC_TP_DFLT_FRONT_MAX_STREAMS_BIDI,
                .quic_frontend_max_window_size = QUIC_DFLT_MAX_WINDOW_SIZE,
+               .quic_frontend_stream_data_ratio = QUIC_DFLT_FRONT_STREAM_DATA_RATIO,
                .quic_reorder_ratio = QUIC_DFLT_REORDER_RATIO,
                .quic_retry_threshold = QUIC_DFLT_RETRY_THRESHOLD,
                .quic_max_frame_loss = QUIC_DFLT_MAX_FRAME_LOSS,
index 8cb50c326608481b4e1de3c8f50df8a205165a16..03d5b12c36ac49bf941ad32c6613eb0e3f9809e5 100644 (file)
@@ -76,8 +76,13 @@ void quic_transport_params_init(struct quic_transport_params *p, int server)
        else
                p->initial_max_data = max_streams_bidi * stream_rx_bufsz;
 
-       /* Set remote streams flow-control data limit. */
-       p->initial_max_stream_data_bidi_remote = stream_rx_bufsz * QMUX_STREAM_RX_BUF_FACTOR;
+       /* Set remote streams flow-control data limit. This is calculated as a
+        * ratio from max-data, then rounded up to bufsize.
+        */
+       p->initial_max_stream_data_bidi_remote =
+         p->initial_max_data * global.tune.quic_frontend_stream_data_ratio / 100;
+       p->initial_max_stream_data_bidi_remote =
+         stream_rx_bufsz * ((p->initial_max_stream_data_bidi_remote + (stream_rx_bufsz - 1)) / stream_rx_bufsz);
 
        /* Set remaining flow-control data limit. Local bidi streams are unused
         * on server side. Uni streams are only used for control exchange, so