From: Willy Tarreau Date: Wed, 11 May 2011 18:47:24 +0000 (+0200) Subject: [OPTIM] stream_sock: don't use splice on too small payloads X-Git-Tag: v1.5-dev8~226 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=14acc7072ea1b31c897df27deea4f69cfc3a364e;p=thirdparty%2Fhaproxy.git [OPTIM] stream_sock: don't use splice on too small payloads It's more expensive to call splice() on short payloads than to use recv()+send(). One of the reasons is that doing a splice() involves allocating a pipe. One other reason is that the kernel will have to copy itself if we try to splice less than a page. So let's fix a short offset of 4kB below which we don't splice. A quick test shows that on chunked encoded data, with splice we had 6826 syscalls (1715 splice, 3461 recv, 1650 send) while with this patch, the same transfer resulted in 5793 syscalls (3896 recv, 1897 send). --- diff --git a/include/common/defaults.h b/include/common/defaults.h index d1ce0214ca..96e0f61b4e 100644 --- a/include/common/defaults.h +++ b/include/common/defaults.h @@ -97,6 +97,12 @@ #define MIN_RET_FOR_READ_LOOP 1460 #endif +// The minimum number of bytes to be forwarded that is worth trying to splice. +// Below 4kB, it's not worth allocating pipes nor pretending to zero-copy. +#ifndef MIN_SPLICE_FORWARD +#define MIN_SPLICE_FORWARD 4096 +#endif + // the max number of events returned in one call to poll/epoll. Too small a // value will cause lots of calls, and too high a value may cause high latency. #ifndef MAX_POLL_EVENTS diff --git a/src/stream_sock.c b/src/stream_sock.c index 5539cd205b..d4752845da 100644 --- a/src/stream_sock.c +++ b/src/stream_sock.c @@ -280,7 +280,7 @@ int stream_sock_read(int fd) { goto out_wakeup; #if defined(CONFIG_HAP_LINUX_SPLICE) - if (b->to_forward && b->flags & BF_KERN_SPLICING) { + if (b->to_forward >= MIN_SPLICE_FORWARD && b->flags & BF_KERN_SPLICING) { /* Under Linux, if FD_POLL_HUP is set, we have reached the end. * Since older splice() implementations were buggy and returned