From: Amaury Denoyelle Date: Wed, 7 May 2025 15:32:46 +0000 (+0200) Subject: MINOR: quic: account Tx data per stream X-Git-Tag: v3.2-dev16~34 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a1dc9070e7abe010c1693de9dea67c127577efb5;p=thirdparty%2Fhaproxy.git MINOR: quic: account Tx data per stream Add accounting at qc_stream_desc level to be able to report the number of allocated Tx buffers and the sum of their data. This represents data ready for emission or already emitted and waiting on ACK. To simplify this accounting, a new counter type bdata_ctr is defined in quic_utils.h. This regroups both buffers and data counter, plus a maximum on the buffer value. These values are now displayed on QCS info used both on logline and traces, and also on "show quic" output. --- diff --git a/include/haproxy/quic_stream-t.h b/include/haproxy/quic_stream-t.h index b26fd850f..acba30914 100644 --- a/include/haproxy/quic_stream-t.h +++ b/include/haproxy/quic_stream-t.h @@ -7,6 +7,7 @@ #include #include +#include /* A QUIC STREAM buffer used for Tx. * @@ -43,6 +44,7 @@ struct qc_stream_desc { uint64_t ack_offset; /* last acknowledged offset */ struct eb_root buf_tree; /* list of active and released buffers */ + struct bdata_ctr data; /* data utilization counter */ int flags; /* QC_SD_FL_* values */ diff --git a/include/haproxy/quic_utils-t.h b/include/haproxy/quic_utils-t.h new file mode 100644 index 000000000..22eb6908c --- /dev/null +++ b/include/haproxy/quic_utils-t.h @@ -0,0 +1,17 @@ +#ifndef _HAPROXY_QUIC_UTILS_T_H +#define _HAPROXY_QUIC_UTILS_T_H + +#ifdef USE_QUIC + +#include + +/* Counter which can be used to measure data amount accross several buffers. */ +struct bdata_ctr { + uint64_t tot; /* sum of data present in all underlying buffers */ + uint8_t bcnt; /* current number of allocated underlying buffers */ + uint8_t bmax; /* max number of allocated buffers during stream lifetime */ +}; + +#endif /* USE_QUIC */ + +#endif /* _HAPROXY_QUIC_UTILS_T_H */ diff --git a/include/haproxy/quic_utils.h b/include/haproxy/quic_utils.h new file mode 100644 index 000000000..0a875e180 --- /dev/null +++ b/include/haproxy/quic_utils.h @@ -0,0 +1,49 @@ +#ifndef _HAPROXY_QUIC_UTILS_H +#define _HAPROXY_QUIC_UTILS_H + +#ifdef USE_QUIC + +#include + +#include +#include + +static inline void bdata_ctr_init(struct bdata_ctr *ctr) +{ + ctr->tot = 0; + ctr->bcnt = 0; + ctr->bmax = 0; +} + +static inline void bdata_ctr_binc(struct bdata_ctr *ctr) +{ + ++ctr->bcnt; + ctr->bmax = MAX(ctr->bcnt, ctr->bmax); +} + +static inline void bdata_ctr_bdec(struct bdata_ctr *ctr) +{ + --ctr->bcnt; +} + +static inline void bdata_ctr_add(struct bdata_ctr *ctr, size_t data) +{ + ctr->tot += data; +} + +static inline void bdata_ctr_del(struct bdata_ctr *ctr, size_t data) +{ + ctr->tot -= data; +} + +static inline void bdata_ctr_print(struct buffer *chunk, + const struct bdata_ctr *ctr, + const char *prefix) +{ + chunk_appendf(chunk, " %s%d(%d)/%llu", + prefix, ctr->bcnt, ctr->bmax, (ullong)ctr->tot); +} + +#endif /* USE_QUIC */ + +#endif /* _HAPROXY_QUIC_UTILS_H */ diff --git a/src/mux_quic.c b/src/mux_quic.c index 98438a7a1..6a0b31897 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -1637,6 +1638,7 @@ void qcc_send_stream(struct qcs *qcs, int urg, int count) if (count) { qfctl_sinc(&qcc->tx.fc, count); qfctl_sinc(&qcs->tx.fc, count); + bdata_ctr_add(&qcs->stream->data, count); } TRACE_LEAVE(QMUX_EV_QCS_SEND, qcc->conn, qcs); @@ -4118,13 +4120,18 @@ void qcc_show_quic(struct qcc *qcc) chunk_appendf(&trash, " qcs=0x%p id=%llu flags=0x%x st=%s", qcs, (ullong)qcs->id, qcs->flags, qcs_st_to_str(qcs->st)); + if (!quic_stream_is_uni(qcs->id) || !quic_stream_is_local(qcc, qcs->id)) chunk_appendf(&trash, " rxoff=%llu", (ullong)qcs->rx.offset); - if (!quic_stream_is_uni(qcs->id) || !quic_stream_is_remote(qcc, qcs->id)) + + if (!quic_stream_is_uni(qcs->id) || !quic_stream_is_remote(qcc, qcs->id)) { + if (qcs->stream) + bdata_ctr_print(&trash, &qcs->stream->data, "txb="); chunk_appendf(&trash, " txoff=%llu(%llu) msd=%llu", (ullong)qcs->tx.fc.off_real, (ullong)qcs->tx.fc.off_soft - (ullong)qcs->tx.fc.off_real, (ullong)qcs->tx.fc.limit); + } chunk_appendf(&trash, "\n"); node = eb64_next(node); } diff --git a/src/qmux_trace.c b/src/qmux_trace.c index 4998cbd00..649af8efe 100644 --- a/src/qmux_trace.c +++ b/src/qmux_trace.c @@ -7,6 +7,7 @@ #include #include #include +#include /* trace source and events */ static void qmux_trace(enum trace_level level, uint64_t mask, @@ -166,6 +167,9 @@ void qmux_dump_qcs_info(struct buffer *msg, const struct qcs *qcs) (ullong)qcs->tx.fc.off_real, (ullong)qcs->tx.fc.limit); + if (qcs->stream) + bdata_ctr_print(msg, &qcs->stream->data, " buf="); + chunk_appendf(msg, " .ti=%u/%u/%u", tot_time_read(&qcs->timer.base), tot_time_read(&qcs->timer.buf), diff --git a/src/quic_stream.c b/src/quic_stream.c index 71988c15d..e29913245 100644 --- a/src/quic_stream.c +++ b/src/quic_stream.c @@ -9,6 +9,7 @@ #include #include #include +#include #include DECLARE_STATIC_POOL(pool_head_quic_stream_desc, "qc_stream_desc", @@ -45,6 +46,8 @@ static void qc_stream_buf_free(struct qc_stream_desc *stream, pool_free(pool_head_sbuf, buf->area); } else { + bdata_ctr_del(&stream->data, b_data(buf)); + bdata_ctr_bdec(&stream->data); b_free(buf); offer_buffers(NULL, 1); } @@ -84,6 +87,7 @@ struct qc_stream_desc *qc_stream_desc_new(uint64_t id, enum qcs_type type, void stream->buf = NULL; stream->buf_tree = EB_ROOT_UNIQUE; stream->buf_offset = 0; + bdata_ctr_init(&stream->data); stream->ack_offset = 0; stream->flags = 0; @@ -263,6 +267,7 @@ static struct qc_stream_buf *qc_stream_buf_ack(struct qc_stream_buf *buf, diff = offset + len - stream->ack_offset; b_del(&buf->buf, diff); stream->ack_offset += diff; + bdata_ctr_del(&stream->data, diff); /* notify room from acked data if buffer has been released. */ if (stream->notify_room && qc_stream_buf_is_released(buf, stream)) { @@ -481,6 +486,7 @@ struct buffer *qc_stream_buf_alloc(struct qc_stream_desc *stream, } eb64_insert(&stream->buf_tree, &stream->buf->offset_node); + bdata_ctr_binc(&stream->data); return &stream->buf->buf; }