First, we must not emit any warning if splicing is not configured and the
global maxpipes value is 0. Then we must not remove GTUNE_USE_SPLICE flag
when we fail to allocate the haterm master pipe. Instead, we test it when we
negociate with the opposite side, to properly exclude the splicing if it is
not usable.
No backport needed.
#include <haproxy/buf.h>
#include <haproxy/cfgparse.h>
#include <haproxy/chunk.h>
#include <haproxy/buf.h>
#include <haproxy/cfgparse.h>
#include <haproxy/chunk.h>
+#include <haproxy/compat.h>
#include <haproxy/global.h>
#include <haproxy/hstream-t.h>
#include <haproxy/http_htx.h>
#include <haproxy/global.h>
#include <haproxy/hstream-t.h>
#include <haproxy/http_htx.h>
nego_flags |= NEGO_FF_FL_EXACT_SIZE;
#if defined(USE_LINUX_SPLICE)
if ((global.tune.options & GTUNE_USE_SPLICE) &&
nego_flags |= NEGO_FF_FL_EXACT_SIZE;
#if defined(USE_LINUX_SPLICE)
if ((global.tune.options & GTUNE_USE_SPLICE) &&
!(sd->iobuf.flags & IOBUF_FL_NO_SPLICING) &&
!(hs->flags & HS_ST_OPT_NO_SPLICING))
nego_flags |= NEGO_FF_FL_MAY_SPLICE;
!(sd->iobuf.flags & IOBUF_FL_NO_SPLICING) &&
!(hs->flags & HS_ST_OPT_NO_SPLICING))
nego_flags |= NEGO_FF_FL_MAY_SPLICE;
#if defined(USE_LINUX_SPLICE)
if (sd->iobuf.pipe) {
#if defined(USE_LINUX_SPLICE)
if (sd->iobuf.pipe) {
+ BUG_ON(master_pipesize == 0 || master_pipe == NULL);
if (len > master_pipesize)
len = master_pipesize;
ret = tee(master_pipe->cons, sd->iobuf.pipe->prod, len, SPLICE_F_NONBLOCK);
if (len > master_pipesize)
len = master_pipesize;
ret = tee(master_pipe->cons, sd->iobuf.pipe->prod, len, SPLICE_F_NONBLOCK);
#if defined(USE_LINUX_SPLICE)
static void hstream_init_splicing(void)
{
#if defined(USE_LINUX_SPLICE)
static void hstream_init_splicing(void)
{
- if (!(global.tune.options & GTUNE_USE_SPLICE))
+ unsigned int pipesize = 65536 * 5 / 4;
+
+ if (!(global.tune.options & GTUNE_USE_SPLICE) || !global.maxpipes)
- if (!global.tune.pipesize)
- global.tune.pipesize = 65536 * 5 / 4;
+ if (global.tune.pipesize)
+ pipesize = global.tune.pipesize;
master_pipe = get_pipe();
if (master_pipe) {
master_pipe = get_pipe();
if (master_pipe) {
.iov_len = sizeof(common_response) };
int total, ret;
.iov_len = sizeof(common_response) };
int total, ret;
+#ifdef F_SETPIPE_SZ
+ fcntl(master_pipe->cons, F_SETPIPE_SZ, pipesize);
+#endif
total = ret = 0;
do {
ret = vmsplice(master_pipe->prod, &v, 1, SPLICE_F_NONBLOCK);
if (ret > 0)
total += ret;
total = ret = 0;
do {
ret = vmsplice(master_pipe->prod, &v, 1, SPLICE_F_NONBLOCK);
if (ret > 0)
total += ret;
- } while (ret > 0 && total < global.tune.pipesize);
+ } while (ret > 0 && total < pipesize);
- if (master_pipesize < global.tune.pipesize) {
+ if (master_pipesize < pipesize) {
if (master_pipesize < 60*1024) {
/* Older kernels were limited to around 60-61 kB */
if (master_pipesize < 60*1024) {
/* Older kernels were limited to around 60-61 kB */
- ha_warning("Failed to vmsplice response buffer after %lu bytes, splicing disabled\n", master_pipesize);
- global.tune.options &= ~GTUNE_USE_SPLICE;
+ ha_warning("Failed to vmsplice haterm mastre pipe after %lu bytes, splicing disabled for haterm\n", master_pipesize);
put_pipe(master_pipe);
master_pipe = NULL;
put_pipe(master_pipe);
master_pipe = NULL;
- ha_warning("Splicing is limited to %lu bytes (too old kernel)\n", master_pipesize);
+ ha_warning("Splicing in haterm is limited to %lu bytes (too old kernel)\n", master_pipesize);
- else {
- ha_warning("Unable to allocate master pipe for splicing, splicing disabled\n");
- global.tune.options &= ~GTUNE_USE_SPLICE;
- }
+ else
+ ha_warning("Unable to allocate haterm master pipe for splicing, splicing disabled for haterm\n");
}
static void hstream_deinit(void)
}
static void hstream_deinit(void)