BUG/MINOR: mux-h2: set CO_SFL_STREAMER when sending lots of data

Emeric noticed that h2 bit-rate performance was always slightly lower
than h1 when the CPU is saturated. Strace showed that we were always
data in 2kB chunks, corresponding to the max_record size. What's
happening is that when this mechanism of dynamic record size was
introduced, the STREAMER flag at the stream level was relied upon.
Since all this was moved to the muxes, the flag has to be passed as
an argument to the snd_buf() function, but the mux h2 did not use it
despite a comment mentioning it, probably because before the multi-buf
it was not easy to figure the status of the buffer.

The solution here consists in checking if the mbuf is congested or not,
by checking if it has more than one buffer allocated. If so we set the
CO_SFL_STREAMER flag, otherwise we don't. This way moderate size
exchanges continue to be made over small chunks, but downloads will
be able to use the large ones.

While it could be backported to all supported versions, it would be
better to limit it to the last LTS, so let's do it for 2.7 and 2.6 only.
This patch requires previous commit "MINOR: buffer: add br_single() to
check if a buffer ring has more than one buf".

(cherry picked from commit 14ea98af73)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 558ac459de1294ced755ace5efffdb7036baac58)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
This commit is contained in:
Willy Tarreau 2023-03-16 17:30:30 +01:00 committed by Christopher Faulet
parent be35f2a511
commit 14e256dd6b

View File

@ -3948,6 +3948,16 @@ static int h2_send(struct h2c *h2c)
if (h2c->flags & (H2_CF_MUX_MFULL | H2_CF_DEM_MBUSY | H2_CF_DEM_MROOM))
flags |= CO_SFL_MSG_MORE;
if (!br_single(h2c->mbuf)) {
/* usually we want to emit small TLS records to speed
* up the decoding on the client. That's what is being
* done by default. However if there is more than one
* buffer being allocated, we're streaming large data
* so we stich to large records.
*/
flags |= CO_SFL_STREAMER;
}
for (buf = br_head(h2c->mbuf); b_size(buf); buf = br_del_head(h2c->mbuf)) {
if (b_data(buf)) {
int ret = conn->xprt->snd_buf(conn, conn->xprt_ctx, buf, b_data(buf), flags);