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 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) &&