BBRv1 四项改进:KCC 仓库补丁详解

KCC 拥塞控制仓库提供了一套基于 Google BBRv1 的补丁,打包为独立模块 bbr1。本文档对比 tcp_bbr.c(原版)与 tcp_bbr1.c(补丁后)的差异,逐条说明每个改动的背景、实现、收益与代价。


概览

改动点 原版行为 补丁行为 影响场景
DRAIN 退出条件 OR 逻辑(1 RTT inflight ≤ BDP) AND + 超时(1 RTT inflight ≤ BDP,或 4×RTT 超时) 多流共享瓶颈
PROBE_BW up-phase 提前退出 固定条件(满 RTT + 丢包或达目标) 可配置增加 app-limited 或无数据退出 短连接、突发流量
PROBE_RTT 入口 所有流同时触发 基于 sk->sk_hash 添加抖动偏移 大规模并发
LT 带宽采样 直接判定 policer 增加拥塞门控(srtt > min_rtt+5ms 时拒绝) 避免误判

以下逐条展开。


一、DRAIN 退出条件:从 OR 改为 AND

原版代码(tcp_bbr.c

if (bbr->pacing_gain > BBR_UNIT)
    return is_full_length && (rs->losses || inflight >= bbr_inflight(...));
/* pacing_gain < 1.0 */
return is_full_length || inflight <= bbr_inflight(sk, bw, BBR_UNIT);

DRAIN 阶段退出条件为:满 1 个 RTT 或者 inflight 已降至 BDP 以下

问题

多流共享瓶颈时,单流 inflight 虽已达标,但多流叠加仍使瓶颈队列残留。过早退出 DRAIN 后进入 PROBE_BW 并以 1.25 倍增益发送,导致周期性延迟和丢包。

补丁后代码(tcp_bbr1.c

{
    bool drained = inflight <= bbr_inflight(sk, bw, BBR_UNIT);
    return (is_full_length && drained) ||
           tcp_stamp_us_delta(tp->delivered_mstamp, bbr->cycle_mstamp) >
           bbr->min_rtt_us << 2;
}

改为 必须同时满足满 1 个 RTT 且 inflight ≤ BDP 才正常退出,另加 4 倍 min_rtt 超时兜底。

流程图

满1RTT 或 inflight≤BDP

满1RTT 且 inflight≤BDP

超时超过 4×min_rtt

进入 DRAIN 阶段

原版判断

退出 DRAIN

继续 DRAIN

进入 DRAIN 阶段

补丁后判断

正常退出

继续 DRAIN

收益与代价

  • 收益:多流公平性提升,尾部延迟降低,队列长度更稳定。
  • 代价:单流、浅缓冲场景收敛稍慢(多出的等待时间通常远小于 200ms)。

二、PROBE_BW up-phase 提前退出选项

原版代码

PROBE_BW up-phase(pacing_gain = 1.25)的退出条件:

if (bbr->pacing_gain > BBR_UNIT)
    return is_full_length && (rs->losses || inflight >= target);

必须满 1 个 RTT (发生丢包 达到目标 inflight)才退出。

问题

当应用层数据不足(app-limited)或发送队列为空时,无法真正填满管道,但仍需等待满 RTT,浪费探测时间。

补丁后代码

新增编译选项 bbr_probe_bw_up_limit(默认 0,即关闭):

(bbr_probe_bw_up_limit && (rs->is_app_limited || !tcp_send_head(sk)))

若开启,则在上述条件中增加一项:允许 app-limited 或无待发数据时提前退出 up-phase。

流程图

满足

不满足

满足

不满足

处于 PROBE_BW up-phase
gain=1.25

检查是否结束当前相位

原版条件:满1个RTT 且
发生丢包 或 达到目标inflight

切换到下一相位

继续 up-phase

补丁后条件

原版条件 或
bbr_probe_bw_up_limit=1 且
app-limited 或 无待发数据

切换到下一相位

继续 up-phase

收益与代价

  • 收益:短连接、突发流量场景减少无效等待,提高探测效率。
  • 代价:默认关闭(bbr_probe_bw_up_limit = 0),因为长连接高吞吐场景下提前退出可能降低探测准确性。由用户按需开启。

三、PROBE_RTT 抖动避让

原版代码

bbr_update_min_rtt() 中判断过滤器是否过期:

filter_expired = after(tcp_jiffies32,
                       bbr->min_rtt_stamp + bbr_min_rtt_win_sec * HZ);

所有流同时过期,同时进入 PROBE_RTT(cwnd 降至 4),退出后又同时以 1.25 倍增益发送,造成周期性吞吐量塌陷。

补丁后代码

u32 jitter_jif = 0;
if (bbr->min_rtt_us != ~0U && bbr->min_rtt_us > 0)
    jitter_jif = usecs_to_jiffies(
        (u32)(sk->sk_hash & 0xFF) * bbr->min_rtt_us >> 6);
filter_expired = after(tcp_jiffies32,
    bbr->min_rtt_stamp + bbr_min_rtt_win_sec * HZ + jitter_jif);

每个流基于 sk->sk_hash 获得不同偏移,打散 PROBE_RTT 启动时间。

流程图

检查 min_rtt 过滤器是否过期

原版

expired = 当前时间 ≥ min_rtt_stamp + 10秒

若 expired 且未在 PROBE_RTT 则进入

检查 min_rtt 过滤器是否过期

补丁后

计算 jitter = hash & 0xFF * min_rtt_us / 64

expired = 当前时间 ≥ min_rtt_stamp + 10秒 + jitter

若 expired 且未在 PROBE_RTT 则进入

收益与代价

  • 收益:彻底消除多流同步震荡,大规模并发下 RTT 和丢包率更平稳。
  • 代价:个别流 PROBE_RTT 间隔可能延长至约 10.4 秒,min_rtt 刷新频率略微下降,对整体性能影响极小。

四、LT 带宽采样增加拥塞门控

原版代码

bbr_lt_bw_interval_done() 中,当两个采样区间 bw 一致且 loss 率达标后,直接启用 lt_bw

问题

路径发生拥塞时,loss 可能由队列溢出而非 policer 导致。此时启用 LT 带宽会错误地限制发送速率。

补丁后代码

在判定为 policed 之前增加瞬时拥塞检查:

u32 srtt_us = tp->srtt_us >> 3;
if (srtt_us > bbr->min_rtt_us + 5000) {
    bbr_reset_lt_bw_sampling(sk);
    return;
}

若当前 srtt 比 min_rtt 高出 5ms 以上,认为路径存在排队,不启用 LT 带宽估计。

流程图

完成一个 LT 采样区间
获得新 bw 样本

bbr->lt_bw 存在?

bw 与 lt_bw 接近?

检查当前 srtt > min_rtt + 5ms?

重置采样,不启用 lt_bw

启用 lt_bw = 平均 bw
pacing_gain = 1

保存新 bw,继续采样

收益与代价

  • 收益:避免因拥塞丢包误判为 policer,减少不必要的限速。
  • 代价:5ms 阈值是经验值,某些高延迟路径可能误触发(概率较低)。

补丁集成说明

上述四项改动已完整集成于 KCC 仓库的 tcp_bbr1.c,编译后模块名为 bbr1(而非原版 bbr)。使用时需:

  1. 替换或额外编译 tcp_bbr1.c 为内核模块;
  2. 通过 sysctl net.ipv4.tcp_congestion_control = bbr1 启用。

与原版 BBR 不冲突,可并行存在。


小结

改动 原版问题 补丁方案 适用场景
DRAIN 退出 队列排空不彻底 AND + 超时 多流共享瓶颈
PROBE_BW up exit app-limited 无效等待 可配置提前退出 短连接/突发流量
PROBE_RTT 入口 同步震荡 哈希抖动 大规模并发
LT 采样 拥塞误判 policer 拥塞门控 避免限速错误

以上为 KCC bbr1 相对于原版 BBRv1 的全部改动。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