]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: dynbuf/mux-h1: do not allocate the buffers in the callback
authorWilly Tarreau <w@1wt.eu>
Mon, 29 Apr 2024 07:20:17 +0000 (09:20 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 10 May 2024 15:18:13 +0000 (17:18 +0200)
One of the problematic designs with the buffer_wait mechanism is that
the callbacks pre-allocate the buffers and stay in the run queue for
a while, resulting in all of the few buffers being assigned to waiting
tasks instead of being all available to one task that needs them all at
once.

Here we simply stop doing this, the callback clears the waiting flags
and wakes the task up so that it has a chance of still finding some
buffers.

src/mux_h1.c

index 1fafdfd260b19afd2ac240edc98ca01430e8e526..79b6afef717059037b30d022ed453393316aafe7 100644 (file)
@@ -501,30 +501,25 @@ static int h1_buf_available(void *target)
 {
        struct h1c *h1c = target;
 
-       if ((h1c->flags & H1C_F_IN_ALLOC) && b_alloc(&h1c->ibuf, DB_MUX_RX)) {
+       if ((h1c->flags & H1C_F_IN_ALLOC) && h1_recv_allowed(h1c)) {
                TRACE_STATE("unblocking h1c, ibuf allocated", H1_EV_H1C_RECV|H1_EV_H1C_BLK|H1_EV_H1C_WAKE, h1c->conn);
                h1c->flags &= ~H1C_F_IN_ALLOC;
-               if (h1_recv_allowed(h1c))
-                       tasklet_wakeup(h1c->wait_event.tasklet);
-               return 1;
+               tasklet_wakeup(h1c->wait_event.tasklet);
        }
 
-       if ((h1c->flags & H1C_F_OUT_ALLOC) && b_alloc(&h1c->obuf, DB_MUX_TX)) {
+       if ((h1c->flags & H1C_F_OUT_ALLOC) && h1c->h1s) {
                TRACE_STATE("unblocking h1s, obuf allocated", H1_EV_TX_DATA|H1_EV_H1S_BLK|H1_EV_STRM_WAKE, h1c->conn, h1c->h1s);
                h1c->flags &= ~H1C_F_OUT_ALLOC;
-               if (h1c->h1s)
-                       h1_wake_stream_for_send(h1c->h1s);
-               return 1;
+               h1_wake_stream_for_send(h1c->h1s);
        }
 
-       if ((h1c->flags & H1C_F_IN_SALLOC) && h1c->h1s && b_alloc(&h1c->h1s->rxbuf, DB_SE_RX)) {
+       if ((h1c->flags & H1C_F_IN_SALLOC) && h1c->h1s) {
                TRACE_STATE("unblocking h1c, stream rxbuf allocated", H1_EV_H1C_RECV|H1_EV_H1C_BLK|H1_EV_H1C_WAKE, h1c->conn);
                h1c->flags &= ~H1C_F_IN_SALLOC;
                tasklet_wakeup(h1c->wait_event.tasklet);
-               return 1;
        }
 
-       return 0;
+       return 1;
 }
 
 /*