]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: stream-int: make failed splice_in always subscribe to recv
authorWilly Tarreau <w@1wt.eu>
Thu, 15 Nov 2018 13:33:05 +0000 (14:33 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 15 Nov 2018 13:39:03 +0000 (14:39 +0100)
As part of the changes that went into 1.9-dev2 regarding the polling
modifications, the changes consecutive to the removal of the wait_list
from the conn_streams (commit 71384551a) made si_cs_recv() occasionally
return without subscribing to receive events, causing spliced transfers
to randomly fail if the client was at least as fast as the server. This
may remain unnoticed on most deployments since servers are usually close
to haproxy with higher bandwidth than clients have, resulting in buffers
always being full.

In order to reproduce his effect, it is better to do it on the local
machine and to transfer very large objects (hundreds of gigs) over a
single connection, to see it suddenly stall after a few tens of gigs.
Now with this fix it's fine even after 3 TB over a single connection.

No backport is needed.

src/stream_interface.c

index b82f68cd84636e353d7f3a23a87dc9c8f76fe89c..a37a9f6ed1d438c7ee96af8736a2613f021be08f 100644 (file)
@@ -652,7 +652,7 @@ int si_cs_send(struct conn_stream *cs)
         * in the normal buffer.
         */
        if (!co_data(oc))
-               return did_send;
+               goto end;
 
        /* when we're here, we already know that there is no spliced
         * data left, and that there are sendable buffered data.
@@ -699,6 +699,7 @@ int si_cs_send(struct conn_stream *cs)
                         */
                }
        }
+ end:
        /* We couldn't send all of our data, let the mux know we'd like to send more */
        if (!channel_is_empty(oc))
                conn->mux->subscribe(cs, SUB_CAN_SEND, &si->wait_event);