Due to the fact that several variable values (rtt_var, srtt) were stored as multiple
of their real values, some calculations were less accurate as expected.
Stop storing 4*rtt_var values, and 8*srtt values.
Adjust all the impacted statements.
Must be backported as far as 2.6.
*/
struct quic_loss {
- /* The most recent RTT measurement. */
+ /* The most recent RTT measurement (ms) */
unsigned int latest_rtt;
- /* Smoothed RTT << 3 */
+ /* Smoothed RTT (ms) */
unsigned int srtt;
- /* RTT variation << 2 */
+ /* RTT variation (ms) */
unsigned int rtt_var;
- /* Minimum RTT. */
+ /* Minimum RTT (ms) */
unsigned int rtt_min;
/* Number of NACKed sent PTO. */
unsigned int pto_count;
static inline void quic_loss_init(struct quic_loss *ql)
{
ql->latest_rtt = 0;
- ql->srtt = QUIC_LOSS_INITIAL_RTT << 3;
- ql->rtt_var = (QUIC_LOSS_INITIAL_RTT >> 1) << 2;
+ ql->srtt = QUIC_LOSS_INITIAL_RTT;
+ ql->rtt_var = QUIC_LOSS_INITIAL_RTT / 2;
ql->rtt_min = 0;
ql->pto_count = 0;
ql->nb_lost_pkt = 0;
if (!period)
return 0;
- congestion_period = (ql->srtt >> 3) +
- QUIC_MAX(ql->rtt_var, QUIC_TIMER_GRANULARITY) + max_ack_delay;
+ congestion_period = ql->srtt +
+ QUIC_MAX(4 * ql->rtt_var, QUIC_TIMER_GRANULARITY) + max_ack_delay;
congestion_period *= QUIC_LOSS_PACKET_THRESHOLD;
return period >= congestion_period;
{
struct quic_loss *ql = &qc->path->loss;
- return (ql->srtt >> 3) + QUIC_MAX(ql->rtt_var, QUIC_TIMER_GRANULARITY) +
+ return ql->srtt + QUIC_MAX(4 * ql->rtt_var, QUIC_TIMER_GRANULARITY) +
(HA_ATOMIC_LOAD(&qc->state) >= QUIC_HS_ST_COMPLETE ? qc->max_ack_delay : 0);
}
chunk_appendf(&trash, " srtt=%-4u rttvar=%-4u rttmin=%-4u ptoc=%-4u cwnd=%-6llu"
" mcwnd=%-6llu sentpkts=%-6llu lostpkts=%-6llu\n",
- qc->path->loss.srtt >> 3, qc->path->loss.rtt_var >> 2,
+ qc->path->loss.srtt, qc->path->loss.rtt_var,
qc->path->loss.rtt_min, qc->path->loss.pto_count, (ullong)qc->path->cwnd,
(ullong)qc->path->mcwnd, (ullong)qc->cntrs.sent_pkt, (ullong)qc->path->loss.nb_lost_pkt);
ql->latest_rtt = rtt;
if (!ql->rtt_min) {
/* No previous measurement. */
- ql->srtt = rtt << 3;
- /* rttval <- rtt / 2 or 4*rttval <- 2*rtt. */
- ql->rtt_var = rtt << 1;
+ ql->srtt = rtt;
+ ql->rtt_var = rtt / 2;
ql->rtt_min = rtt;
}
else {
/* Specific to QUIC (RTT adjustment). */
if (ack_delay && rtt >= ql->rtt_min + ack_delay)
rtt -= ack_delay;
- diff = (ql->srtt >> 3) - rtt;
+ diff = ql->srtt - rtt;
if (diff < 0)
diff = -diff;
- /* 4*rttvar = 3*rttvar + |diff| */
- ql->rtt_var += diff - (ql->rtt_var >> 2);
- /* 8*srtt = 7*srtt + rtt */
- ql->srtt += rtt - (ql->srtt >> 3);
+ ql->rtt_var = (3 * ql->rtt_var + diff) / 4;
+ ql->srtt = (7 * ql->srtt + rtt) / 8;
}
TRACE_PROTO("TX loss srtt update", QUIC_EV_CONN_RTTUPDT, qc,,, ql);
BUG_ON(LIST_ISEMPTY(&qc->pktns_list));
duration =
- (ql->srtt >> 3) +
- (QUIC_MAX(ql->rtt_var, QUIC_TIMER_GRANULARITY) << ql->pto_count);
+ ql->srtt +
+ (QUIC_MAX(4 * ql->rtt_var, QUIC_TIMER_GRANULARITY) << ql->pto_count);
/* RFC 9002 6.2.2.1. Before Address Validation
*
goto out;
ql = &qc->path->loss;
- loss_delay = QUIC_MAX(ql->latest_rtt, ql->srtt >> 3);
+ loss_delay = QUIC_MAX(ql->latest_rtt, ql->srtt);
loss_delay = QUIC_MAX(loss_delay, MS_TO_TICKS(QUIC_TIMER_GRANULARITY)) *
QUIC_LOSS_TIME_THRESHOLD_MULTIPLICAND / QUIC_LOSS_TIME_THRESHOLD_DIVISOR;
if (ql)
chunk_appendf(&trace_buf,
" srtt=%ums rttvar=%ums min_rtt=%ums",
- ql->srtt >> 3, ql->rtt_var >> 2, ql->rtt_min);
+ ql->srtt, ql->rtt_var, ql->rtt_min);
}
if (mask & QUIC_EV_CONN_CC) {
const struct quic_cc_event *ev = a2;