From 3ab68cf0ae4f12446d8c3536bff3f98cc681eef9 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sun, 25 Jan 2009 16:03:28 +0100 Subject: [PATCH] [MEDIUM] splice: add the global "nosplice" option Setting "nosplice" in the global section will disable the use of TCP splicing (both tcpsplice and linux 2.6 splice). The same will be achieved using the "-dS" parameter on the command line. --- include/types/global.h | 2 ++ src/backend.c | 3 ++- src/cfgparse.c | 3 +++ src/haproxy.c | 15 +++++++++++++-- src/session.c | 8 +++++++- 5 files changed, 27 insertions(+), 4 deletions(-) diff --git a/include/types/global.h b/include/types/global.h index 7862e91c69..0c3c8adb1b 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 573e7994fa..be3dcf6a84 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 6defe9e927..f98d07e0aa 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 0c16e14f97..abf6eef2be 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 c7dbf6f8a9..d1bc052aa3 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 @@ resync_stream_interface: !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 @@ resync_stream_interface: !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) && -- 2.39.5