MINOR: mux_quic/pacing: display pacing info on show quic

To improve debugging, extend "show quic" output to report if pacing is
activated on a connection. Two values will be displayed for pacing :

* a new counter paced_sent_ctr is defined in QCC structure. It will be
  incremented each time an emission is interrupted due to pacing.

* pacing engine now saves the number of datagrams sent in the last paced
  emission. This will be helpful to ensure burst parameter is valid.
This commit is contained in:
Amaury Denoyelle 2024-11-19 11:27:00 +01:00
parent 24cea66e07
commit 5a29fd6c61
4 changed files with 20 additions and 2 deletions

View File

@ -71,6 +71,7 @@ struct qcc {
uint64_t buf_in_flight; /* sum of currently allocated Tx buffer sizes */
struct list frms; /* list of STREAM frames ready for sent */
struct quic_pacer pacer; /* engine used to pace emission */
int paced_sent_ctr; /* counter for when emission is interrupted due to pacing */
} tx;
uint64_t largest_bidi_r; /* largest remote bidi stream ID opened. */

View File

@ -7,6 +7,8 @@
struct quic_pacer {
const struct quic_cc *cc; /* Congestion controler algo used for this connection */
ullong next; /* Nanosecond timestamp at which the next emission should be conducted */
int last_sent; /* Number of datagrams sent during last paced emission */
};
#endif /* _HAPROXY_QUIC_PACING_T_H */

View File

@ -2443,6 +2443,7 @@ static int qcc_io_send(struct qcc *qcc)
/* qcc_send_frames cannot return 1 if pacing not used. */
BUG_ON(!qcc_is_pacing_active(qcc->conn));
qcc_wakeup_pacing(qcc);
++qcc->tx.paced_sent_ctr;
}
else if (!LIST_ISEMPTY(&qcc->tx.frms)) {
/* Deallocate frames that the transport layer has rejected. */
@ -2799,17 +2800,22 @@ static void qcc_purge_sending(struct qcc *qcc)
struct quic_pacer *pacer = &qcc->tx.pacer;
struct list *frms = &qcc->tx.frms;
enum quic_tx_err ret = QUIC_TX_ERR_PACING;
int sent = 0;
/* This function is reserved for pacing usage. */
BUG_ON(!qcc_is_pacing_active(qcc->conn));
/* Only restart emission if pacing delay is reached. */
if (quic_pacing_expired(pacer))
if (quic_pacing_expired(pacer)) {
ret = qc_send_mux(qcc->conn->handle.qc, frms, pacer);
sent = 1;
}
if (ret == QUIC_TX_ERR_PACING) {
BUG_ON(LIST_ISEMPTY(frms));
qcc_wakeup_pacing(qcc);
if (sent)
++qcc->tx.paced_sent_ctr;
}
else if (ret == QUIC_TX_ERR_FATAL) {
TRACE_DEVEL("error on sending", QMUX_EV_QCC_SEND, qcc->conn);
@ -2960,8 +2966,10 @@ static int qmux_init(struct connection *conn, struct proxy *prx,
qcc->tx.buf_in_flight = 0;
if (qcc_is_pacing_active(conn))
if (qcc_is_pacing_active(conn)) {
quic_pacing_init(&qcc->tx.pacer, &conn->handle.qc->path->cc);
qcc->tx.paced_sent_ctr = 0;
}
if (conn_is_back(conn)) {
qcc->next_bidi_l = 0x00;
@ -3594,6 +3602,12 @@ void qcc_show_quic(struct qcc *qcc)
qcc, qcc->flags, (ullong)qcc->nb_sc, (ullong)qcc->nb_hreq,
(ullong)qcc->tx.buf_in_flight, (ullong)qc->path->cwnd);
if (qcc_is_pacing_active(qcc->conn)) {
chunk_appendf(&trash, " pacing int_sent=%d last_sent=%d\n",
qcc->tx.paced_sent_ctr,
qcc->tx.pacer.last_sent);
}
node = eb64_first(&qcc->streams_by_id);
while (node) {
struct qcs *qcs = eb64_entry(node, struct qcs, by_id);

View File

@ -12,4 +12,5 @@ int quic_pacing_expired(const struct quic_pacer *pacer)
void quic_pacing_sent_done(struct quic_pacer *pacer, int sent)
{
pacer->next = now_mono_time() + pacer->cc->algo->pacing_rate(pacer->cc) * sent;
pacer->last_sent = sent;
}