Skip to content

Commit

Permalink
net: tcp: dctcp_update_alpha() fixes.
Browse files Browse the repository at this point in the history
dctcp_alpha can be read by from dctcp_get_info() without
synchro, so use WRITE_ONCE() to prevent compiler from using
dctcp_alpha as a temporary variable.

Also, playing with small dctcp_shift_g (like 1), can expose
an overflow with 32bit values shifted 9 times before divide.

Use an u64 field to avoid this problem, and perform the divide
only if acked_bytes_ecn is not zero.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Eric Dumazet authored and David S. Miller committed Jun 11, 2015
1 parent 1edaa7e commit f9c2ff2
Showing 1 changed file with 16 additions and 10 deletions.
26 changes: 16 additions & 10 deletions net/ipv4/tcp_dctcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,20 +204,26 @@ static void dctcp_update_alpha(struct sock *sk, u32 flags)

/* Expired RTT */
if (!before(tp->snd_una, ca->next_seq)) {
/* For avoiding denominator == 1. */
if (ca->acked_bytes_total == 0)
ca->acked_bytes_total = 1;
u64 bytes_ecn = ca->acked_bytes_ecn;
u32 alpha = ca->dctcp_alpha;

/* alpha = (1 - g) * alpha + g * F */
ca->dctcp_alpha = ca->dctcp_alpha -
(ca->dctcp_alpha >> dctcp_shift_g) +
(ca->acked_bytes_ecn << (10U - dctcp_shift_g)) /
ca->acked_bytes_total;

if (ca->dctcp_alpha > DCTCP_MAX_ALPHA)
/* Clamp dctcp_alpha to max. */
ca->dctcp_alpha = DCTCP_MAX_ALPHA;
alpha -= alpha >> dctcp_shift_g;
if (bytes_ecn) {
/* If dctcp_shift_g == 1, a 32bit value would overflow
* after 8 Mbytes.
*/
bytes_ecn <<= (10 - dctcp_shift_g);
do_div(bytes_ecn, max(1U, ca->acked_bytes_total));

alpha = min(alpha + (u32)bytes_ecn, DCTCP_MAX_ALPHA);
}
/* dctcp_alpha can be read from dctcp_get_info() without
* synchro, so we ask compiler to not use dctcp_alpha
* as a temporary variable in prior operations.
*/
WRITE_ONCE(ca->dctcp_alpha, alpha);
dctcp_reset(tp, ca);
}
}
Expand Down

0 comments on commit f9c2ff2

Please sign in to comment.