From 05e2148f4059936d4ae4bbfba97ad90bcce97cc8 Mon Sep 17 00:00:00 2001 From: Jana Iyengar Date: Sun, 21 Mar 2021 17:55:45 -0700 Subject: [PATCH 1/3] Make reno CC a bit loss tolerant --- include/quicly/cc.h | 4 ++++ lib/cc-reno.c | 20 +++++++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/include/quicly/cc.h b/include/quicly/cc.h index 031ed51af..a1c27366e 100644 --- a/include/quicly/cc.h +++ b/include/quicly/cc.h @@ -81,6 +81,10 @@ typedef struct st_quicly_cc_t { * Stash of acknowledged bytes, used during congestion avoidance. */ uint32_t stash; + /** + * Number of losses seen in a recovery episode. + */ + uint32_t num_lost_in_episode; } reno; /** * State information for CUBIC congestion control. diff --git a/lib/cc-reno.c b/lib/cc-reno.c index b1fe1e97d..0dd4c2155 100644 --- a/lib/cc-reno.c +++ b/lib/cc-reno.c @@ -24,6 +24,7 @@ #define QUICLY_MIN_CWND 2 #define QUICLY_RENO_BETA 0.7 +#define QUICLY_RENO_LOSS_THRESHOLD 2 /* TODO: Avoid increase if sender was application limited. */ static void reno_on_acked(quicly_cc_t *cc, const quicly_loss_t *loss, uint32_t bytes, uint64_t largest_acked, uint32_t inflight, @@ -56,10 +57,23 @@ static void reno_on_acked(quicly_cc_t *cc, const quicly_loss_t *loss, uint32_t b static void reno_on_lost(quicly_cc_t *cc, const quicly_loss_t *loss, uint32_t bytes, uint64_t lost_pn, uint64_t next_pn, int64_t now, uint32_t max_udp_payload_size) { - /* Nothing to do if loss is in recovery window. */ - if (lost_pn < cc->recovery_end) + /* Set up state if potentially new recovery episode. */ + if (lost_pn >= cc->recovery_end) { + cc->recovery_end = next_pn; + cc->state.reno.num_lost_in_episode = 0; + } + + cc->state.reno.num_lost_in_episode++; + + /* Nothing to do if number of losses in this recovery episode is below a + * threshold. Doing so builds some tolerance for loss, by only responding + * with a congestion action if the number of losses in a window is greater + * than the threshold. Similarly, there should be only one reduction in a + * window, so nothing to do if number of losses is greater than the + * threshold. + */ + if (cc->state.reno.num_lost_in_episode != QUICLY_RENO_LOSS_THRESHOLD) return; - cc->recovery_end = next_pn; ++cc->num_loss_episodes; if (cc->cwnd_exiting_slow_start == 0) From af03c20ab8d7cf37bdeafeff6f3ac4807cd57f9e Mon Sep 17 00:00:00 2001 From: Jana Iyengar Date: Sun, 21 Mar 2021 18:08:35 -0700 Subject: [PATCH 2/3] allow cwnd to increase if threshold has not yet been hit --- lib/cc-reno.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/cc-reno.c b/lib/cc-reno.c index 0dd4c2155..616eb176a 100644 --- a/lib/cc-reno.c +++ b/lib/cc-reno.c @@ -31,8 +31,10 @@ static void reno_on_acked(quicly_cc_t *cc, const quicly_loss_t *loss, uint32_t b int64_t now, uint32_t max_udp_payload_size) { assert(inflight >= bytes); - /* Do not increase congestion window while in recovery. */ - if (largest_acked < cc->recovery_end) + /* Do not increase congestion window while in recovery and if number of + * losses in this episode is greater than the threshold. */ + if (largest_acked < cc->recovery_end && + cc->state.reno.num_lost_in_episode >= QUICLY_RENO_LOSS_THRESHOLD) return; /* Slow start. */ From c96cc1454655d78b244bc8e0745fd83d9f549928 Mon Sep 17 00:00:00 2001 From: Jana Iyengar Date: Sun, 21 Mar 2021 18:14:32 -0700 Subject: [PATCH 3/3] comments cleanup --- lib/cc-reno.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/cc-reno.c b/lib/cc-reno.c index 616eb176a..3975eb661 100644 --- a/lib/cc-reno.c +++ b/lib/cc-reno.c @@ -32,7 +32,7 @@ static void reno_on_acked(quicly_cc_t *cc, const quicly_loss_t *loss, uint32_t b { assert(inflight >= bytes); /* Do not increase congestion window while in recovery and if number of - * losses in this episode is greater than the threshold. */ + * losses in this episode has met the threshold. */ if (largest_acked < cc->recovery_end && cc->state.reno.num_lost_in_episode >= QUICLY_RENO_LOSS_THRESHOLD) return; @@ -59,7 +59,7 @@ static void reno_on_acked(quicly_cc_t *cc, const quicly_loss_t *loss, uint32_t b static void reno_on_lost(quicly_cc_t *cc, const quicly_loss_t *loss, uint32_t bytes, uint64_t lost_pn, uint64_t next_pn, int64_t now, uint32_t max_udp_payload_size) { - /* Set up state if potentially new recovery episode. */ + /* Set up state if new recovery episode. */ if (lost_pn >= cc->recovery_end) { cc->recovery_end = next_pn; cc->state.reno.num_lost_in_episode = 0;