免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1914 | 回复: 1
打印 上一主题 下一主题

TCP拥塞控制算法内核实现剖析(二) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-14 20:16 |只看该作者 |倒序浏览
TCP拥塞控制算法内核实现剖析(二)













内核版本:2.6.37

主要源文件:linux-2.6.37/ net/ ipv4/ tcp_bic.c



======================================================================================================
  1. /* BIC TCP Parameters */

  2. struct bictcp {

  3.         u32 cnt ; /* increase cwnd by 1 after ACKs */

  4.         u32 last_max_cwnd ; /* last maximum snd_cwnd */

  5.         u32 loss_cwnd ; /* congestion window at last loss */

  6.         u32 last_cwnd ; /* the last snd_cwnd */

  7.         u32 last_time ; /* time when updated last_cwnd */

  8.         u32 epoch_start ; /* beginning of an epoch */

  9. #define ACK_RATIO_SHIFT 4

  10.         u32 delayed_ack ; /* estimate the ratio of Packets/ACKs << 4 */

  11. } ;



  12. /* Scale factor beta calculation

  13. * max_cwnd = snd_cwnd * beta

  14. */

  15. #define BICTCP_BETA_SCALE 1024



  16. /* In binary search ,

  17. * go to point (max+min) / N

  18. */

  19. #define BICTCP_B 4   /*并不是真正的二分*/
复制代码
全局变量
  1. static int fast_convergence = 1 ; /* BIC能快速的达到一个平衡值,开关*/

  2. static int max_increment = 16 ; /* 每次增加的MSS 不能超过这个值,防止增长太过剧烈*/

  3. static int low_window = 14 ; /* lower bound on congestion window , for TCP friendliness */

  4. static int beta = 819 ; /* = 819 / 1024(BICTCP_BETA_SCALE) ,beta for multiplicative increase 。?*/

  5. static int initial_ssthresh ; /* 初始的阈值 */

  6. static int smooth_part = 20 ; /* log(B/(B*Smin))/log(B/(B-1))+B, # of RTT from Wmax-B to Wmax 。?*/

  7. /* initial_ssthresh的初始值被设置成2^31-1=2147483647 */
复制代码
==========================================================================================================
  1. struct inet_connection_sock {

  2.         ...

  3.         u32 icsk_ca_priv[16] ;

  4. #define ICSK_CA_PRIV_SIZE (16*sizeof(u32))

  5. }



  6. static inline void *inet_csk_ca( const struct sock *sk )

  7. {

  8.         return (void *)inet_csk(sk)->icsk_ca_priv ;

  9. }
复制代码
============================================================================================================

不明白?!

  1. /* Slow start with delack produces 3 packets of burst , so that it is safe "de facto". This will be

  2. * default - same as the default reordering threshold - but if reordering increases , we must

  3. * be able to allow cwnd to burst at least this much in order to not pull it back when holes

  4. * are filled.

  5. */

  6. static __inline__ __u32 tcp_max_burst ( const struct tcp_sock *sk )

  7. {

  8.         return tp->reordering ;

  9. }

  10. /* u8 reordering ; Packets reordering metric */



  11. /* RFC2681 Check whether we are limited by application or congestion window

  12. * This is the inverse of cwnd check in tcp_tso_should_defer

  13. */

  14. /* 返回0,不需要增加cwnd ; 返回1,cwnd被限制,需要增加 */

  15. int tcp_is_cwnd_limited ( const struct sock *sk , u32 in_flight )

  16. {

  17.         const struct tcp_sock *tp = tcp_sk(sk) ;

  18.         u32 left ;

  19.         if( in_flight >= tp->snd_cwnd ) /* 不是规定in_flight < snd_cwnd ? */

  20.                 return 1 ;

  21.         left = tp->snd_cwnd - in_flight ;

  22.         if( sk_can_gso(sk) &&

  23.                 left * sysctl_tcp_tso_win_divisor < tp->snd_cwnd &&

  24.                 left * tp->mss_cache < sk->sk_gso_max_size )

  25.                 return 1 ;

  26.         return left <= tcp_max_busrt( tp ) ;

  27. }
复制代码
=============================================================================================================
  1. static void bictcp_cong_avoid ( struct sock *sk , u32 ack , u32 in_flight )

  2. {

  3.         struct tcp_sock *tp = tcp_sk(sk) ;

  4.         struct bictcp *ca = inet_csk_ca(sk) ;

  5.         /* 如果发送拥塞窗口不被限制,不能再增加,则返回 */

  6.         if( !tcp_is_cwnd_limited(sk , in_flight))

  7.                 return ;

  8.         if( tp->snd_cwnd < tp->snd_ssthresh )

  9.                 tcp_slow_start( tp ) ;

  10.         else {

  11.                 bictcp_update(ca , tp->snd_cwnd ) ;

  12.                 tcp_cong_avoid_ai( tp , ca->cnt ) ;

  13.         }

  14. }
复制代码
从以上函数可以看出,BIC的慢启动和reno相同。在拥塞避免阶段,当snd_cwnd <= low_window ,两者也采用相同方法。

只有当snd_cwnd > low时,BIC才开始显示出它的特性。



