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.
This commit is contained in:
Willy Tarreau 2013-01-07 16:57:09 +01:00
parent baf2a500a1
commit b6daedd46c
2 changed files with 18 additions and 0 deletions

View File

@ -243,6 +243,7 @@ ifeq ($(TARGET),linux2628)
USE_ACCEPT4 = implicit USE_ACCEPT4 = implicit
USE_FUTEX = implicit USE_FUTEX = implicit
USE_CPU_AFFINITY= implicit USE_CPU_AFFINITY= implicit
ASSUME_SPLICE_WORKS= implicit
else else
ifeq ($(TARGET),solaris) ifeq ($(TARGET),solaris)
# This is for Solaris 8 # This is for Solaris 8
@ -449,6 +450,11 @@ OPTIONS_CFLAGS += -DUSE_MY_SPLICE
BUILD_OPTIONS += $(call ignore_implicit,USE_MY_SPLICE) BUILD_OPTIONS += $(call ignore_implicit,USE_MY_SPLICE)
endif endif
ifneq ($(ASSUME_SPLICE_WORKS),)
OPTIONS_CFLAGS += -DASSUME_SPLICE_WORKS
BUILD_OPTIONS += $(call ignore_implicit,ASSUME_SPLICE_WORKS)
endif
ifneq ($(USE_ACCEPT4),) ifneq ($(USE_ACCEPT4),)
OPTIONS_CFLAGS += -DUSE_ACCEPT4 OPTIONS_CFLAGS += -DUSE_ACCEPT4
BUILD_OPTIONS += $(call ignore_implicit,USE_ACCEPT4) BUILD_OPTIONS += $(call ignore_implicit,USE_ACCEPT4)

View File

@ -54,6 +54,12 @@
* infinite forwarding */ * infinite forwarding */
#define MAX_SPLICE_AT_ONCE (1<<30) #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 : /* Returns :
* -1 if splice() is not supported * -1 if splice() is not supported
* >= 0 to report the amount of spliced bytes. * >= 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) int raw_sock_to_pipe(struct connection *conn, struct pipe *pipe, unsigned int count)
{ {
#ifndef ASSUME_SPLICE_WORKS
static int splice_detects_close; static int splice_detects_close;
#endif
int ret; int ret;
int retval = 0; 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 * recent kernels (>= 2.6.27.13). If we notice
* it works, we store the info for later use. * it works, we store the info for later use.
*/ */
#ifndef ASSUME_SPLICE_WORKS
splice_detects_close = 1; splice_detects_close = 1;
#endif
goto out_read0; 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 * try to fall back to the normal recv scheme
* which will be able to deal with the situation. * which will be able to deal with the situation.
*/ */
#ifndef ASSUME_SPLICE_WORKS
if (splice_detects_close) if (splice_detects_close)
#endif
__conn_data_poll_recv(conn); /* we know for sure that it's EAGAIN */ __conn_data_poll_recv(conn); /* we know for sure that it's EAGAIN */
break; break;
} }