tcp: use ACCESS_ONCE() in tcp_update_pacing_rate()
authorEric Dumazet <edumazet@google.com>
Thu, 10 Oct 2013 00:14:52 +0000 (17:14 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 10 Oct 2013 04:08:07 +0000 (00:08 -0400)
sk_pacing_rate is read by sch_fq packet scheduler at any time,
with no synchronization, so make sure we update it in a
sensible way. ACCESS_ONCE() is how we instruct compiler
to not do stupid things, like using the memory location
as a temporary variable.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/tcp_input.c

index 47b8ab7dce9cc5620eaef1468bedaeee05b2f19e..eb651a069a6c7b585ce3e5e1740e1b2be207c6c5 100644 (file)
@@ -755,7 +755,12 @@ static void tcp_update_pacing_rate(struct sock *sk)
        if (tp->srtt > 8 + 2)
                do_div(rate, tp->srtt);
 
-       sk->sk_pacing_rate = min_t(u64, rate, sk->sk_max_pacing_rate);
+       /* ACCESS_ONCE() is needed because sch_fq fetches sk_pacing_rate
+        * without any lock. We want to make sure compiler wont store
+        * intermediate values in this location.
+        */
+       ACCESS_ONCE(sk->sk_pacing_rate) = min_t(u64, rate,
+                                               sk->sk_max_pacing_rate);
 }
 
 /* Calculate rto without backoff.  This is the second half of Van Jacobson's