MINOR: mux-h1: report that a buffer allocation succeeded

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!
This commit is contained in:
Willy Tarreau 2024-05-07 17:31:32 +02:00
parent cb2d758043
commit f552f79ba5
2 changed files with 28 additions and 11 deletions

View File

@ -31,13 +31,14 @@
/* 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;

View 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 */