在include/ net / tcp.h中,
  1. /* TCP timestamps are only 32-bits */

  2. #define tcp_time_stamps ((__u32)(jiffies))



  3. /*

  4. * Compute congestion window to use.

  5. */

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

  7. {

  8.         if ( ca->last_cwnd == cwnd &&

  9.                 (s32) ( tcp_time_stamp - ca->last_time) <= HZ / 32 )  /* 31.25ms以内不更新ca!!!*/

  10.         return ;

  11.         ca->last_cwnd = cwnd ;

  12.         ca->last_time = tcp_time_stamp ;

  13.         if ( ca->epoch_start == 0 ) /* recording the beginning of an epoch */

  14.                 ca->epoch_start = tcp_time_stamp ;

  15.         /* start off normal */

  16.         if( cwnd <= low_window ) {  /*为了保持友好性*/

  17.                 ca->cnt = cwnd ;  /*这样16个以内的ack,可使snd_cwnd++ */

  18.                 return ;

  19.         }

  20.         /* binary increase */

  21.         if ( cwnd < ca->last_max_cwnd ) {  /*上次掉包前一个snd_cwnd */

  22.                 __u32 dist = (ca->last_max_cwnd - cwnd) / BICTCP_B ; /* 四分之一 */

  23.                 if ( dist > max_increment ) /* linear increase */

  24.                         /*dist > 16,处于线性增长阶段,每收到16个ACK,会使snd_cwnd++ */

  25.                         ca->cnt = cwnd / max_increment ;

  26.                 else if ( dist <= 1U ) /* binary search increase */

  27.                         /* dist <=1 , ca->cnt=5*cwnd,会造成snd_cwnd增长极其缓慢,即处于稳定阶段 */

  28.                         ca->cnt = (cwnd * smooth_part ) / BICTCP_B ;

  29.                 else /* binary search increase */

  30.                         /* 1 < dist <= 16 ,每收到dist个ACK,会使snd_cwnd++,故增长很快 */

  31.                         ca->cnt = cwnd / dist ;

  32.         } else { /* 进入max_probing阶段 */

  33.                 if ( cwnd < ca->last_max_cwnd + BICTCP_B ) /* cwnd < ca->last_max_cwnd + 4 */

  34.                         ca->cnt = (cwnd * smooth_part ) / BICTCP_B ; /* ca->cnt = 5*cwnd ; slow start */

  35.                 else if ( cwnd < ca->last_max_cwnd + max_increment * ( BICTCP_B - 1))

  36.                         /* 增长率从5/(3*cwnd)~47/(3*cwnd),snd_cwnd的增长加快*/

  37.                         ca->cnt = (cwnd * (BICTCP_B - 1)) / (cwnd - ca->last_max_cwnd) ;

  38.                 else

  39.                         ca->cnt = cwnd / max_increment ; /* 增长率为16/cwnd ,更快 */

  40.         }

  41.         /* if in slow start or link utilization is very low */

  42.         if ( ca->loss_cwnd == 0 ) {  /* 没有发生过丢包,所以snd_cwnd增长应该快点*/

  43.                 if ( ca->cnt > 20 ) /* increase cwnd 5% per RTT */

  44.                       ca->cnt = 20 ;

  45.         }

  46.         /* 相当于乘与delayed_ack的百分比,delayed得越严重,则snd_cwnd应该增加越快*/

  47.         /* 这样有无delayed对snd_cwnd的影响不大*/

  48.         ca->cnt = (ca->cnt << ACK_RATIO_SHIFT) / ca->delayed_ack ;

  49.         /* ca->cnt cannot be zero */

  50.         if ( ca->cnt == 0)

  51.                 ca->cnt = 1 ;

  52. }
复制代码
从以上函数可以看出,和reno相比,BIC在拥塞避免阶段snd_cwnd增长极快。

当ca->last_max_cwnd - snd_cwnd >= 4 时,snd_cwnd最慢的增长率为 1/16 。

而当ca->last_max_cwnd - snd_cwnd <4 时,增长率非常低,可以使当前的snd_cwnd维持很长一段时间,

即以最合适的snd_cwnd发送数据。

这两点使BIC在高带宽、长时延的环境下能达到较高的吞吐量。



1. 搜索阶段
  1. (1) cwnd < last_max_cwnd - 64, 则cnt = cwnd / 16

  2. (2) last_max_cwnd - 64 <= cwnd < last_max_cwnd -4 ,则cnt = cwnd / dist

  3. (3) last_max_cwnd - 4 <= cwnd < last_max_cwnd ,则cnt = 5*cwnd
复制代码
总体来说,snd_cwnd增长先快后慢,趋于稳定。

2. max probing阶段

  1. (1) last_max_cwnd <= cwnd < last_max_cwnd + 4,则cnt = 5*cwnd

  2. (2) last_max_cwnd + 4 <= cwnd < last_max_cwnd + 48 ,则cnt = 3*cwnd / (cwnd - last_max_cwnd)

  3. (3) cwnd >= last_max_cwnd + 48 ,则cnt = cwnd / 16
复制代码
总体来说,snd_cwnd的增长先慢后快,越来越快。

论坛徽章:
0
2 [报告]
发表于 2011-12-20 14:56 |只看该作者
很好阿  希望于楼主多多交流哦
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP