MINOR: quic: split Tx options for FE/BE usage

This patch is similar to the previous one, except that it is focused on
Tx QUIC settings. It is now possible to toggle GSO and pacing on
frontend and backend sides independently.

As with previous patch, option are renamed to use "fe/be" unified
prefixes. This is part of the current serie of commits which unify QUI
settings. Older options are deprecated and will be removed on 3.5
release.
This commit is contained in:
Amaury Denoyelle 2025-07-31 18:20:30 +02:00
parent 33a8cb87a9
commit 9bfe9b9e21
7 changed files with 85 additions and 36 deletions

View File

@ -1893,16 +1893,19 @@ The following keywords are supported in the "global" section :
- tune.quic.be.cc.max-frame-loss
- tune.quic.be.cc.reorder-ratio
- tune.quic.be.sec.glitches-threshold
- tune.quic.be.tx.pacing
- tune.quic.be.tx.udp-gso
- tune.quic.cc.cubic.min-losses (deprecated)
- tune.quic.cc-hystart (deprecated)
- tune.quic.disable-tx-pacing
- tune.quic.disable-udp-gso
- tune.quic.disable-tx-pacing (deprecated)
- tune.quic.disable-udp-gso (deprecated)
- tune.quic.fe.cc.cubic-min-losses
- tune.quic.fe.cc.hystart
- tune.quic.fe.cc.max-frame-loss
- tune.quic.fe.cc.reorder-ratio
- tune.quic.fe.sec.glitches-threshold
- tune.quic.frontend.glitches-threshold (deprecated)
- tune.quic.fe.tx.pacing
- tune.quic.fe.tx.udp-gso
- tune.quic.frontend.max-data-size
- tune.quic.frontend.max-idle-timeout
- tune.quic.frontend.max-streams-bidi
@ -4697,22 +4700,6 @@ tune.pt.zero-copy-forwarding { on | off }
See also: tune.disable-zero-copy-forwarding, option splice-auto,
option splice-request and option splice-response
tune.quic.disable-tx-pacing
Disables pacing support for QUIC emission. The purpose of pacing is to smooth
emission of data to reduce network losses. In most scenario, it will
significantly improve network throughput by avoiding retransmissions.
However, it can be useful to deactivate it for networks with very high
bandwidth/low latency characteristics to prevent unwanted delay and reduce
CPU consumption.
See also the "quic-cc-algo" bind option.
tune.quic.disable-udp-gso
Disable UDP GSO emission. This kernel feature allows to emit multiple
datagrams via a single system call which is more efficient for large
transfer. It may be useful to disable it on developers suggestion when
suspecting an issue on emission.
tune.quic.be.cc.cubic-min-losses <number>
tune.quic.fe.cc.cubic-min-losses <number>
Defines how many lost packets are needed for the Cubic congestion control
@ -4793,6 +4780,35 @@ tune.quic.frontend.glitches-threshold <number> (deprecated)
part of the streamlining process apply on QUIC configuration. If used, this
setting will only be applied on frontend connections.
tune.quic.be.tx.pacing { on | off }
tune.quic.fe.tx.pacing { on | off }
Enables ('on') or disables ('off') pacing support for QUIC emission. By
default, it is active. The purpose of pacing is to smooth emission of data to
reduce network losses. In most scenario, it will significantly improve
network throughput by avoiding retransmissions. However, it can be useful to
deactivate it for networks with very high bandwidth/low latency
characteristics to prevent unwanted delay and reduce CPU consumption.
See also the "quic-cc-algo" bind option.
tune.quic.disable-tx-pacing (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.be.tx.udp-gso { on | off }
tune.quic.fe.tx.udp-gso { on | off }
Enables ('on') or disables ('off') UDP GSO support for QUIC emission. By
default, it is active. This kernel feature allows to emit multiple datagrams
via a single system call which is more efficient for large transfer. It may
be useful to disable it on developers suggestion when suspecting an issue on
emission.
tune.quic.disable-udp-gso (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.frontend.max-data-size <size>
This setting is the hard limit for the number of data bytes in flight over a
QUIC frontend connection. It is reused as the value for the initial_max_data
@ -17110,10 +17126,10 @@ quic-cc-algo { cubic | newreno | bbr | nocc }[(<args,...>)]
similar to those used by TCP.
Pacing is activated on top of the congestion algorithm to reduce loss and
improve throughput. It can be turned off via "tune.quic.disable-tx-pacing"
global keyword. In most cases, pacing should remain activated, especially
when using BBR as it relies on it to work as expected. Using BBR without
pacing may cause slowdowns or high loss rates during transfers.
improve throughput. It can be turned off via "tune.quic.fe.tx.pacing" global
keyword. In most cases, pacing should remain activated, especially when using
BBR as it relies on it to work as expected. Using BBR without pacing may
cause slowdowns or high loss rates during transfers.
Default value: cubic

View File

@ -15,11 +15,11 @@
#define QUIC_TUNE_FE_LISTEN_OFF 0x00000001
#define QUIC_TUNE_NO_PACING 0x00000001
#define QUIC_TUNE_NO_UDP_GSO 0x00000002
#define QUIC_TUNE_SOCK_PER_CONN 0x00000004
#define QUIC_TUNE_FB_CC_HYSTART 0x00000001
#define QUIC_TUNE_FB_TX_PACING 0x00000001
#define QUIC_TUNE_FB_TX_UDP_GSO 0x00000002
#define QUIC_TUNE_FB_CC_HYSTART 0x00000004
struct quic_tune {
struct {

View File

@ -27,10 +27,12 @@ struct quic_tune quic_tune = {
.fe = {
.cc_max_frame_loss = QUIC_DFLT_CC_MAX_FRAME_LOSS,
.cc_reorder_ratio = QUIC_DFLT_CC_REORDER_RATIO,
.fb_opts = QUIC_TUNE_FB_TX_PACING|QUIC_TUNE_FB_TX_UDP_GSO,
},
.be = {
.cc_max_frame_loss = QUIC_DFLT_CC_MAX_FRAME_LOSS,
.cc_reorder_ratio = QUIC_DFLT_CC_REORDER_RATIO,
.fb_opts = QUIC_TUNE_FB_TX_PACING|QUIC_TUNE_FB_TX_UDP_GSO,
},
};
@ -420,6 +422,7 @@ static int cfg_parse_quic_tune_setting0(char **args, int section_type,
const struct proxy *defpx,
const char *file, int line, char **err)
{
int ret = 0;
int prefix_len = strlen("tune.quic.");
const char *suffix;
@ -428,17 +431,23 @@ static int cfg_parse_quic_tune_setting0(char **args, int section_type,
suffix = args[0] + prefix_len;
if (strcmp(suffix, "disable-tx-pacing") == 0) {
quic_tune.options |= QUIC_TUNE_NO_PACING;
memprintf(err, "'%s' is deprecated in 3.3 and will be removed in 3.5. "
"Please use the newer keyword syntax 'tune.quic.fe.tx.pacing'.", args[0]);
quic_tune.fe.fb_opts &= ~QUIC_TUNE_FB_TX_PACING;
ret = 1;
}
else if (strcmp(suffix, "disable-udp-gso") == 0) {
quic_tune.options |= QUIC_TUNE_NO_UDP_GSO;
memprintf(err, "'%s' is deprecated in 3.3 and will be removed in 3.5. "
"Please use the newer keyword syntax 'tune.quic.fe.tx.udp-gso'.", args[0]);
quic_tune.fe.fb_opts &= ~QUIC_TUNE_FB_TX_UDP_GSO;
ret = 1;
}
else {
memprintf(err, "'%s' keyword unhandled (please report this bug).", args[0]);
return -1;
}
return 0;
return ret;
}
/* config parser for global "tune.quic.* {on|off}" */
@ -485,6 +494,24 @@ static int cfg_parse_quic_tune_on_off(char **args, int section_type, struct prox
else
*ptr &= ~QUIC_TUNE_FB_CC_HYSTART;
}
else if (strcmp(suffix, "be.tx.pacing") == 0 ||
strcmp(suffix, "fe.tx.pacing") == 0) {
uint *ptr = (suffix[0] == 'b') ? &quic_tune.be.fb_opts :
&quic_tune.fe.fb_opts;
if (on)
*ptr |= QUIC_TUNE_FB_TX_PACING;
else
*ptr &= ~QUIC_TUNE_FB_TX_PACING;
}
else if (strcmp(suffix, "be.tx.udp-gso") == 0 ||
strcmp(suffix, "fe.tx.udp-gso") == 0) {
uint *ptr = (suffix[0] == 'b') ? &quic_tune.be.fb_opts :
&quic_tune.fe.fb_opts;
if (on)
*ptr |= QUIC_TUNE_FB_TX_UDP_GSO;
else
*ptr &= ~QUIC_TUNE_FB_TX_UDP_GSO;
}
else if (strcmp(suffix, "cc-hystart") == 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.hystart'.", args[0]);
@ -508,8 +535,6 @@ static struct cfg_kw_list cfg_kws = {ILH, {
{ 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 },
{ 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.zero-copy-fwd-send", cfg_parse_quic_tune_on_off },
{ CFG_GLOBAL, "tune.quic.fe.cc.cubic-min-losses", cfg_parse_quic_tune_setting },
@ -517,16 +542,22 @@ static struct cfg_kw_list cfg_kws = {ILH, {
{ CFG_GLOBAL, "tune.quic.fe.cc.max-frame-loss", cfg_parse_quic_tune_setting },
{ CFG_GLOBAL, "tune.quic.fe.cc.reorder-ratio", cfg_parse_quic_tune_setting },
{ CFG_GLOBAL, "tune.quic.fe.sec.glitches-threshold", cfg_parse_quic_tune_setting },
{ CFG_GLOBAL, "tune.quic.fe.tx.pacing", cfg_parse_quic_tune_on_off },
{ CFG_GLOBAL, "tune.quic.fe.tx.udp-gso", cfg_parse_quic_tune_on_off },
{ CFG_GLOBAL, "tune.quic.be.cc.cubic-min-losses", cfg_parse_quic_tune_setting },
{ CFG_GLOBAL, "tune.quic.be.cc.hystart", cfg_parse_quic_tune_on_off },
{ CFG_GLOBAL, "tune.quic.be.cc.max-frame-loss", cfg_parse_quic_tune_setting },
{ CFG_GLOBAL, "tune.quic.be.cc.reorder-ratio", cfg_parse_quic_tune_setting },
{ CFG_GLOBAL, "tune.quic.be.sec.glitches-threshold", cfg_parse_quic_tune_setting },
{ CFG_GLOBAL, "tune.quic.be.tx.pacing", cfg_parse_quic_tune_on_off },
{ CFG_GLOBAL, "tune.quic.be.tx.udp-gso", cfg_parse_quic_tune_on_off },
/* legacy options */
{ CFG_GLOBAL, "tune.quic.cc-hystart", cfg_parse_quic_tune_on_off },
{ CFG_GLOBAL, "tune.quic.cc.cubic.min-losses", cfg_parse_quic_tune_setting },
{ 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.max-frame-loss", cfg_parse_quic_tune_setting },
{ CFG_GLOBAL, "tune.quic.reorder-ratio", cfg_parse_quic_tune_setting },

View File

@ -2978,7 +2978,7 @@ init_proxies_list_stage1:
bind_conf->quic_cc_algo : default_quic_cc_algo;
if (!(cc_algo->flags & QUIC_CC_ALGO_FL_OPT_PACING) &&
quic_tune.options & QUIC_TUNE_NO_PACING) {
!(quic_tune.fe.fb_opts & QUIC_TUNE_FB_TX_PACING)) {
ha_warning("Binding [%s:%d] for %s %s: using the selected congestion algorithm without pacing may cause slowdowns or high loss rates during transfers.\n",
bind_conf->file, bind_conf->line,
proxy_type_str(curproxy), curproxy->id);

View File

@ -43,7 +43,7 @@ static void qmux_ctrl_room(struct qc_stream_desc *, uint64_t room);
/* Returns true if pacing should be used for <conn> connection. */
static int qcc_is_pacing_active(const struct connection *conn)
{
return !(quic_tune.options & QUIC_TUNE_NO_PACING);
return quic_tune_conn_test(QUIC_TUNE_FB_TX_PACING, conn);
}
/* Free <rxbuf> instance and its inner data storage attached to <qcs> stream. */

View File

@ -780,7 +780,8 @@ static int quic_test_socketopts(void)
}
/* Check for UDP GSO support. */
if (!(quic_tune.options & QUIC_TUNE_NO_UDP_GSO)) {
if ((quic_tune.fe.fb_opts & QUIC_TUNE_FB_TX_UDP_GSO) ||
(quic_tune.be.fb_opts & QUIC_TUNE_FB_TX_UDP_GSO)) {
ret = quic_test_gso();
if (ret < 0) {
goto err;
@ -788,7 +789,8 @@ static int quic_test_socketopts(void)
else if (!ret) {
ha_diag_warning("Your platform does not support UDP GSO. "
"This will be automatically disabled for QUIC transfer.\n");
quic_tune.options |= QUIC_TUNE_NO_UDP_GSO;
quic_tune.fe.fb_opts &= ~QUIC_TUNE_FB_TX_UDP_GSO;
quic_tune.be.fb_opts &= ~QUIC_TUNE_FB_TX_UDP_GSO;
}
}

View File

@ -810,7 +810,7 @@ static int qc_prep_pkts(struct quic_conn *qc, struct buffer *buf,
/* Everything sent. Continue within the same datagram. */
prv_pkt = cur_pkt;
}
else if (!(quic_tune.options & QUIC_TUNE_NO_UDP_GSO) &&
else if (quic_tune_test(QUIC_TUNE_FB_TX_UDP_GSO, qc) &&
!(qc->flags & QUIC_FL_CONN_UDP_GSO_EIO) &&
dglen == qc->path->mtu &&
(char *)end < b_wrap(buf) &&