]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: account Tx data per stream
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 7 May 2025 15:32:46 +0000 (17:32 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 13 May 2025 13:41:41 +0000 (15:41 +0200)
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.

include/haproxy/quic_stream-t.h
include/haproxy/quic_utils-t.h [new file with mode: 0644]
include/haproxy/quic_utils.h [new file with mode: 0644]
src/mux_quic.c
src/qmux_trace.c
src/quic_stream.c

index b26fd850f9bb1991270d903d767fc751ae83d572..acba309143cd56e71bce820cbbbf35dcf84720e1 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <haproxy/buf-t.h>
 #include <haproxy/list-t.h>
+#include <haproxy/quic_utils-t.h>
 
 /* 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 (file)
index 0000000..22eb690
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef _HAPROXY_QUIC_UTILS_T_H
+#define _HAPROXY_QUIC_UTILS_T_H
+
+#ifdef USE_QUIC
+
+#include <haproxy/api-t.h>
+
+/* 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 (file)
index 0000000..0a875e1
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef _HAPROXY_QUIC_UTILS_H
+#define _HAPROXY_QUIC_UTILS_H
+
+#ifdef USE_QUIC
+
+#include <haproxy/quic_utils-t.h>
+
+#include <haproxy/buf-t.h>
+#include <haproxy/chunk.h>
+
+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 */
index 98438a7a1b2f353b62158e03e338cfa301bddd34..6a0b3189780d75e3bde5980d76aff8f28e06033b 100644 (file)
@@ -25,6 +25,7 @@
 #include <haproxy/quic_tp-t.h>
 #include <haproxy/quic_tune.h>
 #include <haproxy/quic_tx.h>
+#include <haproxy/quic_utils.h>
 #include <haproxy/session.h>
 #include <haproxy/ssl_sock-t.h>
 #include <haproxy/stconn.h>
@@ -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);
        }
index 4998cbd00f02dd77c106844a4645779e21914b8b..649af8efe8e8a32e170803990578b75cd67aa491 100644 (file)
@@ -7,6 +7,7 @@
 #include <haproxy/mux_quic.h>
 #include <haproxy/quic_conn-t.h>
 #include <haproxy/quic_frame-t.h>
+#include <haproxy/quic_utils.h>
 
 /* 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),
index 71988c15d021f02be0bf2f499278154595240e97..e2991324544863944b7d0d1a6ef2dcc4a6f1029f 100644 (file)
@@ -9,6 +9,7 @@
 #include <haproxy/mux_quic.h>
 #include <haproxy/pool.h>
 #include <haproxy/quic_conn.h>
+#include <haproxy/quic_utils.h>
 #include <haproxy/task.h>
 
 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;
 }