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; }