欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-07-06 16:21:14
...

昨晚凌晨抵达深圳,今早时间有限,于是就长话短说,但无论如何还是会有一些输出的,这次关于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

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

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

  请注意,这是一个主动的补偿,而非盲目的补偿,相比那些满天飞的把窗口增加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 <linux/module.h>
 #include <net/tcp.h>
+#include <linux/skbuff.h>
 #include <linux/inet_diag.h>
 #include <linux/inet.h>
 #include <linux/random.h>
@@ -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 <aaa@qq.com>");
 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给了人们犯罪的一把利器,一把没有开刃的刀具,但绝不是一把没有子弹的枪。


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

后记

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