aboutsummaryrefslogtreecommitdiff
path: root/net/haproxy/patches/023-BUG-MEDIUM-connection-add-a-mux-flag-to-indicate-splice-usability.patch
diff options
context:
space:
mode:
Diffstat (limited to 'net/haproxy/patches/023-BUG-MEDIUM-connection-add-a-mux-flag-to-indicate-splice-usability.patch')
-rw-r--r--net/haproxy/patches/023-BUG-MEDIUM-connection-add-a-mux-flag-to-indicate-splice-usability.patch145
1 files changed, 0 insertions, 145 deletions
diff --git a/net/haproxy/patches/023-BUG-MEDIUM-connection-add-a-mux-flag-to-indicate-splice-usability.patch b/net/haproxy/patches/023-BUG-MEDIUM-connection-add-a-mux-flag-to-indicate-splice-usability.patch
deleted file mode 100644
index da4548eba..000000000
--- a/net/haproxy/patches/023-BUG-MEDIUM-connection-add-a-mux-flag-to-indicate-splice-usability.patch
+++ /dev/null
@@ -1,145 +0,0 @@
-commit 7195d4b9396687e67da196cb92ef25b4bd6938d8
-Author: Willy Tarreau <w@1wt.eu>
-Date: Fri Jan 17 16:19:34 2020 +0100
-
- BUG/MEDIUM: connection: add a mux flag to indicate splice usability
-
- Commit c640ef1a7d ("BUG/MINOR: stream-int: avoid calling rcv_buf() when
- splicing is still possible") fixed splicing in TCP and legacy mode but
- broke it badly in HTX mode.
-
- What happens in HTX mode is that the channel's to_forward value remains
- set to CHN_INFINITE_FORWARD during the whole transfer, and as such it is
- not a reliable signal anymore to indicate whether more data are expected
- or not. Thus, when data are spliced out of the mux using rcv_pipe(), even
- when the end is reached (that only the mux knows about), the call to
- rcv_buf() to get the final HTX blocks completing the message were skipped
- and there was often no new event to wake this up, resulting in transfer
- timeouts at the end of large objects.
-
- All this goes down to the fact that the channel has no more information
- about whether it can splice or not despite being the one having to take
- the decision to call rcv_pipe() or not. And we cannot afford to call
- rcv_buf() inconditionally because, as the commit above showed, this
- reduces the forwarding performance by 2 to 3 in TCP and legacy modes
- due to data lying in the buffer preventing splicing from being used
- later.
-
- The approach taken by this patch consists in offering the muxes the ability
- to report a bit more information to the upper layers via the conn_stream.
- This information could simply be to indicate that more data are awaited
- but the real need being to distinguish splicing and receiving, here
- instead we clearly report the mux's willingness to be called for splicing
- or not. Hence the flag's name, CS_FL_MAY_SPLICE.
-
- The mux sets this flag when it knows that its buffer is empty and that
- data waiting past what is currently known may be spliced, and clears it
- when it knows there's no more data or that the caller must fall back to
- rcv_buf() instead.
-
- The stream-int code now uses this to determine if splicing may be used
- or not instead of looking at the rcv_pipe() callbacks through the whole
- chain. And after the rcv_pipe() call, it checks the flag again to decide
- whether it may safely skip rcv_buf() or not.
-
- All this bitfield dance remains a bit complex and it starts to appear
- obvious that splicing vs reading should be a decision of the mux based
- on permission granted by the data layer. This would however increase
- the API's complexity but definitely need to be thought about, and should
- even significantly simplify the data processing layer.
-
- The way it was integrated in mux-h1 will also result in no more calls
- to rcv_pipe() on chunked encoded data, since these ones are currently
- disabled at the mux level. However once the issue with chunks+splice
- is fixed, it will be important to explicitly check for curr_len|CHNK
- to set MAY_SPLICE, so that we don't call rcv_buf() after each chunk.
-
- This fix must be backported to 2.1 and 2.0.
-
- (cherry picked from commit 17ccd1a3560a634a17d276833ff41b8063b72206)
- Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
-
-diff --git a/include/types/connection.h b/include/types/connection.h
-index 165a683ae..f2aa63c33 100644
---- a/include/types/connection.h
-+++ b/include/types/connection.h
-@@ -95,7 +95,7 @@ enum {
- CS_FL_EOS = 0x00001000, /* End of stream delivered to data layer */
- /* unused: 0x00002000 */
- CS_FL_EOI = 0x00004000, /* end-of-input reached */
-- /* unused: 0x00008000 */
-+ CS_FL_MAY_SPLICE = 0x00008000, /* caller may use rcv_pipe() only if this flag is set */
- CS_FL_WAIT_FOR_HS = 0x00010000, /* This stream is waiting for handhskae */
- CS_FL_KILL_CONN = 0x00020000, /* must kill the connection when the CS closes */
-
-diff --git a/src/mux_h1.c b/src/mux_h1.c
-index d93a7eab5..b76a58fe4 100644
---- a/src/mux_h1.c
-+++ b/src/mux_h1.c
-@@ -489,6 +489,9 @@ static struct conn_stream *h1s_new_cs(struct h1s *h1s)
- if (h1s->flags & H1S_F_NOT_FIRST)
- cs->flags |= CS_FL_NOT_FIRST;
-
-+ if (global.tune.options & GTUNE_USE_SPLICE)
-+ cs->flags |= CS_FL_MAY_SPLICE;
-+
- if (stream_create_from_cs(cs) < 0) {
- TRACE_DEVEL("leaving on stream creation failure", H1_EV_STRM_NEW|H1_EV_STRM_END|H1_EV_STRM_ERR, h1s->h1c->conn, h1s);
- goto err;
-@@ -1275,6 +1278,11 @@ static size_t h1_process_data(struct h1s *h1s, struct h1m *h1m, struct htx **htx
- goto end;
- }
-
-+ if (h1m->state == H1_MSG_DATA && h1m->curr_len && h1s->cs)
-+ h1s->cs->flags |= CS_FL_MAY_SPLICE;
-+ else if (h1s->cs)
-+ h1s->cs->flags &= ~CS_FL_MAY_SPLICE;
-+
- *ofs += ret;
-
- end:
-@@ -2725,6 +2733,9 @@ static int h1_rcv_pipe(struct conn_stream *cs, struct pipe *pipe, unsigned int c
- TRACE_STATE("read0 on connection", H1_EV_STRM_RECV, cs->conn, h1s);
- }
-
-+ if (h1m->state != H1_MSG_DATA || !h1m->curr_len)
-+ cs->flags &= ~CS_FL_MAY_SPLICE;
-+
- TRACE_LEAVE(H1_EV_STRM_RECV, cs->conn, h1s);
- return ret;
- }
-diff --git a/src/mux_pt.c b/src/mux_pt.c
-index 6cbc689ce..2ac7d4715 100644
---- a/src/mux_pt.c
-+++ b/src/mux_pt.c
-@@ -111,6 +111,8 @@ static int mux_pt_init(struct connection *conn, struct proxy *prx, struct sessio
- conn->ctx = ctx;
- ctx->cs = cs;
- cs->flags |= CS_FL_RCV_MORE;
-+ if (global.tune.options & GTUNE_USE_SPLICE)
-+ cs->flags |= CS_FL_MAY_SPLICE;
- return 0;
-
- fail_free:
-diff --git a/src/stream_interface.c b/src/stream_interface.c
-index 012ac71e0..a2ea7d779 100644
---- a/src/stream_interface.c
-+++ b/src/stream_interface.c
-@@ -1268,7 +1268,7 @@ int si_cs_recv(struct conn_stream *cs)
- /* First, let's see if we may splice data across the channel without
- * using a buffer.
- */
-- if (conn->xprt->rcv_pipe && conn->mux->rcv_pipe &&
-+ if (cs->flags & CS_FL_MAY_SPLICE &&
- (ic->pipe || ic->to_forward >= MIN_SPLICE_FORWARD) &&
- ic->flags & CF_KERN_SPLICING) {
- if (c_data(ic)) {
-@@ -1327,7 +1327,7 @@ int si_cs_recv(struct conn_stream *cs)
- ic->pipe = NULL;
- }
-
-- if (ic->pipe && ic->to_forward && !(flags & CO_RFL_BUF_FLUSH)) {
-+ if (ic->pipe && ic->to_forward && !(flags & CO_RFL_BUF_FLUSH) && cs->flags & CS_FL_MAY_SPLICE) {
- /* don't break splicing by reading, but still call rcv_buf()
- * to pass the flag.
- */