Commit 60557969 authored by Eric Dumazet's avatar Eric Dumazet Committed by Jakub Kicinski
Browse files

udp: annotate data-race in __udp_enqueue_schedule_skb()



sk->sk_rcvbuf is read locklessly twice, while other threads
could change its value.

Use a READ_ONCE() to annotate the race.

Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Link: https://lore.kernel.org/r/20240328144032.1864988-2-edumazet@google.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 46dc11be
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -1492,13 +1492,14 @@ int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb)
	struct sk_buff_head *list = &sk->sk_receive_queue;
	int rmem, err = -ENOMEM;
	spinlock_t *busy = NULL;
	int size;
	int size, rcvbuf;

	/* try to avoid the costly atomic add/sub pair when the receive
	 * queue is full; always allow at least a packet
	/* Immediately drop when the receive queue is full.
	 * Always allow at least one packet.
	 */
	rmem = atomic_read(&sk->sk_rmem_alloc);
	if (rmem > sk->sk_rcvbuf)
	rcvbuf = READ_ONCE(sk->sk_rcvbuf);
	if (rmem > rcvbuf)
		goto drop;

	/* Under mem pressure, it might be helpful to help udp_recvmsg()
@@ -1507,7 +1508,7 @@ int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb)
	 * - Less cache line misses at copyout() time
	 * - Less work at consume_skb() (less alien page frag freeing)
	 */
	if (rmem > (sk->sk_rcvbuf >> 1)) {
	if (rmem > (rcvbuf >> 1)) {
		skb_condense(skb);

		busy = busylock_acquire(sk);