Skip to content

Commit

Permalink
recovery: rewrite RttStats
Browse files Browse the repository at this point in the history
  • Loading branch information
vkrasnov authored and ghedo committed May 7, 2024
1 parent bc952e8 commit 3b758cb
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 88 deletions.
10 changes: 10 additions & 0 deletions quiche/src/minmax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
// every new min and overwrites 2nd & 3rd choices. The same property
// holds for 2nd & 3rd best.

use std::ops::Deref;

use std::time::Duration;
use std::time::Instant;

Expand All @@ -65,6 +67,14 @@ pub struct Minmax<T> {
estimate: [MinmaxSample<T>; 3],
}

impl<T> Deref for Minmax<T> {
type Target = T;

fn deref(&self) -> &Self::Target {
&self.estimate[0].value
}
}

impl<T: PartialOrd + Copy> Minmax<T> {
pub fn new(val: T) -> Self {
Minmax {
Expand Down
10 changes: 5 additions & 5 deletions quiche/src/recovery/bbr/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@

use super::*;

use crate::recovery::Recovery;

use std::time::Instant;

// BBR Functions at Initialization.
//

Expand Down Expand Up @@ -59,11 +63,7 @@ fn bbr_init_round_counting(r: &mut Recovery) {
fn bbr_init_pacing_rate(r: &mut Recovery) {
let bbr = &mut r.bbr_state;

let srtt = r
.rtt_stats
.smoothed_rtt
.unwrap_or_else(|| Duration::from_millis(1))
.as_secs_f64();
let srtt = r.rtt_stats.smoothed_rtt.as_secs_f64();

// At init, cwnd is initcwnd.
let nominal_bandwidth = r.congestion_window as f64 / srtt;
Expand Down
8 changes: 3 additions & 5 deletions quiche/src/recovery/bbr2/pacing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,16 @@

use super::*;

use crate::recovery::Recovery;

// BBR2 Transmit Packet Pacing Functions
//

// 4.6.2. Pacing Rate: BBR.pacing_rate
pub fn bbr2_init_pacing_rate(r: &mut Recovery) {
let bbr = &mut r.bbr2_state;

let srtt = r
.rtt_stats
.smoothed_rtt
.unwrap_or_else(|| Duration::from_millis(1))
.as_secs_f64();
let srtt = r.rtt_stats.smoothed_rtt.as_secs_f64();

// At init, cwnd is initcwnd.
let nominal_bandwidth = r.congestion_window as f64 / srtt;
Expand Down
32 changes: 20 additions & 12 deletions quiche/src/recovery/cubic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ fn on_packet_acked(r: &mut Recovery, packet: &Acked, now: Instant) {
// target = w_cubic(t + rtt)
let target = r
.cubic_state
.w_cubic(t + r.rtt_stats.min_rtt, r.max_datagram_size);
.w_cubic(t + *r.rtt_stats.min_rtt, r.max_datagram_size);

// Clipping target to [cwnd, 1.5 x cwnd]
let target = f64::max(target, r.congestion_window as f64);
Expand Down Expand Up @@ -673,7 +673,8 @@ mod tests {
// Shift current time by 1 RTT.
let rtt = Duration::from_millis(100);

r.rtt_stats.update_rtt(rtt, Duration::from_millis(0), now);
r.rtt_stats
.update_rtt(rtt, Duration::from_millis(0), now, true);

// Exit from the recovery.
now += rtt;
Expand Down Expand Up @@ -814,7 +815,7 @@ mod tests {
let now = now + rtt_1st;
for _ in 0..n_rtt_sample {
r.rtt_stats
.update_rtt(rtt_1st, Duration::from_millis(0), now);
.update_rtt(rtt_1st, Duration::from_millis(0), now, true);

let mut acked = vec![Acked {
pkt_num: ack_pn,
Expand Down Expand Up @@ -855,7 +856,7 @@ mod tests {
for _ in 0..n_rtt_sample {
cwnd_prev = r.cwnd();
r.rtt_stats
.update_rtt(rtt_2nd, Duration::from_millis(0), now);
.update_rtt(rtt_2nd, Duration::from_millis(0), now, true);

let mut acked = vec![Acked {
pkt_num: ack_pn,
Expand Down Expand Up @@ -899,7 +900,7 @@ mod tests {
// Last ack will cause to exit to SS.
for _ in 0..n_rtt_sample {
r.rtt_stats
.update_rtt(rtt_3rd, Duration::from_millis(0), now);
.update_rtt(rtt_3rd, Duration::from_millis(0), now, true);

let mut acked = vec![Acked {
pkt_num: ack_pn,
Expand Down Expand Up @@ -975,7 +976,7 @@ mod tests {
let now = now + rtt_1st;
for _ in 0..n_rtt_sample {
r.rtt_stats
.update_rtt(rtt_1st, Duration::from_millis(0), now);
.update_rtt(rtt_1st, Duration::from_millis(0), now, true);

let mut acked = vec![Acked {
pkt_num: ack_pn,
Expand Down Expand Up @@ -1015,7 +1016,7 @@ mod tests {
for _ in 0..n_rtt_sample {
cwnd_prev = r.cwnd();
r.rtt_stats
.update_rtt(rtt_2nd, Duration::from_millis(0), now);
.update_rtt(rtt_2nd, Duration::from_millis(0), now, true);

let mut acked = vec![Acked {
pkt_num: ack_pn,
Expand Down Expand Up @@ -1055,8 +1056,12 @@ mod tests {

// Receiving Acks.
for _ in 0..n_rtt_sample {
r.rtt_stats
.update_rtt(rtt_css, Duration::from_millis(0), now);
r.rtt_stats.update_rtt(
rtt_css,
Duration::from_millis(0),
now,
true,
);

let mut acked = vec![Acked {
pkt_num: ack_pn,
Expand Down Expand Up @@ -1136,7 +1141,8 @@ mod tests {
}];

// Ack more than cwnd bytes with rtt=100ms
r.rtt_stats.update_rtt(rtt, Duration::from_millis(0), now);
r.rtt_stats
.update_rtt(rtt, Duration::from_millis(0), now, true);

// Trigger detecting spurious congestion event
r.on_packets_acked(&mut acked, now + rtt + Duration::from_millis(5));
Expand Down Expand Up @@ -1190,7 +1196,8 @@ mod tests {
}];

// Ack more than cwnd bytes with rtt=100ms.
r.rtt_stats.update_rtt(rtt, Duration::from_millis(0), now);
r.rtt_stats
.update_rtt(rtt, Duration::from_millis(0), now, true);

// Trigger detecting spurious congestion event.
r.on_packets_acked(&mut acked, now + rtt + Duration::from_millis(5));
Expand Down Expand Up @@ -1241,7 +1248,8 @@ mod tests {

// Shift current time by 1 RTT.
let rtt = Duration::from_millis(100);
r.rtt_stats.update_rtt(rtt, Duration::from_millis(0), now);
r.rtt_stats
.update_rtt(rtt, Duration::from_millis(0), now, true);

// Exit from the recovery.
now += rtt;
Expand Down
27 changes: 16 additions & 11 deletions quiche/src/recovery/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,12 +492,12 @@ impl Recovery {
self.bytes_sent += sent_bytes;

// Pacing: Set the pacing rate if CC doesn't do its own.
if !(self.cc_ops.has_custom_pacing)() {
if let Some(srtt) = self.rtt_stats.smoothed_rtt {
let rate = PACING_MULTIPLIER * self.congestion_window as f64 /
srtt.as_secs_f64();
self.set_pacing_rate(rate as u64, now);
}
if !(self.cc_ops.has_custom_pacing)() &&
self.rtt_stats.first_rtt_sample.is_some()
{
let rate = PACING_MULTIPLIER * self.congestion_window as f64 /
self.rtt_stats.smoothed_rtt.as_secs_f64();
self.set_pacing_rate(rate as u64, now);
}

self.schedule_next_packet(now, sent_bytes);
Expand Down Expand Up @@ -717,7 +717,12 @@ impl Recovery {

// Don't update srtt if rtt is zero.
if !latest_rtt.is_zero() {
self.rtt_stats.update_rtt(latest_rtt, ack_delay, now);
self.rtt_stats.update_rtt(
latest_rtt,
ack_delay,
now,
handshake_status.completed,
);
}
}

Expand Down Expand Up @@ -1053,7 +1058,7 @@ impl Recovery {

// Fill in a rate sample.
self.delivery_rate
.generate_rate_sample(self.rtt_stats.min_rtt);
.generate_rate_sample(*self.rtt_stats.min_rtt);

// Call congestion control hooks.
(self.cc_ops.on_packets_acked)(self, acked, now);
Expand Down Expand Up @@ -1124,7 +1129,7 @@ impl Recovery {
#[cfg(feature = "qlog")]
pub fn maybe_qlog(&mut self) -> Option<EventData> {
let qlog_metrics = QlogMetrics {
min_rtt: self.rtt_stats.min_rtt,
min_rtt: *self.rtt_stats.min_rtt,
smoothed_rtt: self.rtt(),
latest_rtt: self.rtt_stats.latest_rtt,
rttvar: self.rtt_stats.rttvar,
Expand Down Expand Up @@ -1238,7 +1243,7 @@ impl std::fmt::Debug for Recovery {

write!(f, "latest_rtt={:?} ", self.rtt_stats.latest_rtt)?;
write!(f, "srtt={:?} ", self.rtt_stats.smoothed_rtt)?;
write!(f, "min_rtt={:?} ", self.rtt_stats.min_rtt)?;
write!(f, "min_rtt={:?} ", *self.rtt_stats.min_rtt)?;
write!(f, "rttvar={:?} ", self.rtt_stats.rttvar)?;
write!(f, "cwnd={} ", self.congestion_window)?;
write!(f, "ssthresh={} ", self.ssthresh)?;
Expand Down Expand Up @@ -2187,7 +2192,7 @@ mod tests {

assert_eq!(r.epochs[packet::Epoch::Application].sent_packets.len(), 0);
assert_eq!(r.bytes_in_flight, 0);
assert_eq!(r.rtt_stats.smoothed_rtt.unwrap(), Duration::from_millis(50));
assert_eq!(r.rtt_stats.smoothed_rtt, Duration::from_millis(50));

// 1 MSS increased.
assert_eq!(r.congestion_window, 12000 + 1200);
Expand Down
3 changes: 2 additions & 1 deletion quiche/src/recovery/reno.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,8 @@ mod tests {
}];

// Ack more than cwnd bytes with rtt=100ms
r.rtt_stats.update_rtt(rtt, Duration::from_millis(0), now);
r.rtt_stats
.update_rtt(rtt, Duration::from_millis(0), now, true);
r.on_packets_acked(&mut acked, now + rtt * 2);

// After acking more than cwnd, expect cwnd increased by MSS
Expand Down
Loading

0 comments on commit 3b758cb

Please sign in to comment.