MINOR: buffers: Move small buffers management from quic to dynbuf part

Because small buffers were only used by QUIC streams, the pool used to alloc
these buffers was located in the quic code. However, their usage will be
extended to other parts. So, the small buffers pool was moved into the
dynbuf part.
This commit is contained in:
Christopher Faulet 2026-03-09 07:38:22 +01:00
parent 1c379cad88
commit 4d6cba03f2
4 changed files with 39 additions and 34 deletions

View File

@ -37,6 +37,7 @@
extern struct pool_head *pool_head_buffer;
extern struct pool_head *pool_head_large_buffer;
extern struct pool_head *pool_head_small_buffer;
int init_buffer(void);
void buffer_dump(FILE *o, struct buffer *b, int from, int to);
@ -66,6 +67,12 @@ static inline int b_is_large_sz(size_t sz)
return (pool_head_large_buffer && sz == pool_head_large_buffer->size);
}
/* Return 1 if <sz> is the size of a small buffer */
static inline int b_is_small_sz(size_t sz)
{
return (pool_head_small_buffer && sz == pool_head_small_buffer->size);
}
/* Return 1 if <bug> is a default buffer */
static inline int b_is_default(struct buffer *buf)
{
@ -78,6 +85,12 @@ static inline int b_is_large(struct buffer *buf)
return b_is_large_sz(b_size(buf));
}
/* Return 1 if <buf> is a small buffer */
static inline int b_is_small(struct buffer *buf)
{
return b_is_small_sz(b_size(buf));
}
/**************************************************/
/* Functions below are used for buffer allocation */
/**************************************************/
@ -172,6 +185,8 @@ static inline char *__b_get_emergency_buf(void)
* than the default buffers */ \
if (unlikely(b_is_large_sz(sz))) \
pool_free(pool_head_large_buffer, area); \
else if (unlikely(b_is_small_sz(sz))) \
pool_free(pool_head_small_buffer, area); \
else if (th_ctx->emergency_bufs_left < global.tune.reserved_bufs) \
th_ctx->emergency_bufs[th_ctx->emergency_bufs_left++] = area; \
else \

View File

@ -2322,6 +2322,17 @@ int check_config_validity()
}
}
if (global.tune.bufsize_small > 0) {
if (global.tune.bufsize_small == global.tune.bufsize)
global.tune.bufsize_small = 0;
else if (global.tune.bufsize_small > global.tune.bufsize) {
ha_warning("invalid small buffer size %d bytes which is greater to default bufsize %d bytes.\n",
global.tune.bufsize_small, global.tune.bufsize);
err_code |= ERR_FATAL | ERR_ABORT;
goto out;
}
}
/* in the worst case these were supposed to be set in thread_detect_count() */
BUG_ON(!global.nbthread);
BUG_ON(!global.nbtgroups);

View File

@ -24,6 +24,7 @@
struct pool_head *pool_head_buffer __read_mostly;
struct pool_head *pool_head_large_buffer __read_mostly = NULL;
struct pool_head *pool_head_small_buffer __read_mostly;
/* perform minimal initializations, report 0 in case of error, 1 if OK. */
int init_buffer()
@ -43,6 +44,12 @@ int init_buffer()
return 0;
}
if (global.tune.bufsize_small) {
pool_head_small_buffer = create_aligned_pool("small_buffer", global.tune.bufsize_small, 64, MEM_F_SHARED|MEM_F_EXACT);
if (!pool_head_small_buffer)
return 0;
}
/* make sure any change to the queues assignment isn't overlooked */
BUG_ON(DB_PERMANENT - DB_UNLIKELY - 1 != DYNBUF_NBQ);
BUG_ON(DB_MUX_RX_Q < DB_SE_RX_Q || DB_MUX_RX_Q >= DYNBUF_NBQ);

View File

@ -16,8 +16,6 @@ DECLARE_STATIC_TYPED_POOL(pool_head_quic_stream_desc, "qc_stream_desc", struct q
DECLARE_STATIC_TYPED_POOL(pool_head_quic_stream_buf, "qc_stream_buf", struct qc_stream_buf);
DECLARE_STATIC_TYPED_POOL(pool_head_quic_stream_ack, "qc_stream_ack", struct qc_stream_ack);
static struct pool_head *pool_head_sbuf;
static void qc_stream_buf_free(struct qc_stream_desc *stream,
struct qc_stream_buf **stream_buf)
{
@ -39,13 +37,10 @@ static void qc_stream_buf_free(struct qc_stream_desc *stream,
room = b_data(buf);
}
if ((*stream_buf)->sbuf) {
pool_free(pool_head_sbuf, buf->area);
}
else {
b_free(buf);
if (!(*stream_buf)->sbuf) {
bdata_ctr_del(&stream->data, b_data(buf));
bdata_ctr_bdec(&stream->data);
b_free(buf);
offer_buffers(NULL, 1);
}
pool_free(pool_head_quic_stream_buf, *stream_buf);
@ -412,10 +407,7 @@ void qc_stream_desc_free(struct qc_stream_desc *stream, int closing)
pool_free(pool_head_quic_stream_ack, ack);
}
if (buf->sbuf)
pool_free(pool_head_sbuf, buf->buf.area);
else
b_free(&buf->buf);
b_free(&buf->buf);
eb64_delete(&buf->offset_node);
pool_free(pool_head_quic_stream_buf, buf);
@ -461,7 +453,7 @@ struct buffer *qc_stream_buf_alloc(struct qc_stream_desc *stream,
stream->buf->buf = BUF_NULL;
stream->buf->offset_node.key = offset;
if (!small) {
if (!small || !global.tune.bufsize_small) {
stream->buf->sbuf = 0;
if (!b_alloc(&stream->buf->buf, DB_MUX_TX)) {
pool_free(pool_head_quic_stream_buf, stream->buf);
@ -472,7 +464,7 @@ struct buffer *qc_stream_buf_alloc(struct qc_stream_desc *stream,
else {
char *area;
if (!(area = pool_alloc(pool_head_sbuf))) {
if (!(area = pool_alloc(pool_head_small_buffer))) {
pool_free(pool_head_quic_stream_buf, stream->buf);
stream->buf = NULL;
return NULL;
@ -502,7 +494,7 @@ struct buffer *qc_stream_buf_realloc(struct qc_stream_desc *stream)
BUG_ON(b_data(&stream->buf->buf));
/* Release buffer */
pool_free(pool_head_sbuf, stream->buf->buf.area);
b_free(&stream->buf->buf);
stream->buf->buf = BUF_NULL;
stream->buf->sbuf = 0;
@ -536,23 +528,3 @@ void qc_stream_buf_release(struct qc_stream_desc *stream)
if (stream->notify_room && room)
stream->notify_room(stream, room);
}
static int create_sbuf_pool(void)
{
if (global.tune.bufsize_small > global.tune.bufsize) {
ha_warning("invalid small buffer size %d bytes which is greater to default bufsize %d bytes.\n",
global.tune.bufsize_small, global.tune.bufsize);
return ERR_FATAL|ERR_ABORT;
}
pool_head_sbuf = create_pool("sbuf", global.tune.bufsize_small,
MEM_F_SHARED|MEM_F_EXACT);
if (!pool_head_sbuf) {
ha_warning("error on small buffer pool allocation.\n");
return ERR_FATAL|ERR_ABORT;
}
return ERR_NONE;
}
REGISTER_POST_CHECK(create_sbuf_pool);