This is an automated email from the git hooks/post-receive script.
dgoulet pushed a commit to branch main in repository tor.
commit acdc0ecdd47879e202b1406236ce80e028b71d40 Author: Mike Perry mikeperry-git@torproject.org AuthorDate: Sun Jul 31 15:14:22 2022 +0000
Reset the min value if we hit cwnd_min.
This can avoid circuits getting stuck due to an abnormally low min value. --- src/core/or/congestion_control_common.c | 33 ++++++++++++++++++++++++++++++++- src/core/or/congestion_control_common.h | 23 +++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-)
diff --git a/src/core/or/congestion_control_common.c b/src/core/or/congestion_control_common.c index b90c78729a..25446621d1 100644 --- a/src/core/or/congestion_control_common.c +++ b/src/core/or/congestion_control_common.c @@ -54,6 +54,8 @@ #define N_EWMA_MAX_DFLT (10) #define N_EWMA_SS_DFLT (2)
+#define RTT_RESET_PCT_DFLT (100) + /* BDP algorithms for each congestion control algorithms use the piecewise * estimattor. See section 3.1.4 of proposal 324. */ #define WESTWOOD_BDP_ALG BDP_ALG_PIECEWISE @@ -118,6 +120,12 @@ static uint8_t n_ewma_ss; */ static uint8_t bwe_sendme_min;
+/** + * Percentage of the current RTT to use when reseting the minimum RTT + * for a circuit. (RTT is reset when the cwnd hits cwnd_min). + */ +static uint8_t rtt_reset_pct; + /** * Update global congestion control related consensus parameter values, * every consensus update. @@ -163,6 +171,14 @@ congestion_control_new_consensus_params(const networkstatus_t *ns) CWND_MAX_MIN, CWND_MAX_MAX);
+#define RTT_RESET_PCT_MIN (0) +#define RTT_RESET_PCT_MAX (100) + rtt_reset_pct = + networkstatus_get_param(NULL, "cc_rtt_reset_pct", + RTT_RESET_PCT_DFLT, + RTT_RESET_PCT_MIN, + RTT_RESET_PCT_MAX); + #define SENDME_INC_MIN 1 #define SENDME_INC_MAX (255) cc_sendme_inc = @@ -857,7 +873,22 @@ congestion_control_update_circuit_rtt(congestion_control_t *cc, cc->max_rtt_usec = rtt; }
- if (cc->min_rtt_usec == 0 || cc->ewma_rtt_usec < cc->min_rtt_usec) { + if (cc->min_rtt_usec == 0) { + // If we do not have a min_rtt yet, use current ewma + cc->min_rtt_usec = cc->ewma_rtt_usec; + } else if (cc->cwnd == cc->cwnd_min) { + // Raise min rtt if cwnd hit cwnd_min. This gets us out of a wedge state + // if we hit cwnd_min due to an abnormally low rtt. + uint64_t new_rtt = percent_max_mix(cc->ewma_rtt_usec, cc->min_rtt_usec, + rtt_reset_pct); + + static ratelim_t rtt_notice_limit = RATELIM_INIT(300); + log_fn_ratelim(&rtt_notice_limit, LOG_NOTICE, LD_CIRC, + "Resetting circ RTT from %"PRIu64" to %"PRIu64" due to low cwnd", + cc->min_rtt_usec/1000, new_rtt/1000); + + cc->min_rtt_usec = new_rtt; + } else if (cc->ewma_rtt_usec < cc->min_rtt_usec) { // Using the EWMA for min instead of current RTT helps average out // effects from other conns cc->min_rtt_usec = cc->ewma_rtt_usec; diff --git a/src/core/or/congestion_control_common.h b/src/core/or/congestion_control_common.h index 71e984f914..50af945d62 100644 --- a/src/core/or/congestion_control_common.h +++ b/src/core/or/congestion_control_common.h @@ -145,6 +145,29 @@ n_count_ewma(uint64_t curr, uint64_t prev, uint64_t N) return (2*curr + (N-1)*prev)/(N+1); }
+/** + * Helper function that gives us a percentile weighted-average between + * two values. The pct_max argument specifies the percentage weight of the + * maximum of a and b, when computing this weighted-average. + * + * This also allows this function to be used as either MIN() or a MAX() + * by this parameterization. It is MIN() when pct_max==0; + * it is MAX() when pct_max==100; it is avg() when pct_max==50; it is a + * weighted-average for values in between. + */ +static inline uint64_t +percent_max_mix(uint64_t a, uint64_t b, uint8_t pct_max) +{ + uint64_t max = MAX(a, b); + uint64_t min = MIN(a, b); + + if (BUG(pct_max > 100)) { + return max; + } + + return pct_max*max/100 + (100-pct_max)*min/100; +} + /* Private section starts. */ #ifdef TOR_CONGESTION_CONTROL_PRIVATE