Skip to content

Commit

Permalink
net: annotate data-races around sk->sk_tx_queue_mapping
Browse files Browse the repository at this point in the history
[ Upstream commit 0bb4d12 ]

This field can be read or written without socket lock being held.

Add annotations to avoid load-store tearing.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Eric Dumazet authored and gregkh committed Nov 28, 2023
1 parent 46537b4 commit e7960d2
Showing 1 changed file with 16 additions and 4 deletions.
20 changes: 16 additions & 4 deletions include/net/sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -2032,21 +2032,33 @@ static inline void sk_tx_queue_set(struct sock *sk, int tx_queue)
/* sk_tx_queue_mapping accept only upto a 16-bit value */
if (WARN_ON_ONCE((unsigned short)tx_queue >= USHRT_MAX))
return;
sk->sk_tx_queue_mapping = tx_queue;
/* Paired with READ_ONCE() in sk_tx_queue_get() and
* other WRITE_ONCE() because socket lock might be not held.
*/
WRITE_ONCE(sk->sk_tx_queue_mapping, tx_queue);
}

#define NO_QUEUE_MAPPING USHRT_MAX

static inline void sk_tx_queue_clear(struct sock *sk)
{
sk->sk_tx_queue_mapping = NO_QUEUE_MAPPING;
/* Paired with READ_ONCE() in sk_tx_queue_get() and
* other WRITE_ONCE() because socket lock might be not held.
*/
WRITE_ONCE(sk->sk_tx_queue_mapping, NO_QUEUE_MAPPING);
}

static inline int sk_tx_queue_get(const struct sock *sk)
{
if (sk && sk->sk_tx_queue_mapping != NO_QUEUE_MAPPING)
return sk->sk_tx_queue_mapping;
if (sk) {
/* Paired with WRITE_ONCE() in sk_tx_queue_clear()
* and sk_tx_queue_set().
*/
int val = READ_ONCE(sk->sk_tx_queue_mapping);

if (val != NO_QUEUE_MAPPING)
return val;
}
return -1;
}

Expand Down

0 comments on commit e7960d2

Please sign in to comment.