From: Christopher Faulet Date: Mon, 4 Dec 2023 14:06:06 +0000 (+0100) Subject: MINOR: mux-h1: Add global option to enable/disable zero-copy forwarding X-Git-Tag: v2.9.0~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f5e73024e97dd56e3e848b66335db1aba1a4f362;p=thirdparty%2Fhaproxy.git MINOR: mux-h1: Add global option to enable/disable zero-copy forwarding 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. --- diff --git a/doc/configuration.txt b/doc/configuration.txt index b3bf728c56..cf794fa039 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -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 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 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 diff --git a/src/mux_h1.c b/src/mux_h1.c index 99f3bd51e8..d2acee6a36 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -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 }, } };