]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: mux-h1: report that a buffer allocation succeeded
authorWilly Tarreau <w@1wt.eu>
Tue, 7 May 2024 15:31:32 +0000 (17:31 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 10 May 2024 15:18:13 +0000 (17:18 +0200)
When the buffer allocation callback is notified of a buffer availability,
it will now set a MAYALLOC flag in addition to clearing the ALLOC one, for
each of the 3 levels where we may fail an allocation. The flag will be
cleared upon a successful allocation. This will soon be used to decide to
re-allocate without waiting again in the queue. For now it has no effect.

There's just a trick, we need to clear the various *_ALLOC flags before
testing h1_recv_allowed() otherwise it will return false!

include/haproxy/mux_h1-t.h
src/mux_h1.c

index 5f4cd7f5f0ba7d132f460c893811e17bf5320471..a0b64a9da971f08a6baf6b818f8afd86da30077c 100644 (file)
 /* Flags indicating why writing output data are blocked */
 #define H1C_F_OUT_ALLOC      0x00000001 /* mux is blocked on lack of output buffer */
 #define H1C_F_OUT_FULL       0x00000002 /* mux is blocked on output buffer full */
-/* 0x00000004 - 0x00000008 unused */
+#define H1C_F_OUT_MAYALLOC   0x00000004 /* mux was just unblocked and may try to alloc out again */
 
 /* Flags indicating why reading input data are blocked. */
+#define H1C_F_IN_MAYALLOC    0x00000008 /* mux was just unblocked and may try to alloc in again */
 #define H1C_F_IN_ALLOC       0x00000010 /* mux is blocked on lack of input buffer */
 #define H1C_F_IN_FULL        0x00000020 /* mux is blocked on input buffer full */
 #define H1C_F_IN_SALLOC      0x00000040 /* mux is blocked on lack of stream's request buffer */
-/* 0x00000080 unused */
+#define H1C_F_IN_SMAYALLOC   0x00000080 /* mux was just unblocked and may try to alloc strm again */
 
 #define H1C_F_EOS            0x00000100 /* End-of-stream seen on the H1 connection (read0 detected) */
 #define H1C_F_ERR_PENDING    0x00000200 /* A write error was detected (block sends but not reads) */
@@ -66,12 +67,12 @@ static forceinline char *h1c_show_flags(char *buf, size_t len, const char *delim
        /* prologue */
        _(0);
        /* flags */
-       _(H1C_F_OUT_ALLOC, _(H1C_F_OUT_FULL,
-       _(H1C_F_IN_ALLOC, _(H1C_F_IN_FULL, _(H1C_F_IN_SALLOC,
+       _(H1C_F_OUT_ALLOC, _(H1C_F_OUT_FULL, _(H1C_F_OUT_MAYALLOC,
+       _(H1C_F_IN_MAYALLOC, _(H1C_F_IN_ALLOC, _(H1C_F_IN_FULL, _(H1C_F_IN_SALLOC, _(H1C_F_IN_SMAYALLOC,
        _(H1C_F_EOS, _(H1C_F_ERR_PENDING, _(H1C_F_ERROR,
        _(H1C_F_SILENT_SHUT, _(H1C_F_ABRT_PENDING, _(H1C_F_ABRTED,
        _(H1C_F_WANT_FASTFWD, _(H1C_F_WAIT_NEXT_REQ, _(H1C_F_UPG_H2C, _(H1C_F_CO_MSG_MORE,
-       _(H1C_F_CO_STREAMER, _(H1C_F_CANT_FASTFWD, _(H1C_F_IS_BACK))))))))))))))))));
+       _(H1C_F_CO_STREAMER, _(H1C_F_CANT_FASTFWD, _(H1C_F_IS_BACK)))))))))))))))))))));
        /* epilogue */
        _(~0U);
        return buf;
