当前位置:网站首页>BBR bandwidth per second conversion logic

BBR bandwidth per second conversion logic

2022-06-24 21:24:00 already_ skb

/* Scale factor for rate in pkt/uSec unit to avoid truncation in bandwidth
 * estimation. The rate unit ~= (1500 bytes / 1 usec / 2^24) ~= 715 bps.
 * This handles bandwidths from 0.06pps (715bps) to 256Mpps (3Tbps) in a u32.
 * Since the minimum window is >=4 packets, the lower bound isn't
 * an issue. The upper bound isn't an issue with existing technologies.
 */
#define BW_SCALE 24
#define BW_UNIT (1 << BW_SCALE)

#define BBR_SCALE 8 /* scaling factor for fractions in BBR (e.g. gains) */
#define BBR_UNIT (1 << BBR_SCALE)






static void bbr_init_pacing_rate_from_rtt(struct sock *sk)
{
    struct tcp_sock *tp = tcp_sk(sk);
    struct bbr *bbr = inet_csk_ca(sk);
    u64 bw;
    u32 rtt_us;

    if (tp->srtt_us) {      /* any RTT sample yet? */
        rtt_us = max(tp->srtt_us >> 3, 1U);
        bbr->has_seen_rtt = 1;
    } else {             /* no RTT sample yet */
        rtt_us = USEC_PER_MSEC;  /* use nominal default RTT */
    }
    bw = (u64)tp->snd_cwnd * BW_UNIT;
    do_div(bw, rtt_us);
    sk->sk_pacing_rate = bbr_bw_to_pacing_rate(sk, bw, bbr_high_gain);
}

static u32 bbr_bw_to_pacing_rate(struct sock *sk, u32 bw, int gain)
{
    u64 rate = bw;

    rate = bbr_rate_bytes_per_sec(sk, rate, gain);
    rate = min_t(u64, rate, sk->sk_max_pacing_rate);
    return rate;
}

static u64 bbr_rate_bytes_per_sec(struct sock *sk, u64 rate, int gain)
{
    rate *= tcp_mss_to_mtu(sk, tcp_sk(sk)->mss_cache);
    rate *= gain;
    rate >>= BBR_SCALE;
    rate *= USEC_PER_SEC;
    return rate >> BW_SCALE;
}

Normally, the conversion logic should be like this :

bw(B/s) = cwnd * mss * gain / rtt_us * 1000000L

But avoid the error caused by division , So when it comes to design , Did the amplification operation .

1)BBR In order to reduce the error introduced by Division , Multiplied by BW_UNIT : 

bw = (u64)tp->snd_cwnd * BW_UNIT;

2) Multiplied by mss  and   gain(gain Also magnified 256):

    rate *= tcp_mss_to_mtu(sk, tcp_sk(sk)->mss_cache);
    rate *= gain;

3) Next you need to remove BBR_UNIT:

    rate >>= BBR_SCALE;

4) Convert to second granularity results :

    rate *= USEC_PER_SEC;

5) Divided by the initial amplification factor
    return rate >> BW_SCALE;

It's written in a roundabout way , But there is no better way .

原网站

版权声明
本文为[already_ skb]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202211315156011.html