Cong Avoid
low_window = 14
BICTCP_B = 4
max_increment = 16
smooth_part = 20
if (cwnd < ca->last_max_cwnd) {
__u32 dist = (ca->last_max_cwnd - cwnd) / BICTCP_B;
if (dist > max_increment)
ca->cnt = cwnd / max_increment;
else if (dist <= 1U)
ca->cnt = (cwnd * smooth_part) / BICTCP_B;
else
ca->cnt = cwnd / dist;
} else {
if (cwnd < ca->last_max_cwnd + BICTCP_B)
ca->cnt = (cwnd * smooth_part) / BICTCP_B;
else if (cwnd < ca->last_max_cwnd + max_increment*(BICTCP_B-1))
ca->cnt = (cwnd * (BICTCP_B-1)) / (cwnd - ca->last_max_cwnd);
else
ca->cnt = cwnd / max_increment;
/* delayed_ack = (15/16) * delayed_ack + (1/16)cnt */
ca->cnt = (ca->cnt << ACK_RATIO_SHIFT) / ca->delayed_ack;
}
增长曲线分为六段,离last_max_cwnd越近增长越慢
- cwnd < last_max_cwnd
- dist > max_increment
- 1U < dist <= max_increment
- dist <= 1U
- cwnd >= last_max_cwnd
- cwnd < last_max_cwnd + BICTCP_B
- cwnd < last_max_cwnd + max_increment*(BICTCP_B-1)
- cwnd >= last_max_cwnd + max_increment*(BICTCP_B-1)
Recalc Ssthresh
if (tp->snd_cwnd < ca->last_max_cwnd && fast_convergence)
/* last_max_cwnd = cwnd *(1024 + 819) / 2048 = 0.8999 * cwnd */
ca->last_max_cwnd = (tp->snd_cwnd * (BICTCP_BETA_SCALE + beta)) / (2 * BICTCP_BETA_SCALE);
else
ca->last_max_cwnd = tp->snd_cwnd;
ca->loss_cwnd = tp->snd_cwnd;
if (tp->snd_cwnd <= low_window)
return max(tp->snd_cwnd >> 1U, 2U);
else
/* ssthresh = cwnd * (819/1024) = 0.7998 * cwnd */
return max((tp->snd_cwnd * beta) / BICTCP_BETA_SCALE, 2U);
snd_ssthresh略小于last_max_cwnd,方便前期使用慢启动快速逼近阈值。