Skip to content

Commit 289c67b

Browse files
committed
fixed inflight, fixed several calculation errors, fixed pacing logic to not be affected by leaky bucket logic
1 parent ee7d629 commit 289c67b

File tree

2 files changed

+36
-31
lines changed

2 files changed

+36
-31
lines changed

quinn-proto/src/congestion/bbr3/mod.rs

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -212,19 +212,22 @@ struct BbrPacket {
212212
struct BbrRateSample {
213213
/// equivalent to RS.delivery_rate: The delivery rate (aka bandwidth) sample obtained from the packet that has just been ACKed.
214214
delivery_rate: f64,
215-
/// equivalent to RS.is_app_limited
215+
/// equivalent to RS.is_app_limited: The P.is_app_limited from the most recent packet
216+
/// delivered; indicates whether the rate sample is application-limited.
216217
is_app_limited: bool,
217-
/// equivalent to RS.interval
218+
/// equivalent to RS.interval: The length of the sampling interval.
218219
interval: Duration,
219220
/// equivalent to RS.delivered: The volume of data delivered between the transmission of the packet that has just been ACKed and the current time.
220221
delivered: u64,
221-
/// equivalent to RS.prior_delivered
222+
/// equivalent to RS.prior_delivered: The P.delivered count from the most recent packet delivered.
222223
prior_delivered: u64,
223-
/// equivalent to RS.prior_time
224+
/// equivalent to RS.prior_time: The P.delivered_time from the most recent packet delivered.
224225
prior_time: Instant,
225-
/// equivalent to RS.send_elapsed
226+
/// equivalent to RS.send_elapsed: Send time interval calculated from the most recent
227+
/// packet delivered (see the "Send Rate" section above).
226228
send_elapsed: Duration,
227-
/// equivalent to RS.ack_elapsed
229+
/// equivalent to RS.ack_elapsed: ACK time interval calculated from the most recent
230+
/// packet delivered (see the "ACK Rate" section above).
228231
ack_elapsed: Duration,
229232
/// equivalent to RS.rtt: The RTT sample calculated based on the most recently-sent packet of the packets that have just been ACKed.
230233
rtt: Duration,
@@ -516,14 +519,14 @@ impl Bbr3 {
516519
bw_latest: 0.0,
517520
inflight_latest: 0,
518521
max_bw_filter: MaxFilter::new(MAX_BW_FILTER_LEN as u64),
519-
extra_acked_interval_start: None,
522+
extra_acked_interval_start: Some(Instant::now()),
520523
extra_acked_delivered: 0,
521524
extra_acked_filter: MaxFilter::new(EXTRA_ACKED_FILTER_LEN as u64),
522525
full_bw_reached: false,
523526
full_bw_now: false,
524527
full_bw: 0.0,
525528
full_bw_count: 0,
526-
min_rtt_stamp: None,
529+
min_rtt_stamp: Some(Instant::now()),
527530
min_rtt_filter_len: MIN_RTT_FILTER_LEN,
528531
probe_rtt_cwnd_gain,
529532
probe_rtt_duration: Duration::from_millis(PROBE_RTT_DURATION_MS),
@@ -580,13 +583,12 @@ impl Bbr3 {
580583
/// equivalent to BBRInflightAtLoss <https://www.ietf.org/archive/id/draft-ietf-ccwg-bbr-04.html#section-5.5.10.2-11>
581584
/// We check at what prefix of packet did losses exceed `loss_thresh`
582585
fn inflight_at_loss(&mut self, lost_bytes: u64) -> u64 {
583-
let inflight_prev;
584586
if let Some(rate_sample) = self.rs {
585-
inflight_prev = rate_sample.tx_in_flight.saturating_sub(lost_bytes);
587+
let inflight_prev = rate_sample.tx_in_flight.saturating_sub(lost_bytes);
586588
let lost_prev = rate_sample.lost.saturating_sub(lost_bytes);
587589
let compared_loss = inflight_prev.saturating_sub(lost_prev);
588590
let lost_prefix = (self.loss_thresh * compared_loss as f64) / (1.0 - self.loss_thresh);
589-
let inflight_at_loss = inflight_prev.saturating_sub(lost_prefix as u64);
591+
let inflight_at_loss = inflight_prev + lost_prefix as u64;
590592
return inflight_at_loss;
591593
}
592594
0
@@ -657,14 +659,13 @@ impl Bbr3 {
657659
}
658660

659661
if self.is_inflight_too_high() {
660-
let mut new_inflight_hi = self.bdp;
662+
let mut new_inflight_hi = self.bdp.max(self.inflight_latest);
661663
if let Some(rate_sample) = self.rs {
662-
if new_inflight_hi < rate_sample.prior_delivered {
663-
new_inflight_hi = rate_sample.prior_delivered;
664+
if new_inflight_hi < rate_sample.delivered {
665+
new_inflight_hi = rate_sample.delivered;
664666
}
665667
}
666-
667-
self.inflight_latest = new_inflight_hi;
668+
self.inflight_longterm = new_inflight_hi;
668669
self.full_bw_reached = true;
669670
}
670671
}
@@ -1087,6 +1088,7 @@ impl Bbr3 {
10871088
{
10881089
self.max_bw_filter
10891090
.update_max(self.cycle_count, rate_sample.delivery_rate.round() as u64);
1091+
10901092
self.max_bw = self.max_bw_filter.get_max() as f64;
10911093
}
10921094
}
@@ -1253,8 +1255,8 @@ impl Bbr3 {
12531255
if self.loss_round_start {
12541256
if let Some(rate_sample) = self.rs {
12551257
self.bw_latest = rate_sample.delivery_rate;
1258+
self.inflight_latest = rate_sample.delivered;
12561259
}
1257-
self.inflight_latest = self.delivered;
12581260
}
12591261
}
12601262

@@ -1376,10 +1378,8 @@ impl Controller for Bbr3 {
13761378
self.first_send_time = Some(now);
13771379
self.delivered_time = Some(now);
13781380
}
1379-
if bytes > 0 {
1380-
let added_bytes = bytes as u64;
1381-
self.inflight += added_bytes;
1382-
}
1381+
let added_bytes = bytes as u64;
1382+
self.inflight += added_bytes;
13831383
self.packets.push_back(BbrPacket {
13841384
delivered: self.delivered,
13851385
delivered_time: self.delivered_time.unwrap_or(now),
@@ -1407,7 +1407,6 @@ impl Controller for Bbr3 {
14071407
let bytes64 = bytes as u64;
14081408
if let Some(mut rate_sample) = self.rs {
14091409
rate_sample.newly_acked += bytes64;
1410-
rate_sample.rtt = rtt.get();
14111410
self.rs = Some(rate_sample);
14121411
self.delivered += bytes64;
14131412
self.delivered_time = Some(now);
@@ -1420,8 +1419,9 @@ impl Controller for Bbr3 {
14201419
if let Some(p) = self.packets.get_mut(p_index) {
14211420
p.acknowledged = true;
14221421
if let Some(mut rate_sample) = self.rs {
1422+
rate_sample.rtt = now - p.send_time;
14231423
if is_newest_packet {
1424-
self.srtt = rate_sample.rtt;
1424+
self.srtt = rtt.get();
14251425
rate_sample.prior_delivered = p.delivered;
14261426
rate_sample.prior_time = p.delivered_time;
14271427
rate_sample.is_app_limited = p.is_app_limited;
@@ -1471,9 +1471,9 @@ impl Controller for Bbr3 {
14711471
app_limited: bool,
14721472
largest_packet_num_acked: Option<u64>,
14731473
) {
1474-
self.inflight = in_flight.ack_eliciting;
1474+
self.inflight = in_flight.bytes;
14751475
if let Some(largest_packet_num) = largest_packet_num_acked {
1476-
if app_limited {
1476+
if app_limited && self.delivered > self.app_limited {
14771477
self.app_limited = largest_packet_num;
14781478
} else {
14791479
self.app_limited = 0;
@@ -1505,6 +1505,8 @@ impl Controller for Bbr3 {
15051505
}
15061506
}
15071507
rate_sample.newly_acked = 0;
1508+
rate_sample.lost = 0;
1509+
rate_sample.newly_lost = 0;
15081510
self.rs = Some(rate_sample);
15091511
}
15101512
} else if self.app_limited > 0 && self.delivered > self.app_limited {

quinn-proto/src/connection/pacing.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,15 @@ impl Pacer {
8181
self.tokens = self.capacity.min(self.tokens);
8282
}
8383

84+
if let Some(pacing_rate) = pacing_rate {
85+
if bytes_to_send <= self.capacity {
86+
return None;
87+
}
88+
let capped_bytes_to_send = bytes_to_send.max(self.capacity);
89+
let delay = Duration::from_secs_f64(capped_bytes_to_send as f64 / pacing_rate as f64);
90+
return Some(now + delay);
91+
}
92+
8493
// if we can already send a packet, there is no need for delay
8594
if self.tokens >= bytes_to_send {
8695
return None;
@@ -117,12 +126,6 @@ impl Pacer {
117126
return None;
118127
}
119128

120-
if let Some(pacing_rate) = pacing_rate {
121-
let capped_bytes_to_send = bytes_to_send.max(self.capacity);
122-
let delay = Duration::from_secs_f64(capped_bytes_to_send as f64 / pacing_rate as f64);
123-
return Some(now + delay);
124-
}
125-
126129
let unscaled_delay = smoothed_rtt
127130
.checked_mul((bytes_to_send.max(self.capacity) - self.tokens) as _)
128131
.unwrap_or(Duration::MAX)

0 commit comments

Comments
 (0)