]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: global: Add an option to disable the zero-copy forwarding
authorChristopher Faulet <cfaulet@haproxy.com>
Mon, 16 Oct 2023 16:28:59 +0000 (18:28 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Tue, 17 Oct 2023 16:51:13 +0000 (18:51 +0200)
The zero-copy forwarding or the mux-to-mux forwarding is a way to
fast-forward data without using the channels buffers. Data are transferred
from a mux to the other one. The kernel splicing is an optimization of the
zero-copy forwarding. But it can also use normal buffers (but not channels
ones). This way, it could be possible to fast-forward data with muxes not
supporting the kernel splicing (H2 and H3 muxes) but also with applets.

However, this mode can introduce regressions or bugs in future (just like
the kernel splicing). Thus, It could be usefull to disable this optim. To do
so, in configuration, the global tune settting
'tune.disable-zero-copy-forwarding' may be set in a global section or the
'-dZ' command line parameter may be used to start HAProxy. Of course, this
also disables the kernel splicing.

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

index 88a576795b4094b824210d91f52388a76b8f3217..54905263b1582f743bfa927f88772b1591869465 100644 (file)
@@ -1175,6 +1175,7 @@ The following keywords are supported in the "global" section :
    - tune.bufsize
    - tune.comp.maxlevel
    - tune.disable-fast-forward
+   - tune.disable-zero-copy-forwarding
    - tune.fail-alloc
    - tune.fd.edge-triggered
    - tune.h2.be.initial-window-size
@@ -2892,11 +2893,18 @@ tune.disable-fast-forward [ EXPERIMENTAL ]
   Disables the data fast-forwarding. It is a mechanism to optimize the data
   forwarding by passing data directly from a side to the other one without
   waking the stream up. Thanks to this directive, it is possible to disable
-  this optimization. Note it also disable any kernel tcp splicing. This command
-  is not meant for regular use, it will generally only be suggested by
-  developers along complex debugging sessions. For this reason it is internally
-  marked as experimental, meaning that "expose-experimental-directives" must
-  appear on a line before this directive.
+  this optimization. Note it also disable any kernel tcp splicing but also the
+  zero-copy forwarding. This command is not meant for regular use, it will
+  generally only be suggested by developers along complex debugging
+  sessions. For this reason it is internally marked as experimental, meaning
+  that "expose-experimental-directives" must appear on a line before this
+  directive.
+
+tune.zero-copy-forwarding
+  Disables the zero-copy forwarding of data. It is a mechanism to optimize the
+  data fast-forwarding by avoiding to use the channel's buffer. Thanks to this
+  directive, it is possible to disable this optimization. Note it also disable
+  any kernel tcp splicing.
 
 tune.fail-alloc
   If compiled with DEBUG_FAIL_ALLOC or started with "-dMfail", gives the
index 1aca09b2ffae323181462c2fce9e5405b343a921..cf17c4481da28fefd4d7f5960c87800e7bd8df28 100644 (file)
@@ -66,7 +66,7 @@
 #define GTUNE_USE_SYSTEMD        (1<<10)
 
 #define GTUNE_BUSY_POLLING       (1<<11)
-/* unused: (1<<12) */
+#define GTUNE_USE_ZERO_COPY_FWD  (1<<12)
 #define GTUNE_SET_DUMPABLE       (1<<13)
 #define GTUNE_USE_EVPORTS        (1<<14)
 #define GTUNE_STRICT_LIMITS      (1<<15)
index 52dac8febda257913ef4cca48ca072321f571680..7834ea18fe1dfbb9c7c6a6ecdf85274724479542 100644 (file)
@@ -517,6 +517,11 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
                        goto out;
                global.tune.options &= GTUNE_USE_FAST_FWD;
        }
+       else if (strcmp(args[0], "tune.disable-zero-copy-forwarding") == 0) {
+               if (alertif_too_many_args(0, file, linenum, args, &err_code))
+                       goto out;
+               global.tune.options &= GTUNE_USE_ZERO_COPY_FWD;
+       }
        else if (strcmp(args[0], "cluster-secret") == 0) {
                blk_SHA_CTX sha1_ctx;
                unsigned char sha1_out[20];
index 5b7d44fda44436e3c9822422e03b370640b3f022..7a4f49fa69058088ef2ded75d2fdbdc36f5eafd8 100644 (file)
@@ -649,6 +649,7 @@ static void usage(char *name)
                "        -dW fails if any warning is emitted\n"
                "        -dD diagnostic mode : warn about suspicious configuration statements\n"
                "        -dF disable fast-forward\n"
+               "        -dZ disable zero-copy forwarding\n"
                "        -sf/-st [pid ]* finishes/terminates old pids.\n"
                "        -x <unix_socket> get listening sockets from a unix socket\n"
                "        -S <bind>[,<bind options>...] new master CLI\n"
@@ -1609,6 +1610,7 @@ static void init_args(int argc, char **argv)
        global.tune.options |= GTUNE_STRICT_LIMITS;
 
        global.tune.options |= GTUNE_USE_FAST_FWD; /* Use fast-forward by default */
+       global.tune.options |= GTUNE_USE_ZERO_COPY_FWD; /* Use zero-copy forwarding by default */
 
        /* keep a copy of original arguments for the master process */
        old_argv = copy_argv(argc, argv);
@@ -1664,6 +1666,8 @@ static void init_args(int argc, char **argv)
                                global.tune.options &= ~GTUNE_USE_FAST_FWD;
                        else if (*flag == 'd' && flag[1] == 'V')
                                global.ssl_server_verify = SSL_SERVER_VERIFY_NONE;
+                       else if (*flag == 'd' && flag[1] == 'Z')
+                               global.tune.options &= ~GTUNE_USE_ZERO_COPY_FWD;
                        else if (*flag == 'V')
                                arg_mode |= MODE_VERBOSE;
                        else if (*flag == 'd' && flag[1] == 'C') {
index 79fc51608836d458bb0227811821e1fb8a8b50cf..799cdafd3c34962345192884ae08aaaa8104ef0c 100644 (file)
@@ -1271,7 +1271,8 @@ static int sc_conn_recv(struct stconn *sc)
        /* First, let's see if we may fast-forward data from a side to the other
         * one without using the channel buffer.
         */
-       if (sc_ep_test(sc, SE_FL_MAY_FASTFWD) && ic->to_forward) {
+       if ((global.tune.options & GTUNE_USE_ZERO_COPY_FWD) &&
+           sc_ep_test(sc, SE_FL_MAY_FASTFWD) && ic->to_forward) {
                if (c_data(ic)) {
                        /* We're embarrassed, there are already data pending in
                         * the buffer and we don't want to have them at two