• TCP拥塞控制算法 — CUBIC的补丁(一)


    cubic从2.6.37到3.0之间有7个patch,从3.0到3.8(当前最新版本)中无patch。

    描述

    以下是提交者Stephen Hemminger对这个patch的描述:

    fix comparison of jiffies

    Jiffies wraps around therefore the correct way to compare is to use cast to signed value.

    Note: cubic is not using full jiffies value on 64 bit arch because using full unsigned long

    makes struct bictcp grow too large for the available ca_priv area.

    Includes correction from Sangtae Ha to improve ack train detection.

    代码

    --- a/net/ipv4/tcp_cubic.c
    +++ b/net/ipv4/tcp_cubic.c
    @@ -342,9 +342,11 @@ static void hystart_update(struct sock *sk, u32 delay)
                    u32 curr_jiffies = jiffies;
     
                    /* first detection parameter - ack-train detection */
    -               if (curr_jiffies - ca->last_jiffies <= msecs_to_jiffies(2)) {
    +               if ((s32)(curr_jiffies - ca->last_jiffies) <=
    +                   msecs_to_jiffies(2)) {
                            ca->last_jiffies = curr_jiffies;
    -                       if (curr_jiffies - ca->round_start >= ca->delay_min>>4)
    +                       if ((s32) (curr_jiffies - ca->round_start) >
    +                           ca->delay_min >> 4)
                                    ca->found |= HYSTART_ACK_TRAIN;
                    }

    分析

    @arch/x86/include/asm/posix_types_64.h:
    typedef long __kernel_time_t;
    typedef long __kernel_suseconds_t;
    
    @include/linux/time.h:
    struct timeval {
        __kernel_time_t tv_sec; /* seconds */
        __kernel_suseconds_t tv_usec; /* microseconds */
    }
    
    @include/linux/raid/pq.h:
    typedef uint32_t u32;
    
    #define jiffies raid6_jiffies()
    
    #undef HZ
    #define HZ 1000
    
    static inline uint32_t raid6_jiffies(void)
    {
        struct timeval tv;
        gettimeofday(&tv, NULL);
        return tv.tv_sec * 1000 + tv.tv_usec/1000;
    }

    我们可以看到jiffies为u32类型,单位为毫秒。这样一来jiffies在49.7天后就会溢出。

    当jiffies达到最大值后,它的值就会回绕到0。

    u32 a;

    u32 b;

    (a - b)为u32的,如果a < b,但是这时的结果为正数,则不能正确表示a和b的大小关系。

    所以需要把结果转化为有符号的,即(s32)(a - b)。

    评价

    我们知道从道理上讲curr_jiffies应该总大于last_jiffies和round_start的,因为后两个是过去的时间。

    这个patch并不能保证这一点,所以当curr_jiffies回绕时,还是会出现错误判断!

    因为这个时候 (curr_jiffies - ca->round_start )总是小于0的。 

    当然,回绕发生的概率低(49.7天一次),被这个函数遇到的概率更低,并且除了ack train方法外还有

    delay increase来检查退出点,所以影响微乎其微。

    其实要更彻底解决这个问题,只需要把ca->round_start和ca->last_jiffies换为u64类型,再使用64位

    jiffies即可。这样在任何人的有生之年都别指望看到jiffies溢出了。提交者没有这样做的原因是这会使

    bictcp结构的大小超出icsk_ca_priv所指向空间的大小,而其实增大icsk_ca_priv所指向空间大小是很

    方便的。

    Author

    zhangskd @ csdn blog



  • 相关阅读:
    存储器
    存储器
    存储器
    计算机组成原理目录
    锁原理
    锁原理
    并发编程
    Java 算法
    Java 数据结构
    Java数据结构
  • 原文地址:https://www.cnblogs.com/aiwz/p/6333353.html
Copyright © 2020-2023  润新知