diff --git a/include/types/global.h b/include/types/global.h index 7862e91c6..0c3c8adb1 100644 --- a/include/types/global.h +++ b/include/types/global.h @@ -51,6 +51,8 @@ #define GTUNE_USE_EPOLL (1<<2) #define GTUNE_USE_KQUEUE (1<<3) #define GTUNE_USE_SEPOLL (1<<4) +/* platform-specific options */ +#define GTUNE_USE_SPLICE (1<<5) /* FIXME : this will have to be redefined correctly */ diff --git a/src/backend.c b/src/backend.c index 573e7994f..be3dcf6a8 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1675,7 +1675,8 @@ int connect_server(struct session *s) } #ifdef CONFIG_HAP_TCPSPLICE - if ((s->fe->options & s->be->options) & PR_O_TCPSPLICE) { + if ((global.tune.options & GTUNE_USE_SPLICE) && + (s->fe->options & s->be->options) & PR_O_TCPSPLICE) { /* TCP splicing supported by both FE and BE */ tcp_splice_initfd(s->req->prod->fd, fd); } diff --git a/src/cfgparse.c b/src/cfgparse.c index 6defe9e92..f98d07e0a 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -302,6 +302,9 @@ int cfg_parse_global(const char *file, int linenum, char **args, int inv) else if (!strcmp(args[0], "nopoll")) { global.tune.options &= ~GTUNE_USE_POLL; } + else if (!strcmp(args[0], "nosplice")) { + global.tune.options &= ~GTUNE_USE_SPLICE; + } else if (!strcmp(args[0], "quiet")) { global.mode |= MODE_QUIET; } diff --git a/src/haproxy.c b/src/haproxy.c index 0c16e14f9..abf6eef2b 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -220,6 +220,9 @@ void usage(char *name) #endif #if defined(ENABLE_POLL) " -dp disables poll() usage even when available\n" +#endif +#if defined(CONFIG_HAP_LINUX_SPLICE) || defined(CONFIG_HAP_TCPSPLICE) + " -dS disables splice usage (broken on old kernels)\n" #endif " -sf/-st [pid ]* finishes/terminates old pids. Must be last arguments.\n" "\n", @@ -421,6 +424,9 @@ void init(int argc, char **argv) #if defined(ENABLE_KQUEUE) global.tune.options |= GTUNE_USE_KQUEUE; #endif +#if defined(CONFIG_HAP_LINUX_SPLICE) || defined(CONFIG_HAP_TCPSPLICE) + global.tune.options |= GTUNE_USE_SPLICE; +#endif pid = getpid(); progname = *argv; @@ -456,6 +462,10 @@ void init(int argc, char **argv) #if defined(ENABLE_KQUEUE) else if (*flag == 'd' && flag[1] == 'k') global.tune.options &= ~GTUNE_USE_KQUEUE; +#endif +#if defined(CONFIG_HAP_LINUX_SPLICE) || defined(CONFIG_HAP_TCPSPLICE) + else if (*flag == 'd' && flag[1] == 'S') + global.tune.options &= ~GTUNE_USE_SPLICE; #endif else if (*flag == 'V') arg_mode |= MODE_VERBOSE; @@ -1011,11 +1021,12 @@ int main(int argc, char **argv) } #ifdef CONFIG_HAP_TCPSPLICE - if (global.last_checks & LSTCHK_TCPSPLICE) { + if ((global.tune.options & GTUNE_USE_SPLICE) && (global.last_checks & LSTCHK_TCPSPLICE)) { if (tcp_splice_start() < 0) { Alert("[%s.main()] Cannot enable tcp_splice.\n" " Make sure you have enough permissions and that the module is loadable.\n" - " Alternatively, you may disable the 'tcpsplice' options in the configuration.\n" + " Alternatively, you may disable the 'tcpsplice' options in the configuration\n" + " or add 'nosplice' in the global section, or start with '-dS'.\n" "", argv[0], global.gid); protocol_unbind_all(); exit(1); diff --git a/src/session.c b/src/session.c index c7dbf6f8a..d1bc052aa 100644 --- a/src/session.c +++ b/src/session.c @@ -32,6 +32,9 @@ #include #include +#ifdef CONFIG_HAP_TCPSPLICE +#include +#endif struct pool_head *pool2_session; struct list sessions; @@ -315,7 +318,8 @@ void sess_establish(struct session *s, struct stream_interface *si) s->do_log(s); } #ifdef CONFIG_HAP_TCPSPLICE - if ((s->fe->options & s->be->options) & PR_O_TCPSPLICE) { + if ((global.tune.options & GTUNE_USE_SPLICE) && + (s->fe->options & s->be->options) & PR_O_TCPSPLICE) { /* TCP splicing supported by both FE and BE */ tcp_splice_splicefd(req->prod->fd, si->fd, 0); } @@ -761,6 +765,7 @@ void process_session(struct task *t, int *next) !s->req->analysers && !(s->req->flags & BF_HIJACK)) { /* check if it is wise to enable kernel splicing on the request buffer */ if (!(s->req->flags & BF_KERN_SPLICING) && + (global.tune.options & GTUNE_USE_SPLICE) && (pipes_used < global.maxpipes) && (((s->fe->options2|s->be->options2) & PR_O2_SPLIC_REQ) || (((s->fe->options2|s->be->options2) & PR_O2_SPLIC_AUT) && @@ -884,6 +889,7 @@ void process_session(struct task *t, int *next) !s->rep->analysers && !(s->rep->flags & BF_HIJACK)) { /* check if it is wise to enable kernel splicing on the response buffer */ if (!(s->rep->flags & BF_KERN_SPLICING) && + (global.tune.options & GTUNE_USE_SPLICE) && (pipes_used < global.maxpipes) && (((s->fe->options2|s->be->options2) & PR_O2_SPLIC_RTR) || (((s->fe->options2|s->be->options2) & PR_O2_SPLIC_AUT) &&