TCP BBR失速控制的一个小trick一个小patch

昨晚凌晨抵达深圳,今早时间有限,于是就长话短说,但无论如何还是会有一些输出的,这次关于BBR。我曾经说过,我是不需要太多睡眠的,凌晨3点睡,照样早上6点起,应该可以把华为的人熬到cusi吧…不得而知了。

  晚上的火车上,手机充电很难,于是我拿着纸笔比划着一些传统的东西,好不容易蹭到了一个充电桩…满格100%后我看了几篇技术文章,其中有一个猛烈点的关于BBR的优化,当然这个不是我写的,虽然参考了我写的东西但还不是我写的,虽然我知道怎么写但我从来没写过反而还故意误导而反写。

  我看到了人性!看到了人自私的本质。…好吧,我承认,Google的BBR 2.0已经在逐步满足人们贪婪的本质了,这很OK,非常OK,然而非常容易被恶意利用。所以,我强烈反对这种控制论范畴的代码开源,强烈反对。

  没有人知道如何衡量公平性,是的,没有人知道,人们也不在乎。人们在乎的是,以激进为荣,以退让为耻,哪怕大家玉石俱焚反正只要你不成功我就很欣慰…

  云青青兮欲雨,水淡淡兮生烟,杭州西湖美景却挤满了拍照发朋友圈的人扔下成吨的垃圾,TCP…也就不说了…

  倚南窗以寄傲,审容膝之易安。小桥流水,可与鸿儒畅谈,江南烟雨中,杯酒杯茶可与思绪共勉,走在泥泞的土路上,仰头,想起了5年前…


BBR失速控制

很多人是真的不懂这些细节的,从多少次的聊天中就可以得知。前一篇文章说了TCP失速的原理:
从CUBIC/BBR的TCP ACK失速说起:https://blog.csdn.net/dog250/article/details/80140194
这里展示一下TCP BBR失速控制的原理:

TCP BBR失速控制的一个小trick一个小patch_第1张图片

可以看到,之所以没有发生真正的失速,是因为通过某种方式补偿了cwnd,即通过extral来补偿!

  总之,失速控制的关键在于,你要保持一个足够大的窗口,在由于ACK丢失,聚集(而不是原始数据丢失)引起的失速时仍然有足够的发送窗口

  请注意,这是一个主动的补偿,而非盲目的补偿,相比那些满天飞的把窗口增加 n n 倍,把参数调大这种拍脑袋的做法,这种方案明显是可取的。另外值得注意的是,如何计算当前的extral呢?我这里采用了一种常见的方案,当然还有另一种BBR推崇的方案(然而我并不喜欢):

  • 我的方案:采用移动指数平均来取extral;
  • BBR的方案:采用Window max来取extral。

哪个好?自己决定,反正思路就在这里,万变不离其宗。这也挺无趣的。


我的一个BBR失速控制patch

还是那句话,看破不说破,不传播负能量。通过上面的图解,很容易看出这种场景的解法,那么下面就是一个怎么做的patch:

--- tcp_bbr.c   2018-05-02 10:43:40.167859439 -0400
+++ tcp_bbr_new.c       2018-05-07 06:40:58.411514978 -0400
@@ -58,6 +58,7 @@
  */
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -116,6 +117,9 @@
                unused_b:5;
        u32     prior_cwnd;     /* prior cwnd upon entering loss recovery */
        u32     full_bw;        /* recent bw, to estimate if pipe is full */
+       u32     sextral;
+       u64     ack_interval;
+
 };

 #define CYCLE_LEN      8       /* number of phases in a pacing gain cycle */
@@ -429,6 +433,9 @@
                cwnd = cwnd + acked;
        cwnd = max(cwnd, bbr_cwnd_min_target);

+       if (!rs->losses) 
+               cwnd += bbr->sextral;
+
 done:
        tp->snd_cwnd = min(cwnd, tp->snd_cwnd_clamp);   /* apply global cap */
        if (bbr->mode == BBR_PROBE_RTT)  /* drain queue, refresh min_rtt */
@@ -653,7 +660,11 @@
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct bbr *bbr = inet_csk_ca(sk);
+       u32 extral;
        u64 bw;
+       u64 temp;
+
+       bbr->ack_interval = tcp_stamp_us_delta(tcp_clock_us(), bbr->ack_interval);

        bbr->round_start = 0;
        if (rs->delivered < 0 || rs->interval_us <= 0)
@@ -676,6 +687,11 @@
        bw = (u64)rs->delivered * BW_UNIT;
        do_div(bw, rs->interval_us);

+       temp = (u64)rs->delivered*bbr->ack_interval;
+       extral = (u64)rs->delivered - do_div(temp, rs->interval_us);
+       if (extral > 0) 
+               bbr->sextral = bbr->sextral - (bbr->sextral >> 3) + (extral >> 3);
+
        /* If this sample is application-limited, it is likely to have a very
         * low delivered count that represents application behavior rather than
         * the available network rate. Such a sample could drag down estimated
@@ -856,6 +872,8 @@
        bbr->cycle_idx = 0;
        bbr_reset_lt_bw_sampling(sk);
        bbr_reset_startup_mode(sk);
+       bbr->ack_interval = 0;
+       bbr->sextral = 0;

        cmpxchg(&sk->sk_pacing_status, SK_PACING_NONE, SK_PACING_NEEDED);
 }
@@ -952,3 +970,4 @@
 MODULE_AUTHOR("Soheil Hassas Yeganeh ");
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_DESCRIPTION("TCP BBR (Bottleneck Bandwidth and RTT)");
+// for Linux 4.14 by zhaoya the shabi!

有人就要问了,这么做真的可以吗?哦,我不明白所谓的可以指的是可以干什么…

  答案是,这么做不可以,这么做什么都不可以,这只是思路,这不是交付件!另外,这么做很有可能你会付出成本代价…

  如今类似的神器已经太多了,我也不怕得罪谁,我就实话实说。当初医院排队,12306抢票,后来上海拍车牌,然后就是各种学区房的挤抢占…总之我们已经处于一个资源必须抢,抢不到就毁的现实中,所有人的心理都是趋向于损人不利己,请注意这个不利己词,非常重要!不管自己成不成功,只要别人失败就行。

  这是典型的结果导向的恶果!我过不去,那么大家就都别过去,就这么简单。延伸到技术,那就是TCP加速!BBR是一个很不错的算法,然而它错在开源,结果被一大帮怀着各种目的的人改参数放大招,结果就是互联网传输通路越来越一塌糊涂,BBR给了人们犯罪的一把利器,一把没有开刃的刀具,但绝不是一把没有子弹的枪。


相信任何人都不希望传播技术负能量,用技术手段去控制资源据为己有,如果有能力,也不会任由那些不懂装懂的工具小子持续作恶。

后记

对了,昨天在高铁站买了一本书,在非常累的时候看看也是不错的,这本书是笔名二混子写的《半小时漫画世界史》,讲得非常好,我一直都想自己写一本这样的集子,但最终还是行动力欠佳…本来我是想看看这本书之后对于细节跟作者线上讨教一番的,但是没有发现可以怼的地方,所以我想线下讨教,有熟悉的人帮忙引荐一下,我想我和作者可以成为朋友…

你可能感兴趣的:(TCP BBR失速控制的一个小trick一个小patch)