拥塞算法中消除delay_ack的影响

    在2.6.32内核中,基于丢包的拥塞算法基本都需要考虑,delay_ack所带来的影响。例如每个ack都确认两个数据包,如果被拥塞算法当做一个ack确认一个数据包,那窗口的增加速率必然下降。在4.9内核版本之前,由于拥塞窗口接口函数原型中并不携带本次ack确认多少个数据包信息,当拥塞窗口进行调整时,确需要考虑到delay_ack进行适当的调整。主要的过程是使用类似计算srtt_us的方式,估算一个ack平均确认多少个数据包,在拥塞窗口调整时,对调整幅度进行微调。

主要数据结构

    struct tcp_congestion_ops {

    struct list_head list;

    unsigned long flags;

    /* initialize private data (optional) */

    void (*init)(struct sock *sk);

    /* cleanup private data  (optional) */

    void (*release)(struct sock *sk);

    /* return slow start threshold (required) */

    u32 (*ssthresh)(struct sock *sk);

    /* lower bound for congestion window (optional) */

    u32 (*min_cwnd)(const struct sock *sk);

    /* do new cwnd calculation (required) */

    void (*cong_avoid)(struct sock *sk, u32 ack, u32 in_flight);//拥塞窗口调整接口

    /* call before changing ca_state (optional) */

    ...

    void (*pkts_acked)(struct sock *sk, u32 num_acked, s32 rtt_us);//收到ack确认数据包调用接口

    /* get info for inet_diag (optional) */

    void (*get_info)(struct sock *sk, u32 ext, struct sk_buff *skb);

    char name[TCP_CA_NAME_MAX];

    struct module *owner;

    };

需要注意的是4.9内核中拥塞窗口调整函数原型已经变为

    void (*cong_avoid)(struct sock *sk, u32 ack, u32 acked);

不同之处在于最后一个变量,网络中存在数据包个数in_flight变为了本次ack确认的数据包个数。已经将该ack确认的数据包个数传递进来,因此,不需要再进行delay_ack的比例估算。

以2.6.32内核中的bic算法为例,使用计算平均delay_ack比例在拥塞窗口调整函数bictcp_cong_avoid中调用bictcp_update函数

    static void bictcp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)

    {

    struct tcp_sock *tp = tcp_sk(sk);

    struct bictcp *ca = inet_csk_ca(sk);

    if (!tcp_is_cwnd_limited(sk, in_flight))

        return;

    if (tp->snd_cwnd <= tp->snd_ssthresh)

        tcp_slow_start(tp);

    else {

        bictcp_update(ca, tp->snd_cwnd);

        tcp_cong_avoid_ai(tp, ca->cnt);

    }

    }

bictcp_update函数中结尾部分,对控制调整拥塞窗口快慢的变量ca->cnt进行按比例调整。

    static inline void bictcp_update(struct bictcp *ca, u32 cwnd)

    {

    ....

    ca->cnt = (ca->cnt << ACK_RATIO_SHIFT) / ca->delayed_ack; //对调整拥塞窗口的幅度进行按比例调整

    if (ca->cnt == 0) /* cannot be zero */

    ca->cnt = 1;

    }

而估算delay_ack比例的部分在(*pkts_acked)接口函数中进行

    #define ACK_RATIO_SHIFT 4

    /* Track delayed acknowledgment ratio using sliding window

    * ratio = (15*ratio + sample) / 16

    */

    static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt)

    {

    const struct inet_connection_sock *icsk = inet_csk(sk);

    if (icsk->icsk_ca_state == TCP_CA_Open) {

        struct bictcp *ca = inet_csk_ca(sk);

        cnt -= ca->delayed_ack >> ACK_RATIO_SHIFT;

        ca->delayed_ack += cnt;

    }

    }

代码比较简单就不分析了,但是存在一个bug,假设初始状态ca->delayed_ack = 32,每次ack都不是delay_ack,都确认一个数据包,ca->delay_ack最小值却停留在31,不会继续减小。原因就是先ca->delay_ack/16,由于整型除法是向下取整,因此

cubic版本中对delay_ack的计算也类似,也存在ca->delay_ack最小值为31的问题,不同的是增加了最大值限制。

    #define ACK_RATIO_SHIFT 4

    #define ACK_RATIO_LIMIT (32u << ACK_RATIO_SHIFT)

    static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt_us)

    {

        const struct inet_connection_sock *icsk = inet_csk(sk);

        const struct tcp_sock *tp = tcp_sk(sk);

        struct bictcp *ca = inet_csk_ca(sk);

        u32 delay;

        if (icsk->icsk_ca_state == TCP_CA_Open) {

            u32 ratio = ca->delayed_ack;

            ratio -= ca->delayed_ack >> ACK_RATIO_SHIFT;

            ratio += cnt;

            ca->delayed_ack = min(ratio, ACK_RATIO_LIMIT);//最大比例不能超过32

        }

        ......

    }

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容