zoukankan      html  css  js  c++  java
  • TCP拥塞控制算法 — CUBIC的补丁(四)

    描述

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

    enable high resolution ack time if needed

    This is a refined version of an earlier patch by Lucas Nussbaum.

    Cubic needs RTT values in miliseconds. If HZ < 1000 then the values will be too coarse.

    代码

    --- a/net/ipv4/tcp_cubic.c
    +++ b/net/ipv4/tcp_cubic.c
    @@ -459,6 +459,10 @@ static int __init cubictcp_register(void)
     	/* divide by bic_scale and by constant Srtt (100ms) */
     	do_div(cube_factor, bic_scale * 10);
     
    +	/* hystart needs ms clock resolution */
    +	if (hystart && HZ < 1000)
    +		cubictcp.flags |= TCP_CONG_RTT_STAMP;
    +
     	return tcp_register_congestion_control(&cubictcp);
     }

    分析

    @include/net/tcp.h:
    #define TCP_CONG_RTT_STAMP 0x02
    
    struct tcp_congestion_ops {
        ...
        unsigned long flags;
        ...
    };
    
    /**
     * @tstamp: Time we arrived
     */
    struct sk_buff {
        ...
        ktime_t tstamp;
        ...
    };
    
    static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets, u32 prior_snd_una)
    {
        ktime_t last_ackt = net_invalid_timestamp();
        ...
            ca_seq_rtt = now - scb->when;
            last_ackt = skb->tstamp;
        ...
        if (ca_ops->pkts_acked) {
            s32 rtt_us = -1;
    
            /* Is the ACK triggering packet unambiguous? */
            if (! (flag & FLAG_RETRANS_DATA_ACKED)) {
                /* High resolution needed and available? */
                if (ca_ops->flags & TCP_CONG_RTT_STAMP &&
                    ! ktime_equal(last_ackt, net_invalid_timestamp()))
                    rtt_us = ktime_us_delta(ktime_get_real(), last_ackt); /* 精确到微秒*/
    
                else if (ca_seq_rtt >= 0)
                    rtt_us = jiffies_to_usecs(ca_seq_rtt); /*精确度只有jiffies,一般是毫秒 */
            }
            ca_ops->pkts_acked(sk, pkts_acked, rtt_us);
        }
        ...
    }
    
    /**
     * ktime_equal - Compares two ktime_t variables to see if they are equal
     * @cmp1: comparable1
     * @cmp2: comparable2
     * Compare two ktime_t variables, returns 1 if equal
     */
    static inline int ktime_equal(const ktime_t cmp1, const ktime_t cmp2)
    {
        return cmp1.tv64 == cmp2.tv64;
    }
    
    static inline ktime_t net_invalid_timestamp(void)
    {
        return ktime_set(0, 0);
    }
    
    /* Set a ktime_t variable to a value in sec/nsec representation: */
    static inline ktime_t ktime_set (const long secs, const unsigned long nsecs)
    {
        return (ktime_t) { .tv = { .sec = secs, .nsec = nsecs} };
    }
    @tcp_transmit_skb
    /* If congestion control is doing timestamping, we must take such a timestamp
     * before we potentially clone/copy.
     */
    if (icsk->icsk_ca_ops->flags & TCP_CONG_RTT_STAMP)
        __net_timestamp(skb); /*设置skb->tstamp,记录发送时间*/
     
    static inline void __net_timestamp(struct sk_buff *skb)
    {
        skb->tstamp = ktime_get_real(); /* 获取当前时间的ktime_t表示 */
    }
    

    评价

    我们知道当HZ < 1000时,计算得到的RTT的精确度就在1ms以上。这个时候可以通过设置

    TCP_CONG_RTT_STAMP标志来获得更高精度的RTT,测量得到的RTT可以精确到微秒。

    但是由于x86机器的HZ一般为1000,所以这个补丁的影响有限。

    Author

    zhangskd @ csdn blog

  • 相关阅读:
    PHP连接MYSQL数据库
    Eclipse读取xml中文乱码问题解决
    JSP
    参考代码案例
    EL和JSTL(2)
    EL和JSTL(1)
    状态管理(之cookie、session、filter、listener)
    一、Servlet
    状态管理(之cookie、session、filter、listener)
    spring
  • 原文地址:https://www.cnblogs.com/aiwz/p/6333350.html
Copyright © 2011-2022 走看看