]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: mux-h1: Add global option to enable/disable zero-copy forwarding
authorChristopher Faulet <cfaulet@haproxy.com>
Mon, 4 Dec 2023 14:06:06 +0000 (15:06 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 4 Dec 2023 14:33:07 +0000 (15:33 +0100)
tune.h1.zero-copy-fwd-recv and tune.h1.zero-copy-fwd-send can now be used to
enable or disable the zero-copy fast-forwarding for the H1 mux only, for
receives or sends. Unlike the PT mux, there are 2 options here because
client and server sides can use difference muxes.

Both are enabled ('on') by default.

doc/configuration.txt
src/mux_h1.c

index b3bf728c56a9eceebf70935402c986e07679a3ce..cf794fa039b009b96d8b3a66a52b4a8b782ad1aa 100644 (file)
@@ -1181,6 +1181,8 @@ The following keywords are supported in the "global" section :
    - tune.events.max-events-at-once
    - tune.fail-alloc
    - tune.fd.edge-triggered
+   - tune.h1.zero-copy-fwd-recv
+   - tune.h1.zero-copy-fwd-send
    - tune.h2.be.initial-window-size
    - tune.h2.be.max-concurrent-streams
    - tune.h2.fe.initial-window-size
@@ -2922,7 +2924,8 @@ tune.disable-zero-copy-forwarding
   Thanks to this directive, it is possible to disable this optimization. Note
   it also disable any kernel tcp splicing.
 
-  See also: tune.pt.zero-copy-forwarding
+  See also: tune.pt.zero-copy-forwarding,
+            tune.h1.zero-copy-fwd-recv, tune.h1.zero-copy-fwd-send
 
 tune.events.max-events-at-once <number>
   Sets the number of events that may be processed at once by an asynchronous
@@ -2949,6 +2952,18 @@ tune.fd.edge-triggered { on | off }  [ EXPERIMENTAL ]
   certain scenarios. This is still experimental, it may result in frozen
   connections if bugs are still present, and is disabled by default.
 
+tune.h1.zero-copy-fwd-recv { on | off }
+  Enables ('on') of disabled ('off') the zero-copy receives of data for the H1
+  multiplexer. It is enabled by default.
+
+  See also: tune.disable-zero-copy-forwarding, tune.h1.zero-copy-fwd-send
+
+tune.h1.zero-copy-fwd-send { on | off }
+  Enables ('on') of disabled ('off') the zero-copy sends of data for the H1
+  multiplexer. It is enabled by default.
+
+  See also: tune.disable-zero-copy-forwarding, tune.h1.zero-copy-fwd-recv
+
 tune.h2.be.initial-window-size <number>
   Sets the HTTP/2 initial window size for outgoing connections, which is the
   number of bytes the server can respond before waiting for an acknowledgment
index 99f3bd51e80eded6c4ca78966e3b3c27d34c3cfe..d2acee6a36a1eb8020a8ba32c139322a4e7f3d59 100644 (file)
@@ -4409,6 +4409,12 @@ static size_t h1_nego_ff(struct stconn *sc, struct buffer *input, size_t count,
 
        TRACE_ENTER(H1_EV_STRM_SEND, h1c->conn, h1s, 0, (size_t[]){count});
 
+
+       if (global.tune.no_zero_copy_fwd & NO_ZERO_COPY_FWD_H1_SND) {
+               h1s->sd->iobuf.flags |= IOBUF_FL_NO_FF;
+               goto out;
+       }
+
        /* TODO: add check on curr_len if CLEN */
 
        if (h1m->flags & H1_MF_CHNK) {
@@ -4573,6 +4579,11 @@ static int h1_fastfwd(struct stconn *sc, unsigned int count, unsigned int flags)
 
        TRACE_ENTER(H1_EV_STRM_RECV, h1c->conn, h1s, 0, (size_t[]){count});
 
+       if (global.tune.no_zero_copy_fwd & NO_ZERO_COPY_FWD_H1_RCV) {
+               h1c->flags = (h1c->flags & ~H1C_F_WANT_FASTFWD) | H1C_F_CANT_FASTFWD;
+               goto end;
+       }
+
        if (h1m->state != H1_MSG_DATA && h1m->state != H1_MSG_TUNNEL) {
                h1c->flags &= ~H1C_F_WANT_FASTFWD;
                TRACE_STATE("Cannot fast-forwad data now !(msg_data|msg_tunnel)", H1_EV_STRM_RECV, h1c->conn, h1s);
@@ -5231,11 +5242,51 @@ static int cfg_parse_h1_headers_case_adjust_file(char **args, int section_type,
         return 0;
 }
 
+/* config parser for global "tune.h1.zero-copy-fwd-recv" */
+static int cfg_parse_h1_zero_copy_fwd_rcv(char **args, int section_type, struct proxy *curpx,
+                                          const struct proxy *defpx, const char *file, int line,
+                                          char **err)
+{
+       if (too_many_args(1, args, err, NULL))
+               return -1;
+
+       if (strcmp(args[1], "on") == 0)
+               global.tune.no_zero_copy_fwd &= ~NO_ZERO_COPY_FWD_H1_RCV;
+       else if (strcmp(args[1], "off") == 0)
+               global.tune.no_zero_copy_fwd |= NO_ZERO_COPY_FWD_H1_RCV;
+       else {
+               memprintf(err, "'%s' expects 'on' or 'off'.", args[0]);
+               return -1;
+       }
+       return 0;
+}
+
+/* config parser for global "tune.h1.zero-copy-fwd-send" */
+static int cfg_parse_h1_zero_copy_fwd_snd(char **args, int section_type, struct proxy *curpx,
+                                         const struct proxy *defpx, const char *file, int line,
+                                         char **err)
+{
+       if (too_many_args(1, args, err, NULL))
+               return -1;
+
+       if (strcmp(args[1], "on") == 0)
+               global.tune.no_zero_copy_fwd &= ~NO_ZERO_COPY_FWD_H1_SND;
+       else if (strcmp(args[1], "off") == 0)
+               global.tune.no_zero_copy_fwd |= NO_ZERO_COPY_FWD_H1_SND;
+       else {
+               memprintf(err, "'%s' expects 'on' or 'off'.", args[0]);
+               return -1;
+       }
+       return 0;
+}
+
 /* config keyword parsers */
 static struct cfg_kw_list cfg_kws = {{ }, {
                { CFG_GLOBAL, "h1-accept-payload-with-any-method", cfg_parse_h1_accept_payload_with_any_method },
                { CFG_GLOBAL, "h1-case-adjust", cfg_parse_h1_header_case_adjust },
                { CFG_GLOBAL, "h1-case-adjust-file", cfg_parse_h1_headers_case_adjust_file },
+               { CFG_GLOBAL, "tune.h1.zero-copy-fwd-recv", cfg_parse_h1_zero_copy_fwd_rcv },
+               { CFG_GLOBAL, "tune.h1.zero-copy-fwd-send", cfg_parse_h1_zero_copy_fwd_snd },
                { 0, NULL, NULL },
        }
 };