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:
parent
24cea66e07
commit
5a29fd6c61
|
@ -71,6 +71,7 @@ struct qcc {
|
||||||
uint64_t buf_in_flight; /* sum of currently allocated Tx buffer sizes */
|
uint64_t buf_in_flight; /* sum of currently allocated Tx buffer sizes */
|
||||||
struct list frms; /* list of STREAM frames ready for sent */
|
struct list frms; /* list of STREAM frames ready for sent */
|
||||||
struct quic_pacer pacer; /* engine used to pace emission */
|
struct quic_pacer pacer; /* engine used to pace emission */
|
||||||
|
int paced_sent_ctr; /* counter for when emission is interrupted due to pacing */
|
||||||
} tx;
|
} tx;
|
||||||
|
|
||||||
uint64_t largest_bidi_r; /* largest remote bidi stream ID opened. */
|
uint64_t largest_bidi_r; /* largest remote bidi stream ID opened. */
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
struct quic_pacer {
|
struct quic_pacer {
|
||||||
const struct quic_cc *cc; /* Congestion controler algo used for this connection */
|
const struct quic_cc *cc; /* Congestion controler algo used for this connection */
|
||||||
ullong next; /* Nanosecond timestamp at which the next emission should be conducted */
|
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 */
|
#endif /* _HAPROXY_QUIC_PACING_T_H */
|
||||||
|
|
|
@ -2443,6 +2443,7 @@ static int qcc_io_send(struct qcc *qcc)
|
||||||
/* qcc_send_frames cannot return 1 if pacing not used. */
|
/* qcc_send_frames cannot return 1 if pacing not used. */
|
||||||
BUG_ON(!qcc_is_pacing_active(qcc->conn));
|
BUG_ON(!qcc_is_pacing_active(qcc->conn));
|
||||||
qcc_wakeup_pacing(qcc);
|
qcc_wakeup_pacing(qcc);
|
||||||
|
++qcc->tx.paced_sent_ctr;
|
||||||
}
|
}
|
||||||
else if (!LIST_ISEMPTY(&qcc->tx.frms)) {
|
else if (!LIST_ISEMPTY(&qcc->tx.frms)) {
|
||||||
/* Deallocate frames that the transport layer has rejected. */
|
/* 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 quic_pacer *pacer = &qcc->tx.pacer;
|
||||||
struct list *frms = &qcc->tx.frms;
|
struct list *frms = &qcc->tx.frms;
|
||||||
enum quic_tx_err ret = QUIC_TX_ERR_PACING;
|
enum quic_tx_err ret = QUIC_TX_ERR_PACING;
|
||||||
|
int sent = 0;
|
||||||
|
|
||||||
/* This function is reserved for pacing usage. */
|
/* This function is reserved for pacing usage. */
|
||||||
BUG_ON(!qcc_is_pacing_active(qcc->conn));
|
BUG_ON(!qcc_is_pacing_active(qcc->conn));
|
||||||
|
|
||||||
/* Only restart emission if pacing delay is reached. */
|
/* 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);
|
ret = qc_send_mux(qcc->conn->handle.qc, frms, pacer);
|
||||||
|
sent = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret == QUIC_TX_ERR_PACING) {
|
if (ret == QUIC_TX_ERR_PACING) {
|
||||||
BUG_ON(LIST_ISEMPTY(frms));
|
BUG_ON(LIST_ISEMPTY(frms));
|
||||||
qcc_wakeup_pacing(qcc);
|
qcc_wakeup_pacing(qcc);
|
||||||
|
if (sent)
|
||||||
|
++qcc->tx.paced_sent_ctr;
|
||||||
}
|
}
|
||||||
else if (ret == QUIC_TX_ERR_FATAL) {
|
else if (ret == QUIC_TX_ERR_FATAL) {
|
||||||
TRACE_DEVEL("error on sending", QMUX_EV_QCC_SEND, qcc->conn);
|
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;
|
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);
|
quic_pacing_init(&qcc->tx.pacer, &conn->handle.qc->path->cc);
|
||||||
|
qcc->tx.paced_sent_ctr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (conn_is_back(conn)) {
|
if (conn_is_back(conn)) {
|
||||||
qcc->next_bidi_l = 0x00;
|
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,
|
qcc, qcc->flags, (ullong)qcc->nb_sc, (ullong)qcc->nb_hreq,
|
||||||
(ullong)qcc->tx.buf_in_flight, (ullong)qc->path->cwnd);
|
(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);
|
node = eb64_first(&qcc->streams_by_id);
|
||||||
while (node) {
|
while (node) {
|
||||||
struct qcs *qcs = eb64_entry(node, struct qcs, by_id);
|
struct qcs *qcs = eb64_entry(node, struct qcs, by_id);
|
||||||
|
|
|
@ -12,4 +12,5 @@ int quic_pacing_expired(const struct quic_pacer *pacer)
|
||||||
void quic_pacing_sent_done(struct quic_pacer *pacer, int sent)
|
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->next = now_mono_time() + pacer->cc->algo->pacing_rate(pacer->cc) * sent;
|
||||||
|
pacer->last_sent = sent;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue