From a324616cdb0be7942313c18eb0d2595c2b5bf0b8 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Fri, 13 Feb 2026 09:54:53 +0100 Subject: [PATCH] MINOR: dynbuf: Add helpers to know if a buffer is a default or a large buffer b_is_default() and b_is_large() can now be used to know if a buffer is a default buffer or a large one. _b_free() now relies on it. These functions are also used when possible (stream_free(), stream_release_buffers() and http_wait_for_msg_body()). --- include/haproxy/dynbuf.h | 26 +++++++++++++++++++++++++- src/http_ana.c | 2 +- src/stream.c | 14 ++++++++++---- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/include/haproxy/dynbuf.h b/include/haproxy/dynbuf.h index ca16379c7..42e4d1f4b 100644 --- a/include/haproxy/dynbuf.h +++ b/include/haproxy/dynbuf.h @@ -54,6 +54,30 @@ static inline int buffer_almost_full(const struct buffer *buf) return b_almost_full(buf); } +/* Return 1 if is the default buffer size */ +static inline int b_is_default_sz(size_t sz) +{ + return (sz == pool_head_buffer->size); +} + +/* Return 1 if is the size of a large buffer (alwoys false is large buffers are not configured) */ +static inline int b_is_large_sz(size_t sz) +{ + return (pool_head_large_buffer && sz == pool_head_large_buffer->size); +} + +/* Return 1 if is a default buffer */ +static inline int b_is_default(struct buffer *buf) +{ + return b_is_default_sz(b_size(buf)); +} + +/* Return 1 if is a large buffer (alwoys 0 is large buffers are not configured) */ +static inline int b_is_large(struct buffer *buf) +{ + return b_is_large_sz(b_size(buf)); +} + /**************************************************/ /* Functions below are used for buffer allocation */ /**************************************************/ @@ -146,7 +170,7 @@ static inline char *__b_get_emergency_buf(void) __ha_barrier_store(); \ /* if enabled, large buffers are always strictly greater \ * than the default buffers */ \ - if (unlikely(pool_head_large_buffer && sz == pool_head_large_buffer->size)) \ + if (unlikely(b_is_large_sz(sz))) \ pool_free(pool_head_large_buffer, area); \ else if (th_ctx->emergency_bufs_left < global.tune.reserved_bufs) \ th_ctx->emergency_bufs[th_ctx->emergency_bufs_left++] = area; \ diff --git a/src/http_ana.c b/src/http_ana.c index 8a8f3a369..937f580b4 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -4306,7 +4306,7 @@ enum rule_result http_wait_for_msg_body(struct stream *s, struct channel *chn, struct buffer lbuf; char *area; - if (large_buffer == 0 || c_size(chn) == global.tune.bufsize_large) + if (large_buffer == 0 || b_is_large(&chn->buf)) goto end; /* don't use large buffer or large buffer is full */ /* normal buffer is full, allocate a large one diff --git a/src/stream.c b/src/stream.c index c537f5209..d760c8cba 100644 --- a/src/stream.c +++ b/src/stream.c @@ -658,11 +658,17 @@ void stream_free(struct stream *s) b_dequeue(&s->buffer_wait); if (s->req.buf.size || s->res.buf.size) { - int count = (s->req.buf.size == global.tune.bufsize) + (s->res.buf.size == global.tune.bufsize); + int count = 0; + + if (b_is_default(&s->req.buf)) + count++; + if (b_is_default(&s->res.buf)) + count++; b_free(&s->req.buf); b_free(&s->res.buf); - offer_buffers(NULL, count); + if (count) + offer_buffers(NULL, count); } pool_free(pool_head_uniqueid, s->unique_id.ptr); @@ -808,12 +814,12 @@ void stream_release_buffers(struct stream *s) int offer = 0; if (c_size(&s->req) && c_empty(&s->req)) { - if (c_size(&s->req) == global.tune.bufsize) + if (b_is_default(&s->req.buf)) offer++; b_free(&s->req.buf); } if (c_size(&s->res) && c_empty(&s->res)) { - if (c_size(&s->res) == global.tune.bufsize) + if (b_is_default(&s->res.buf)) offer++; b_free(&s->res.buf); }