]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
OPTIM: splicing: use splice() for the last block when relevant
authorWilly Tarreau <w@1wt.eu>
Thu, 18 Jul 2013 20:21:54 +0000 (22:21 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 22 Jul 2013 07:31:56 +0000 (09:31 +0200)
Splicing is avoided for small transfers because it's generally cheaper
to perform a couple of recv+send calls than pipe+splice+splice. This
has the consequence that the last chunk of a large transfer may be
transferred using recv+send if it's less than 4 kB. But when the pipe
is already set up, it's better to use splice() to read the pending data,
since they will get merged with the pending ones. This is what now
happens everytime the reader is slower than the writer.

Note that this change alone could have fixed most of the CPU hog bug,
except at the end when only the close was pending.

src/stream_interface.c

index 905612cef5dea28df849f976f4755f1de7fcaad4..33f1d0efc026d4f5865a6b7076ef4fedd3bc0b02 100644 (file)
@@ -934,7 +934,8 @@ static void si_conn_recv_cb(struct connection *conn)
         * using a buffer.
         */
        if (conn->xprt->rcv_pipe &&
-           chn->to_forward >= MIN_SPLICE_FORWARD && chn->flags & CF_KERN_SPLICING) {
+           (chn->pipe || chn->to_forward >= MIN_SPLICE_FORWARD) &&
+           chn->flags & CF_KERN_SPLICING) {
                if (buffer_not_empty(chn->buf)) {
                        /* We're embarrassed, there are already data pending in
                         * the buffer and we don't want to have them at two