Commit 0bb4d124 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

net: annotate data-races around sk->sk_tx_queue_mapping



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

Add annotations to avoid load-store tearing.

Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5eef0b8d
Loading
Loading
Loading
Loading
+16 −4
Original line number Diff line number Diff line
@@ -2007,21 +2007,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;
}