History

tcp_cubic: limit delayed_ack ratio to prevent divide error

TCP Cubic keeps a metric 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.

stephen hemminger committed 15 years ago

Commit b9f47a31 parent 9c412941 file · +7 −2Browse files

Unified · Split

net/ipv4/tcp_cubic.c+7−2
@@ -93,6 +93,7 @@ struct bictcp { · 92 unmodified lines
9393 u32 ack_cnt; /* number of acks */
9494 u32 tcp_cwnd; /* estimated tcp cwnd */
9595 #define ACK_RATIO_SHIFT 4
96+#define ACK_RATIO_LIMIT (32u << ACK_RATIO_SHIFT)
9697 u16 delayed_ack; /* estimate the ratio of Packets/ACKs << 4 */
9798 u8 sample_cnt; /* number of samples to decide curr_rtt */
9899 u8 found; /* the exit point is found? */
@@ -398,8 +399,12 @@ static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt_us) · 299 unmodified lines
398399 u32 delay;
399400
400401 if (icsk->icsk_ca_state == TCP_CA_Open) {
401− cnt -= ca->delayed_ack >> ACK_RATIO_SHIFT;
402− ca->delayed_ack += cnt;
402+ u32 ratio = ca->delayed_ack;
403+
404+ ratio -= ca->delayed_ack >> ACK_RATIO_SHIFT;
405+ ratio += cnt;
406+
407+ ca->delayed_ack = min(ratio, ACK_RATIO_LIMIT);
403408 }
404409
405410 /* Some calls are for duplicates without timetamps */