diff --git a/doc/configuration.txt b/doc/configuration.txt index 33e4ab63bf..670b2e80e9 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -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 Sets the number of events that may be processed at once by an asynchronous diff --git a/include/haproxy/global-t.h b/include/haproxy/global-t.h index e302de45df..bb39baffce 100644 --- a/include/haproxy/global-t.h +++ b/include/haproxy/global-t.h @@ -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) @@ -85,6 +85,18 @@ #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 */ diff --git a/src/cfgparse-global.c b/src/cfgparse-global.c index a80ac854f6..540dda79b0 100644 --- a/src/cfgparse-global.c +++ b/src/cfgparse-global.c @@ -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; diff --git a/src/haproxy.c b/src/haproxy.c index 3b5b1719b2..e186325542 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -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') { diff --git a/src/stconn.c b/src/stconn.c index 59b4acf10a..63dd9bf1f3 100644 --- a/src/stconn.c +++ b/src/stconn.c @@ -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