* [PATCH net-next] net: tcp: dctcp_update_alpha() fixes.
@ 2015-06-11 5:11 Eric Dumazet
2015-06-11 6:28 ` David Miller
2015-06-11 21:07 ` Daniel Borkmann
0 siblings, 2 replies; 3+ messages in thread
From: Eric Dumazet @ 2015-06-11 5:11 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Daniel Borkmann, Florian Westphal
From: Eric Dumazet <edumazet@google.com>
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>
---
net/ipv4/tcp_dctcp.c | 26 ++++++++++++++++----------
1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/net/ipv4/tcp_dctcp.c b/net/ipv4/tcp_dctcp.c
index 4c41c1287197eb4748198ae9532d1f6233aa7f6a..7092a61c4dc8465fcf17ff71b289cf25bbb8b559 100644
--- a/net/ipv4/tcp_dctcp.c
+++ b/net/ipv4/tcp_dctcp.c
@@ -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);
}
}
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH net-next] net: tcp: dctcp_update_alpha() fixes.
2015-06-11 5:11 [PATCH net-next] net: tcp: dctcp_update_alpha() fixes Eric Dumazet
@ 2015-06-11 6:28 ` David Miller
2015-06-11 21:07 ` Daniel Borkmann
1 sibling, 0 replies; 3+ messages in thread
From: David Miller @ 2015-06-11 6:28 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev, daniel, fw
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 10 Jun 2015 22:11:17 -0700
> From: Eric Dumazet <edumazet@google.com>
>
> 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>
This looks fine, applied, thanks Eric.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH net-next] net: tcp: dctcp_update_alpha() fixes.
2015-06-11 5:11 [PATCH net-next] net: tcp: dctcp_update_alpha() fixes Eric Dumazet
2015-06-11 6:28 ` David Miller
@ 2015-06-11 21:07 ` Daniel Borkmann
1 sibling, 0 replies; 3+ messages in thread
From: Daniel Borkmann @ 2015-06-11 21:07 UTC (permalink / raw)
To: Eric Dumazet, David Miller; +Cc: netdev, Florian Westphal
On 06/11/2015 07:11 AM, Eric Dumazet wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> 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>
Change looks correct to me, thanks Eric!
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2015-06-11 21:07 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-06-11 5:11 [PATCH net-next] net: tcp: dctcp_update_alpha() fixes Eric Dumazet
2015-06-11 6:28 ` David Miller
2015-06-11 21:07 ` Daniel Borkmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).