- 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.stream-data-ratio
- tune.quic.frontend.default-max-window-size
- tune.quic.max-frame-loss
See also: "tune.quic.frontend.max-data-size",
"tune.quic.frontend.stream-data-ratio"
+tune.quic.frontend.max-tx-mem <size>
+ 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
#define FWLC_MIN_FREE_ENTRIES 500
#endif /* FWLC_MIN_FREE_ENTRIES */
+/*
+ * QUIC
+ */
+
+/* Memory usage in bytes on Tx side, 0 for unlimited. */
+#ifndef QUIC_MAX_TX_MEM
+#define QUIC_MAX_TX_MEM 0
+#endif
+
#endif /* _HAPROXY_DEFAULTS_H */
unsigned int quic_frontend_glitches_threshold;
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;
}
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;
{ 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.max-frame-loss", cfg_parse_quic_tune_setting },
.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_reorder_ratio = QUIC_DFLT_REORDER_RATIO,
return 2 * path->in_flight >= path->cwnd || path->cwnd < 16384;
}
+/* Calculate ratio of free memory relative to the maximum configured limit. */
+static int quic_cc_max_win_ratio(void)
+{
+ uint64_t tot, free = 0;
+ int ratio = 100;
+
+ if (global.tune.quic_frontend_max_tx_mem) {
+ 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;
+ }
+
+ return ratio;
+}
+
/* Restore congestion window for <path> to its minimal value. */
void quic_cc_path_reset(struct quic_cc_path *path)
{
void quic_cc_path_set(struct quic_cc_path *path, uint64_t val)
{
const uint64_t old = path->cwnd;
+ const uint64_t limit_max = path->limit_max * quic_cc_max_win_ratio() / 100;
- path->cwnd = QUIC_MIN(val, path->limit_max);
+ path->cwnd = QUIC_MIN(val, limit_max);
path->cwnd = QUIC_MAX(path->cwnd, path->limit_min);
cshared_add(&quic_mem_diff, path->cwnd - old);
void quic_cc_path_inc(struct quic_cc_path *path, uint64_t val)
{
const uint64_t old = path->cwnd;
+ uint64_t limit_max;
if (quic_cwnd_may_increase(path)) {
- path->cwnd = QUIC_MIN(path->cwnd + val, path->limit_max);
+ limit_max = path->limit_max * quic_cc_max_win_ratio() / 100;
+ path->cwnd = QUIC_MIN(path->cwnd + val, limit_max);
path->cwnd = QUIC_MAX(path->cwnd, path->limit_min);
cshared_add(&quic_mem_diff, path->cwnd - old);