Re: [PATCH net-next v4 09/15] quic: add congestion control
Xin Long <[email protected]> Thu, 6 Nov 2025 15:24:30 -0500
| Newsgroups | dev.linux.lists.quic,dev.linux.lists.kernel-tls-handshake,org.kernel.vger.linux-cifs,org.kernel.vger.netdev |
|---|---|
| Message-ID | <CADvbK_d8WoKJkU7ACK6nzbv7hzxxkAYZ5--DPzVQHsSZbEJnuw@mail.gmail.com> |
On Tue, Nov 4, 2025 at 7:02 AM Paolo Abeni <[email protected]> wrote: > > On 10/29/25 3:35 PM, Xin Long wrote: > > +/* Compute and update the pacing rate based on congestion window and smoothed RTT. */ > > +static void quic_cong_pace_update(struct quic_cong *cong, u32 bytes, u32 max_rate) > > +{ > > + u64 rate; > > + > > + /* rate = N * congestion_window / smoothed_rtt */ > > + rate = (u64)cong->window * USEC_PER_SEC * 2; > > + if (likely(cong->smoothed_rtt)) > > + rate = div64_ul(rate, cong->smoothed_rtt); > > + > > + WRITE_ONCE(cong->pacing_rate, min_t(u64, rate, max_rate)); > > + pr_debug("%s: update pacing rate: %u, max rate: %u, srtt: %u\n", > > + __func__, cong->pacing_rate, max_rate, cong->smoothed_rtt); > > I think you should skip entirely the pacing_rate update when > `smoothed_rtt == 0` > will update it. > [...]> +/* rfc9002#section-5: Estimating the Round-Trip Time */ > > +void quic_cong_rtt_update(struct quic_cong *cong, u32 time, u32 ack_delay) > > +{ > > + u32 adjusted_rtt, rttvar_sample; > > + > > + /* Ignore RTT sample if ACK delay is suspiciously large. */ > > + if (ack_delay > cong->max_ack_delay * 2) > > + return; > > + > > + /* rfc9002#section-5.1: latest_rtt = ack_time - send_time_of_largest_acked */ > > + cong->latest_rtt = cong->time - time; > > + > > + /* rfc9002#section-5.2: Estimating min_rtt */ > > + if (!cong->min_rtt_valid) { > > + cong->min_rtt = cong->latest_rtt; > > + cong->min_rtt_valid = 1; > > + } > > + if (cong->min_rtt > cong->latest_rtt) > > + cong->min_rtt = cong->latest_rtt; > > + > > + if (!cong->is_rtt_set) { > > + /* rfc9002#section-5.3: > > + * smoothed_rtt = latest_rtt > > + * rttvar = latest_rtt / 2 > > + */ > > + cong->smoothed_rtt = cong->latest_rtt; > > + cong->rttvar = cong->smoothed_rtt / 2; > > + quic_cong_pto_update(cong); > > + cong->is_rtt_set = 1; > > + return; > > + } > > + > > + /* rfc9002#section-5.3: > > + * adjusted_rtt = latest_rtt > > + * if (latest_rtt >= min_rtt + ack_delay): > > + * adjusted_rtt = latest_rtt - ack_delay > > + * smoothed_rtt = 7/8 * smoothed_rtt + 1/8 * adjusted_rtt > > + * rttvar_sample = abs(smoothed_rtt - adjusted_rtt) > > + * rttvar = 3/4 * rttvar + 1/4 * rttvar_sample > > + */ > > + adjusted_rtt = cong->latest_rtt; > > + if (cong->latest_rtt >= cong->min_rtt + ack_delay) > > + adjusted_rtt = cong->latest_rtt - ack_delay; > > + > > + cong->smoothed_rtt = (cong->smoothed_rtt * 7 + adjusted_rtt) / 8; > > Out of sheer curiosity, is the compiler smart enough to use a 'srl 3' > for the above? > Yes. 266 cong->smoothed_rtt = (cong->smoothed_rtt * 7 + adjusted_rtt) / 8; 0x593d <+77>: mov (%rbx),%ecx ; ecx = cong->smoothed_rtt 0x593f <+79>: lea (%rax,%rcx,8),%edx ; edx = adjusted_rtt + (ecx * 8) 0x5942 <+82>: sub %ecx,%edx ; edx = adjusted_rtt + (8*ecx) - ecx = ecx*7 + adjusted_rtt 0x5946 <+86>: shr $0x3,%edx ; edx >>= 3 → divide by 8 0x594d <+93>: mov %edx,(%rbx) ; store result back to cong->smoothed_rtt Thanks.