diff --git a/include/haproxy/dynbuf.h b/include/haproxy/dynbuf.h index 42e4d1f4b..d487e1068 100644 --- a/include/haproxy/dynbuf.h +++ b/include/haproxy/dynbuf.h @@ -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 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 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 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 \ diff --git a/src/cfgparse.c b/src/cfgparse.c index d89acfeb6..f36e5719d 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -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); diff --git a/src/dynbuf.c b/src/dynbuf.c index ff80b8198..5c299edbd 100644 --- a/src/dynbuf.c +++ b/src/dynbuf.c @@ -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); diff --git a/src/quic_stream.c b/src/quic_stream.c index 364030477..407ca1efe 100644 --- a/src/quic_stream.c +++ b/src/quic_stream.c @@ -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);