Skip to content

Commit

Permalink
net: annotate data-races around sk->sk_max_pacing_rate
Browse files Browse the repository at this point in the history
sk_getsockopt() runs locklessly. This means sk->sk_max_pacing_rate
can be read while other threads are changing its value.

Fixes: 62748f3 ("net: introduce SO_MAX_PACING_RATE")
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 Jul 29, 2023
1 parent c76a032 commit ea7f45e
Showing 1 changed file with 6 additions and 3 deletions.
9 changes: 6 additions & 3 deletions net/core/sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -1439,7 +1439,8 @@ int sk_setsockopt(struct sock *sk, int level, int optname,
cmpxchg(&sk->sk_pacing_status,
SK_PACING_NONE,
SK_PACING_NEEDED);
sk->sk_max_pacing_rate = ulval;
/* Pairs with READ_ONCE() from sk_getsockopt() */
WRITE_ONCE(sk->sk_max_pacing_rate, ulval);
sk->sk_pacing_rate = min(sk->sk_pacing_rate, ulval);
break;
}
Expand Down Expand Up @@ -1903,12 +1904,14 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
#endif

case SO_MAX_PACING_RATE:
/* The READ_ONCE() pair with the WRITE_ONCE() in sk_setsockopt() */
if (sizeof(v.ulval) != sizeof(v.val) && len >= sizeof(v.ulval)) {
lv = sizeof(v.ulval);
v.ulval = sk->sk_max_pacing_rate;
v.ulval = READ_ONCE(sk->sk_max_pacing_rate);
} else {
/* 32bit version */
v.val = min_t(unsigned long, sk->sk_max_pacing_rate, ~0U);
v.val = min_t(unsigned long, ~0U,
READ_ONCE(sk->sk_max_pacing_rate));
}
break;

Expand Down

0 comments on commit ea7f45e

Please sign in to comment.