]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: global: Use a dedicated bitfield to customize zero-copy fast-forwarding
authorChristopher Faulet <cfaulet@haproxy.com>
Mon, 4 Dec 2023 13:18:50 +0000 (14:18 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 4 Dec 2023 14:31:47 +0000 (15:31 +0100)
Zero-copy fast-forwading feature is a quite new and is a bit sensitive.
There is an option to disable it globally. However, all protocols have not
the same maturity. For instance, for the PT multiplexer, there is nothing
really new. The zero-copy fast-forwading is only another name for the kernel
splicing. However, for the QUIC/H3, it is pretty new, not really optimized
and it will evolved. And soon, the support will be added for the cache
applet.

In this context, it is usefull to be able to enable/disable zero-copy
fast-forwading per-protocol and applet. And when it is applicable, on sends
or receives separately. So, instead of having one flag to disable it
globally, there is now a dedicated bitfield, global.tune.no_zero_copy_fwd.

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

index 33e4ab63bfd087cd0e36087ffc8bcc6482bf42b7..670b2e80e9c2c493d50e3eaa4c9063d4e6e1736b 100644 (file)
@@ -2916,10 +2916,10 @@ tune.disable-fast-forward [ EXPERIMENTAL ]
   directive.
 
 tune.disable-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.
+  Globally 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.events.max-events-at-once <number>
   Sets the number of events that may be processed at once by an asynchronous
index e302de45dfc0c6be4e889f368ae7700668981917..bb39baffce99fb790ca14cae445ab6aa6611541b 100644 (file)
@@ -66,7 +66,7 @@
 #define GTUNE_USE_SYSTEMD        (1<<10)
 
 #define GTUNE_BUSY_POLLING       (1<<11)
-#define GTUNE_USE_ZERO_COPY_FWD  (1<<12)
+/* (1<<12) unused */
 #define GTUNE_SET_DUMPABLE       (1<<13)
 #define GTUNE_USE_EVPORTS        (1<<14)
 #define GTUNE_STRICT_LIMITS      (1<<15)
 #define GTUNE_LISTENER_MQ_OPT    (1<<28)
 #define GTUNE_LISTENER_MQ_ANY    (GTUNE_LISTENER_MQ_FAIR | GTUNE_LISTENER_MQ_OPT)
 
+#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) */
+#define NO_ZERO_COPY_FWD_H1_RCV      0x0004 /* disable zero-copy FF for H1 on received */
+#define NO_ZERO_COPY_FWD_H1_SND      0x0008 /* disable zero-copy FF for H1 on send */
+#define NO_ZERO_COPY_FWD_H2_RCV      0x0010 /* disable zero-copy FF for H2 on received */
+#define NO_ZERO_COPY_FWD_H2_SND      0x0020 /* disable zero-copy FF for H2 on send */
+#define NO_ZERO_COPY_FWD_QUIC_RCV    0x0040 /* disable zero-copy FF for QUIC on received */
+#define NO_ZERO_COPY_FWD_QUIC_SND    0x0080 /* disable zero-copy FF for QUIC on send */
+#define NO_ZERO_COPY_FWD_FCGI_RCV    0x0100 /* disable zero-copy FF for FCGI on received */
+#define NO_ZERO_COPY_FWD_FCGI_SND    0x0200 /* disable zero-copy FF for FCGI on send */
+
+
 extern int cluster_secret_isset; /* non zero means a cluster secret was initialized */
 
 /* SSL server verify mode */
@@ -173,6 +185,7 @@ struct global {
                int pool_high_count;  /* max number of opened fd before we start killing idle connections when creating new connections */
                size_t pool_cache_size;    /* per-thread cache size per pool (defaults to CONFIG_HAP_POOL_CACHE_SIZE) */
                unsigned short idle_timer; /* how long before an empty buffer is considered idle (ms) */
+               unsigned short no_zero_copy_fwd; /* Flags to disable zero-copy fast-forwarding (global & per-protocols) */
                int nb_stk_ctr;       /* number of stick counters, defaults to MAX_SESS_STKCTR */
                int default_shards; /* default shards for listeners, or -1 (by-thread) or -2 (by-group) */
                uint max_checks_per_thread; /* if >0, no more than this concurrent checks per thread */
index a80ac854f6ccbdb861c656cb1fe4c36edd708e58..540dda79b0838f1bb19b2c213058d5d08a6e0430 100644 (file)
@@ -520,7 +520,7 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
        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;
+               global.tune.no_zero_copy_fwd |= NO_ZERO_COPY_FWD;
        }
        else if (strcmp(args[0], "cluster-secret") == 0) {
                blk_SHA_CTX sha1_ctx;
index 3b5b1719b2fd42938d2408e170afba3429f3e196..e1863255422459e806f7e50828e81976bb41c14c 100644 (file)
@@ -1599,7 +1599,9 @@ 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 */
+
+       /* Use zero-copy forwarding by default */
+       global.tune.no_zero_copy_fwd = 0;
 
        /* keep a copy of original arguments for the master process */
        old_argv = copy_argv(argc, argv);
@@ -1656,7 +1658,7 @@ static void init_args(int argc, char **argv)
                        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;
+                               global.tune.no_zero_copy_fwd |= NO_ZERO_COPY_FWD;
                        else if (*flag == 'V')
                                arg_mode |= MODE_VERBOSE;
                        else if (*flag == 'd' && flag[1] == 'C') {
index 59b4acf10a17beff4b0cde8b863ff76d2dae2321..63dd9bf1f3416e8012ffb4f66f7088bde490bb0d 100644 (file)
@@ -1276,7 +1276,7 @@ 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 ((global.tune.options & GTUNE_USE_ZERO_COPY_FWD) &&
+       if (!(global.tune.no_zero_copy_fwd & NO_ZERO_COPY_FWD) &&
            sc_ep_test(sc, SE_FL_MAY_FASTFWD) && ic->to_forward) {
                if (channel_data(ic)) {
                        /* We're embarrassed, there are already data pending in