From b6daedd46ca527bcd16cb3d70a78e897761c33d3 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Mon, 7 Jan 2013 16:57:09 +0100 Subject: OPTIM: splice: assume by default that splice is working correctly Versions of splice between 2.6.25 and 2.6.27.12 were bogus and would return EAGAIN on incoming shutdowns. On these versions, we have to call recv() after such a return in order to find whether splice is OK or not. Since 2.6.27.13 we don't need to do this anymore, saving one useless recv() call after each splice() returning EAGAIN, and we can avoid this logic by defining ASSUME_SPLICE_WORKS. Building with linux2628 automatically enables splice and the flag above since the kernel is safe. People enabling splice for custom kernels will be able to disable this logic by hand too. --- Makefile | 6 ++++++ src/raw_sock.c | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/Makefile b/Makefile index fb6ce98..f1eed55 100644 --- a/Makefile +++ b/Makefile @@ -243,6 +243,7 @@ ifeq ($(TARGET),linux2628) USE_ACCEPT4 = implicit USE_FUTEX = implicit USE_CPU_AFFINITY= implicit + ASSUME_SPLICE_WORKS= implicit else ifeq ($(TARGET),solaris) # This is for Solaris 8 @@ -449,6 +450,11 @@ OPTIONS_CFLAGS += -DUSE_MY_SPLICE BUILD_OPTIONS += $(call ignore_implicit,USE_MY_SPLICE) endif +ifneq ($(ASSUME_SPLICE_WORKS),) +OPTIONS_CFLAGS += -DASSUME_SPLICE_WORKS +BUILD_OPTIONS += $(call ignore_implicit,ASSUME_SPLICE_WORKS) +endif + ifneq ($(USE_ACCEPT4),) OPTIONS_CFLAGS += -DUSE_ACCEPT4 BUILD_OPTIONS += $(call ignore_implicit,USE_ACCEPT4) diff --git a/src/raw_sock.c b/src/raw_sock.c index 9528911..ad4a0aa 100644 --- a/src/raw_sock.c +++ b/src/raw_sock.c @@ -54,6 +54,12 @@ * infinite forwarding */ #define MAX_SPLICE_AT_ONCE (1<<30) +/* Versions of splice between 2.6.25 and 2.6.27.12 were bogus and would return EAGAIN + * on incoming shutdowns. On these versions, we have to call recv() after such a return + * in order to find whether splice is OK or not. Since 2.6.27.13 we don't need to do + * this anymore, and we can avoid this logic by defining ASSUME_SPLICE_WORKS. + */ + /* Returns : * -1 if splice() is not supported * >= 0 to report the amount of spliced bytes. @@ -62,7 +68,9 @@ */ int raw_sock_to_pipe(struct connection *conn, struct pipe *pipe, unsigned int count) { +#ifndef ASSUME_SPLICE_WORKS static int splice_detects_close; +#endif int ret; int retval = 0; @@ -95,7 +103,9 @@ int raw_sock_to_pipe(struct connection *conn, struct pipe *pipe, unsigned int co * recent kernels (>= 2.6.27.13). If we notice * it works, we store the info for later use. */ +#ifndef ASSUME_SPLICE_WORKS splice_detects_close = 1; +#endif goto out_read0; } @@ -125,7 +135,9 @@ int raw_sock_to_pipe(struct connection *conn, struct pipe *pipe, unsigned int co * try to fall back to the normal recv scheme * which will be able to deal with the situation. */ +#ifndef ASSUME_SPLICE_WORKS if (splice_detects_close) +#endif __conn_data_poll_recv(conn); /* we know for sure that it's EAGAIN */ break; } -- 1.7.12.2.21.g234cd45.dirty