From fad0e6cf7376bfe9ad4e08228918d53285ab6052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= Date: Thu, 6 Apr 2023 10:19:17 +0200 Subject: [PATCH] MINOR: quic: Add packet loss and maximum cc window to "show quic" Add the number of packet losts and the maximum congestion control window computed by the algorithms to "show quic". Same thing for the traces of existent congestion control algorithms. Must be backported to 2.7 and 2.6. --- include/haproxy/quic_conn-t.h | 1 + include/haproxy/quic_conn.h | 1 + include/haproxy/quic_loss-t.h | 1 + include/haproxy/quic_loss.h | 1 + src/quic_cc_cubic.c | 5 ++++- src/quic_cc_newreno.c | 9 +++++++-- src/quic_conn.c | 6 ++++-- src/quic_loss.c | 1 + 8 files changed, 20 insertions(+), 5 deletions(-) diff --git a/include/haproxy/quic_conn-t.h b/include/haproxy/quic_conn-t.h index fdeb9dad3..2213a7f77 100644 --- a/include/haproxy/quic_conn-t.h +++ b/include/haproxy/quic_conn-t.h @@ -579,6 +579,7 @@ struct quic_path { size_t mtu; /* Congestion window. */ uint64_t cwnd; + uint64_t mcwnd; /* Minimum congestion window. */ uint64_t min_cwnd; /* Prepared data to be sent (in bytes). */ diff --git a/include/haproxy/quic_conn.h b/include/haproxy/quic_conn.h index 568911052..6806d4fdc 100644 --- a/include/haproxy/quic_conn.h +++ b/include/haproxy/quic_conn.h @@ -538,6 +538,7 @@ static inline void quic_path_init(struct quic_path *path, int ipv4, quic_loss_init(&path->loss); path->mtu = max_dgram_sz; path->cwnd = QUIC_MIN(10 * max_dgram_sz, QUIC_MAX(max_dgram_sz << 1, 14720U)); + path->mcwnd = path->cwnd; path->min_cwnd = max_dgram_sz << 1; path->prep_in_flight = 0; path->in_flight = 0; diff --git a/include/haproxy/quic_loss-t.h b/include/haproxy/quic_loss-t.h index 4fb20847f..8ab41b256 100644 --- a/include/haproxy/quic_loss-t.h +++ b/include/haproxy/quic_loss-t.h @@ -54,6 +54,7 @@ struct quic_loss { unsigned int rtt_min; /* Number of NACKed sent PTO. */ unsigned int pto_count; + unsigned long nb_lost_pkt; }; #endif /* USE_QUIC */ diff --git a/include/haproxy/quic_loss.h b/include/haproxy/quic_loss.h index e4cb82f2c..a5f67d70a 100644 --- a/include/haproxy/quic_loss.h +++ b/include/haproxy/quic_loss.h @@ -38,6 +38,7 @@ static inline void quic_loss_init(struct quic_loss *ql) ql->rtt_var = (QUIC_LOSS_INITIAL_RTT >> 1) << 2; ql->rtt_min = 0; ql->pto_count = 0; + ql->nb_lost_pkt = 0; } /* Return 1 if a persistent congestion is observed for a list of diff --git a/src/quic_cc_cubic.c b/src/quic_cc_cubic.c index 1a5fa4e5b..d22897b37 100644 --- a/src/quic_cc_cubic.c +++ b/src/quic_cc_cubic.c @@ -168,6 +168,7 @@ static inline void quic_cubic_update(struct quic_cc *cc, uint32_t acked) } path->cwnd += inc; + path->mcwnd = QUIC_MAX(path->cwnd, path->mcwnd); leave: TRACE_LEAVE(QUIC_EV_CONN_CC, cc->qc); } @@ -217,6 +218,7 @@ static void quic_cc_cubic_ss_cb(struct quic_cc *cc, struct quic_cc_event *ev) /* Exit to congestion avoidance if slow start threshold is reached. */ if (path->cwnd >= c->ssthresh) c->state = QUIC_CC_ST_CA; + path->mcwnd = QUIC_MAX(path->cwnd, path->mcwnd); break; case QUIC_CC_EVT_LOSS: @@ -309,9 +311,10 @@ static void quic_cc_cubic_state_trace(struct buffer *buf, const struct quic_cc * struct cubic *c = quic_cc_priv(cc); path = container_of(cc, struct quic_path, cc); - chunk_appendf(buf, " state=%s cwnd=%llu ssthresh=%d rpst=%dms", + chunk_appendf(buf, " state=%s cwnd=%llu mcwnd=%llu ssthresh=%d rpst=%dms", quic_cc_state_str(c->state), (unsigned long long)path->cwnd, + (unsigned long long)path->mcwnd, (int)c->ssthresh, !tick_isset(c->recovery_start_time) ? -1 : TICKS_TO_MS(tick_remain(c->recovery_start_time, now_ms))); diff --git a/src/quic_cc_newreno.c b/src/quic_cc_newreno.c index 4d9bf136a..65763d762 100644 --- a/src/quic_cc_newreno.c +++ b/src/quic_cc_newreno.c @@ -87,6 +87,7 @@ static void quic_cc_nr_ss_cb(struct quic_cc *cc, struct quic_cc_event *ev) switch (ev->type) { case QUIC_CC_EVT_ACK: path->cwnd += ev->ack.acked; + path->mcwnd = QUIC_MAX(path->cwnd, path->mcwnd); /* Exit to congestion avoidance if slow start threshold is reached. */ if (path->cwnd > nr->ssthresh) nr->state = QUIC_CC_ST_CA; @@ -123,6 +124,7 @@ static void quic_cc_nr_ca_cb(struct quic_cc *cc, struct quic_cc_event *ev) acked = ev->ack.acked * path->mtu + nr->remain_acked; nr->remain_acked = acked % path->cwnd; path->cwnd += acked / path->cwnd; + path->mcwnd = QUIC_MAX(path->cwnd, path->mcwnd); break; } @@ -182,11 +184,14 @@ static void quic_cc_nr_state_trace(struct buffer *buf, const struct quic_cc *cc) struct nr *nr = quic_cc_priv(cc); path = container_of(cc, struct quic_path, cc); - chunk_appendf(buf, " state=%s cwnd=%llu ssthresh=%ld recovery_start_time=%llu", + chunk_appendf(buf, " state=%s cwnd=%llu mcwnd=%llu ssthresh=%ld rpst=%dms pktloss=%llu", quic_cc_state_str(nr->state), (unsigned long long)path->cwnd, + (unsigned long long)path->mcwnd, (long)nr->ssthresh, - (unsigned long long)nr->recovery_start_time); + !tick_isset(nr->recovery_start_time) ? -1 : + TICKS_TO_MS(tick_remain(nr->recovery_start_time, now_ms)), + (unsigned long long)path->loss.nb_lost_pkt); } static void (*quic_cc_nr_state_cbs[])(struct quic_cc *cc, diff --git a/src/quic_conn.c b/src/quic_conn.c index 2d90ab3ef..d87bf05b6 100644 --- a/src/quic_conn.c +++ b/src/quic_conn.c @@ -8454,9 +8454,11 @@ static int cli_io_handler_dump_quic(struct appctx *appctx) chunk_appendf(&trash, " [01rtt] rx.ackrng=%-6zu tx.inflight=%-6zu\n", pktns->rx.arngs.sz, pktns->tx.in_flight); - chunk_appendf(&trash, " srtt=%-4u rttvar=%-4u rttmin=%-4u ptoc=%-4u cwnd=%-6llu\n", + chunk_appendf(&trash, " srtt=%-4u rttvar=%-4u rttmin=%-4u ptoc=%-4u cwnd=%-6llu" + " mcwnd=%-6llu lostpkts=%-6llu\n", qc->path->loss.srtt >> 3, qc->path->loss.rtt_var >> 2, - qc->path->loss.rtt_min, qc->path->loss.pto_count, (ullong)qc->path->cwnd); + qc->path->loss.rtt_min, qc->path->loss.pto_count, (ullong)qc->path->cwnd, + (ullong)qc->path->mcwnd, (ullong)qc->path->loss.nb_lost_pkt); /* Streams */ diff --git a/src/quic_loss.c b/src/quic_loss.c index 888b61d5b..a8696e913 100644 --- a/src/quic_loss.c +++ b/src/quic_loss.c @@ -190,6 +190,7 @@ void qc_packet_loss_lookup(struct quic_pktns *pktns, struct quic_conn *qc, (int64_t)largest_acked_pn >= pkt->pn_node.key + QUIC_LOSS_PACKET_THRESHOLD) { eb64_delete(&pkt->pn_node); LIST_APPEND(lost_pkts, &pkt->list); + ql->nb_lost_pkt++; HA_ATOMIC_INC(&qc->prx_counters->lost_pkt); } else {