index 79b6afef717059037b30d022ed453393316aafe7..8515b36b9cc485022f056d56fb77fdbfe9ab523d 100644 (file)
@@ -501,21 +501,27 @@ static int h1_buf_available(void *target)
 {
        struct h1c *h1c = target;
 
-       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);
+       if (h1c->flags & H1C_F_IN_ALLOC) {
                h1c->flags &= ~H1C_F_IN_ALLOC;
-               tasklet_wakeup(h1c->wait_event.tasklet);
+               h1c->flags |=  H1C_F_IN_MAYALLOC;
        }
 
        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);
+               TRACE_STATE("unblocking h1s, obuf allocatable", H1_EV_TX_DATA|H1_EV_H1S_BLK|H1_EV_STRM_WAKE, h1c->conn, h1c->h1s);
                h1c->flags &= ~H1C_F_OUT_ALLOC;
+               h1c->flags |=  H1C_F_OUT_MAYALLOC;
                h1_wake_stream_for_send(h1c->h1s);
        }
 
        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);
+               TRACE_STATE("unblocking h1c, stream rxbuf allocatable", H1_EV_H1C_RECV|H1_EV_H1C_BLK|H1_EV_H1C_WAKE, h1c->conn);
                h1c->flags &= ~H1C_F_IN_SALLOC;
+               h1c->flags |=  H1C_F_IN_SMAYALLOC;
+               tasklet_wakeup(h1c->wait_event.tasklet);
+       }
+
+       if ((h1c->flags & H1C_F_IN_MAYALLOC) && h1_recv_allowed(h1c)) {
+               TRACE_STATE("unblocking h1c, ibuf allocatable", H1_EV_H1C_RECV|H1_EV_H1C_BLK|H1_EV_H1C_WAKE, h1c->conn);
                tasklet_wakeup(h1c->wait_event.tasklet);
        }
 
@@ -537,6 +543,9 @@ static inline struct buffer *h1_get_ibuf(struct h1c *h1c)
                b_queue(DB_MUX_RX, &h1c->buf_wait, h1c, h1_buf_available);
                h1c->flags |= H1C_F_IN_ALLOC;
        }
+       else
+               h1c->flags &= ~H1C_F_IN_MAYALLOC;
+
        return buf;
 }
 
@@ -552,6 +561,9 @@ static inline struct buffer *h1_get_obuf(struct h1c *h1c)
                b_queue(DB_MUX_TX, &h1c->buf_wait, h1c, h1_buf_available);
                h1c->flags |= H1C_F_OUT_ALLOC;
        }
+       else
+               h1c->flags &= ~H1C_F_OUT_MAYALLOC;
+
        return buf;
 }
 
@@ -568,6 +580,9 @@ static inline struct buffer *h1_get_rxbuf(struct h1s *h1s)
                b_queue(DB_SE_RX, &h1c->buf_wait, h1c, h1_buf_available);
                h1c->flags |= H1C_F_IN_SALLOC;
        }
+       else
+               h1c->flags &= ~H1C_F_IN_SMAYALLOC;
+
        return buf;
 }
 
@@ -932,7 +947,8 @@ static void h1s_destroy(struct h1s *h1s)
                h1_release_buf(h1c, &h1s->rxbuf);
 
                h1c->flags &= ~(H1C_F_WANT_FASTFWD|
-                               H1C_F_OUT_FULL|H1C_F_OUT_ALLOC|H1C_F_IN_SALLOC|
+                               H1C_F_OUT_FULL|H1C_F_OUT_ALLOC|H1C_F_OUT_MAYALLOC|
+                               H1C_F_IN_SALLOC|H1C_F_IN_SMAYALLOC|
                                H1C_F_CO_MSG_MORE|H1C_F_CO_STREAMER);
 
                if (!(h1c->flags & (H1C_F_EOS|H1C_F_ERR_PENDING|H1C_F_ERROR|H1C_F_ABRT_PENDING|H1C_F_ABRTED)) &&  /* No error/read0/abort */