TCP拥塞控制算法 — CUBIC的补丁(七)
描述
以下是提交者Stephen Hemminger对这个patch的描述:
limit delayed_ack ratio to prevent divide error
TCP Cubic keeps a metirc that estimates the amount of delayed acknowledgements to use
in adjusting the window. If an abnormally large number of packets are acknowledged at once,
then the update could wrap and reach zero. This kind of ACK could only happen when there
was a large window and huge number of ACK's were lost.
This patch limits the value of delayed ack ratio. The choice of 32 is just a conservative value
since normally it should be range of 1 to 4 packets.
代码
--- a/net/ipv4/tcp_cubic.c +++ b/net/ipv4/tcp_cubic.c @@ -93,6 +93,7 @@ struct bictcp { u32 ack_cnt; /* number of acks */ u32 tcp_cwnd; /* estimated tcp cwnd */ #define ACK_RATIO_SHIFT 4 +#define ACK_RATIO_LIMIT (32u << ACK_RATIO_SHIFT) u16 delayed_ack; /* estimate the ratio of Packets/ACKs << 4 */ u8 sample_cnt; /* number of samples to decide curr_rtt */ u8 found; /* the exit point is found? */ @@ -398,8 +399,12 @@ static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt_us) u32 delay; if (icsk->icsk_ca_state == TCP_CA_Open) { - cnt -= ca->delayed_ack >> ACK_RATIO_SHIFT; - ca->delayed_ack += cnt; + u32 ratio = ca->delayed_ack; + + ratio -= ca->delayed_ack >> ACK_RATIO_SHIFT; + ratio += cnt; + + ca->delayed_ack = min(ratio, ACK_RATIO_LIMIT); } /* Some calls are for duplicates without timetamps */
评价
这个补丁限制了delayed_ack的最大值为(32 << 4)。也就是说Packets/ACKs的最大估计值限制为32。
为什么要增加这个限制呢?这是因为如果发送窗口很大,并且这个窗口的数据包的ACK大量丢失,那
么发送端就会得到一个累积确认了非常多数据包的ACK,这会造成delayed_ack值剧烈的增大。如果
一个ACK累积确认的数据包超过4096个,那么16位的delayed_ack就会溢出,最后的值可能为0。我
们知道delayed_ack在bictcp_update中是作为除数的,这时会产生除数为0的错误。
Author
zhangskd @ csdn blog