From: Willy Tarreau Date: Tue, 28 Nov 2023 08:15:26 +0000 (+0100) Subject: OPTIM: mux-h2/zero-copy: don't allocate more buffers per connections than streams X-Git-Tag: v2.9-dev12~76 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d656ac7e13266c3725e196c510eb0871d8792547;p=thirdparty%2Fhaproxy.git 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. --- diff --git a/src/mux_h2.c b/src/mux_h2.c index e17e47cc64..c6b30ff547 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;