]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: activate UDP GSO for QUIC if supported
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 30 May 2024 12:49:25 +0000 (14:49 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 11 Jul 2024 09:02:44 +0000 (11:02 +0200)
Add a startup test for GSO support in quic_test_socketopts() and
automatically activate it in qc_prep_pkts() when building datagrams as
big as MTU.

Also define a new config option tune.quic.disable-udp-gso. This is
useful to prevent warning on older platform or to debug an issue which
may be related to GSO.

doc/configuration.txt
include/haproxy/global-t.h
src/cfgparse-quic.c
src/proto_quic.c

index e723305ba6b35531738bf396584f8b3ae3aa076a..4e38936f28d84874ae5079c36303e2f79b5eead4 100644 (file)
@@ -1414,6 +1414,7 @@ The following keywords are supported in the "global" section :
    - tune.pool-low-fd-ratio
    - tune.pt.zero-copy-forwarding
    - tune.quic.cc-hystart
+   - tune.quic.disable-udp-gso
    - tune.quic.frontend.conn-tx-buffers.limit
    - tune.quic.frontend.glitches-threshold
    - tune.quic.frontend.max-idle-timeout
@@ -3770,6 +3771,12 @@ tune.quic.cc-hystart { on | off }
   QUIC connections used as a replacement for the slow start phase of congestion
   control algorithms which may cause high packet loss. It is disabled by default.
 
+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.frontend.conn-tx-buffers.limit <number>
   This settings defines the maximum number of buffers allocated for a QUIC
   connection on data emission. By default, it is set to 30. QUIC buffers are
index 6e66a1d814e8bd20c84d846b66f43aba5890b2a7..f4d87b7a1282605b91e13fa32667e24127664362 100644 (file)
@@ -85,6 +85,7 @@
 #define GTUNE_LISTENER_MQ_OPT    (1<<28)
 #define GTUNE_LISTENER_MQ_ANY    (GTUNE_LISTENER_MQ_FAIR | GTUNE_LISTENER_MQ_OPT)
 #define GTUNE_QUIC_CC_HYSTART    (1<<29)
+#define GTUNE_QUIC_NO_UDP_GSO    (1<<30)
 
 #define NO_ZERO_COPY_FWD             0x0001 /* Globally disable zero-copy FF */
 #define NO_ZERO_COPY_FWD_PT          0x0002 /* disable zero-copy FF for PT (recv & send are disabled automatically) */
index 4a23bf20ec3f791efdc851b1f1b4ae17039309c9..97c515acffdfbd888017690bf78f44be050592a5 100644 (file)
@@ -1,5 +1,6 @@
 #include <errno.h>
 #include <string.h>
+#include <netinet/udp.h>
 
 #include <haproxy/api.h>
 #include <haproxy/cfgparse.h>
@@ -259,6 +260,29 @@ static int cfg_parse_quic_tune_setting(char **args, int section_type,
        return 0;
 }
 
+static int cfg_parse_quic_tune_setting0(char **args, int section_type,
+                                        struct proxy *curpx,
+                                        const struct proxy *defpx,
+                                        const char *file, int line, char **err)
+{
+       int prefix_len = strlen("tune.quic.");
+       const char *suffix;
+
+       if (too_many_args(0, args, err, NULL))
+               return -1;
+
+       suffix = args[0] + prefix_len;
+       if (strcmp(suffix, "disable-udp-gso") == 0) {
+               global.tune.options |= GTUNE_QUIC_NO_UDP_GSO;
+       }
+       else {
+               memprintf(err, "'%s' keyword unhandled (please report this bug).", args[0]);
+               return -1;
+       }
+
+       return 0;
+}
+
 /* config parser for global "tune.quic.* {on|off}" */
 static int cfg_parse_quic_tune_on_off(char **args, int section_type, struct proxy *curpx,
                                       const struct proxy *defpx, const char *file, int line,
@@ -308,6 +332,7 @@ static struct cfg_kw_list cfg_kws = {ILH, {
        { 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 },
+       { 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 },
        { 0, NULL, NULL }
 }};
index 2e5ad64804ec0274b874ae15d210dddb99e4a04a..96d33fe5a90c70ce5344eaabd8619298bc6e8fd0 100644 (file)
@@ -555,6 +555,28 @@ static int quic_test_socketopts(struct listener *l)
 #endif
        }
 
+       /* Check for UDP GSO support. */
+       if (!(global.tune.options & GTUNE_QUIC_NO_UDP_GSO)) {
+               if (fdtest < 0) {
+                       fdtest = socket(rx->proto->fam->sock_domain,
+                                       rx->proto->sock_type, rx->proto->sock_prot);
+                       if (fdtest < 0)
+                               goto err;
+               }
+
+#ifdef UDP_SEGMENT
+               if (setsockopt(fdtest, SOL_UDP, UDP_SEGMENT, &zero, sizeof(zero))) {
+                       ha_alert("Your platform does not support UDP GSO. "
+                                "This will be automatically disabled for QUIC transfer.\n");
+                       global.tune.options |= GTUNE_QUIC_NO_UDP_GSO;
+               }
+#else
+               ha_alert("Your platform does not support UDP GSO. "
+                        "This will be automatically disabled for QUIC transfer.\n");
+               global.tune.options |= GTUNE_QUIC_NO_UDP_GSO;
+#endif
+       }
+
        close(fdtest);
        return ERR_NONE;