From d656ac7e13266c3725e196c510eb0871d8792547 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 28 Nov 2023 09:15:26 +0100 Subject: [PATCH] OPTIM: mux-h2/zero-copy: don't allocate more buffers per connections than streams It's the exact same as commit 0a7ab7067 ("OPTIM: mux-h2: don't allocate more buffers per connections than streams"), but for the zero-copy case this time. Previously it was only done on the regular snd_buf() path, but this one is needed as well. A transfer on 16 parallel streams now consumes half of the memory, and a single stream consumes much less. An alternate approach would be worth investigating in the future, based on the same principle as the CF_STREAMER_FAST at the higher level: in short, by monitoring how many mux buffers we write at once before refilling them, we would get an idea of how much is worth keeping in buffers max, given that anything beyond would just waste memory. Some tests show that a single buffer already seems almost as good, except for single-stream transfers, which is why it's worth spending more time on this. --- src/mux_h2.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/mux_h2.c b/src/mux_h2.c index e17e47cc6..c6b30ff54 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -6967,6 +6967,16 @@ static size_t h2_nego_ff(struct stconn *sc, struct buffer *input, size_t count, mbuf = br_tail(h2c->mbuf); retry: + if (br_count(h2c->mbuf) > h2c->nb_streams) { + /* more buffers than streams allocated, pointless + * to continue, we'd use more RAM for no reason. + */ + h2s->flags |= H2_SF_BLK_MROOM; + h2s->sd->iobuf.flags |= IOBUF_FL_FF_BLOCKED; + TRACE_STATE("waiting for room in output buffer", H2_EV_TX_FRAME|H2_EV_TX_DATA|H2_EV_H2S_BLK, h2c->conn, h2s); + goto end; + } + if (!h2_get_buf(h2c, mbuf)) { h2c->flags |= H2_CF_MUX_MALLOC; h2s->flags |= H2_SF_BLK_MROOM;