Skip to content

Commit 2024305

Browse files
committed
Merge branch 'net-avoid-KCSAN-splats'
Eric Dumazet says: ==================== net: avoid KCSAN splats Often times we use skb_queue_empty() without holding a lock, meaning that other cpus (or interrupt) can change the queue under us. This is fine, but we need to properly annotate the lockless intent to make sure the compiler wont over optimize things. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents fc11078 + 7c422d0 commit 2024305

File tree

18 files changed

+56
-41
lines changed

18 files changed

+56
-41
lines changed

drivers/crypto/chelsio/chtls/chtls_io.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1702,7 +1702,7 @@ int chtls_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
17021702
return peekmsg(sk, msg, len, nonblock, flags);
17031703

17041704
if (sk_can_busy_loop(sk) &&
1705-
skb_queue_empty(&sk->sk_receive_queue) &&
1705+
skb_queue_empty_lockless(&sk->sk_receive_queue) &&
17061706
sk->sk_state == TCP_ESTABLISHED)
17071707
sk_busy_loop(sk, nonblock);
17081708

drivers/isdn/capi/capi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,7 @@ capi_poll(struct file *file, poll_table *wait)
744744

745745
poll_wait(file, &(cdev->recvwait), wait);
746746
mask = EPOLLOUT | EPOLLWRNORM;
747-
if (!skb_queue_empty(&cdev->recvqueue))
747+
if (!skb_queue_empty_lockless(&cdev->recvqueue))
748748
mask |= EPOLLIN | EPOLLRDNORM;
749749
return mask;
750750
}

drivers/nvme/host/tcp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2219,7 +2219,7 @@ static int nvme_tcp_poll(struct blk_mq_hw_ctx *hctx)
22192219
struct nvme_tcp_queue *queue = hctx->driver_data;
22202220
struct sock *sk = queue->sock->sk;
22212221

2222-
if (sk_can_busy_loop(sk) && skb_queue_empty(&sk->sk_receive_queue))
2222+
if (sk_can_busy_loop(sk) && skb_queue_empty_lockless(&sk->sk_receive_queue))
22232223
sk_busy_loop(sk, true);
22242224
nvme_tcp_try_recv(queue);
22252225
return queue->nr_cqe;

include/linux/skbuff.h

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,6 +1495,19 @@ static inline int skb_queue_empty(const struct sk_buff_head *list)
14951495
return list->next == (const struct sk_buff *) list;
14961496
}
14971497

1498+
/**
1499+
* skb_queue_empty_lockless - check if a queue is empty
1500+
* @list: queue head
1501+
*
1502+
* Returns true if the queue is empty, false otherwise.
1503+
* This variant can be used in lockless contexts.
1504+
*/
1505+
static inline bool skb_queue_empty_lockless(const struct sk_buff_head *list)
1506+
{
1507+
return READ_ONCE(list->next) == (const struct sk_buff *) list;
1508+
}
1509+
1510+
14981511
/**
14991512
* skb_queue_is_last - check if skb is the last entry in the queue
15001513
* @list: queue head
@@ -1848,9 +1861,11 @@ static inline void __skb_insert(struct sk_buff *newsk,
18481861
struct sk_buff *prev, struct sk_buff *next,
18491862
struct sk_buff_head *list)
18501863
{
1851-
newsk->next = next;
1852-
newsk->prev = prev;
1853-
next->prev = prev->next = newsk;
1864+
/* see skb_queue_empty_lockless() for the opposite READ_ONCE() */
1865+
WRITE_ONCE(newsk->next, next);
1866+
WRITE_ONCE(newsk->prev, prev);
1867+
WRITE_ONCE(next->prev, newsk);
1868+
WRITE_ONCE(prev->next, newsk);
18541869
list->qlen++;
18551870
}
18561871

@@ -1861,11 +1876,11 @@ static inline void __skb_queue_splice(const struct sk_buff_head *list,
18611876
struct sk_buff *first = list->next;
18621877
struct sk_buff *last = list->prev;
18631878

1864-
first->prev = prev;
1865-
prev->next = first;
1879+
WRITE_ONCE(first->prev, prev);
1880+
WRITE_ONCE(prev->next, first);
18661881

1867-
last->next = next;
1868-
next->prev = last;
1882+
WRITE_ONCE(last->next, next);
1883+
WRITE_ONCE(next->prev, last);
18691884
}
18701885

18711886
/**
@@ -2006,8 +2021,8 @@ static inline void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list)
20062021
next = skb->next;
20072022
prev = skb->prev;
20082023
skb->next = skb->prev = NULL;
2009-
next->prev = prev;
2010-
prev->next = next;
2024+
WRITE_ONCE(next->prev, prev);
2025+
WRITE_ONCE(prev->next, next);
20112026
}
20122027

20132028
/**

net/atm/common.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,7 @@ __poll_t vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
668668
mask |= EPOLLHUP;
669669

670670
/* readable? */
671-
if (!skb_queue_empty(&sk->sk_receive_queue))
671+
if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
672672
mask |= EPOLLIN | EPOLLRDNORM;
673673

674674
/* writable? */

net/bluetooth/af_bluetooth.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ __poll_t bt_sock_poll(struct file *file, struct socket *sock,
460460
if (sk->sk_state == BT_LISTEN)
461461
return bt_accept_poll(sk);
462462

463-
if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
463+
if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
464464
mask |= EPOLLERR |
465465
(sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);
466466

@@ -470,7 +470,7 @@ __poll_t bt_sock_poll(struct file *file, struct socket *sock,
470470
if (sk->sk_shutdown == SHUTDOWN_MASK)
471471
mask |= EPOLLHUP;
472472

473-
if (!skb_queue_empty(&sk->sk_receive_queue))
473+
if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
474474
mask |= EPOLLIN | EPOLLRDNORM;
475475

476476
if (sk->sk_state == BT_CLOSED)

net/caif/caif_socket.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,7 @@ static __poll_t caif_poll(struct file *file,
953953
mask |= EPOLLRDHUP;
954954

955955
/* readable? */
956-
if (!skb_queue_empty(&sk->sk_receive_queue) ||
956+
if (!skb_queue_empty_lockless(&sk->sk_receive_queue) ||
957957
(sk->sk_shutdown & RCV_SHUTDOWN))
958958
mask |= EPOLLIN | EPOLLRDNORM;
959959

net/core/datagram.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ int __skb_wait_for_more_packets(struct sock *sk, int *err, long *timeo_p,
9797
if (error)
9898
goto out_err;
9999

100-
if (sk->sk_receive_queue.prev != skb)
100+
if (READ_ONCE(sk->sk_receive_queue.prev) != skb)
101101
goto out;
102102

103103
/* Socket shut down? */
@@ -278,7 +278,7 @@ struct sk_buff *__skb_try_recv_datagram(struct sock *sk, unsigned int flags,
278278
break;
279279

280280
sk_busy_loop(sk, flags & MSG_DONTWAIT);
281-
} while (sk->sk_receive_queue.prev != *last);
281+
} while (READ_ONCE(sk->sk_receive_queue.prev) != *last);
282282

283283
error = -EAGAIN;
284284

@@ -767,7 +767,7 @@ __poll_t datagram_poll(struct file *file, struct socket *sock,
767767
mask = 0;
768768

769769
/* exceptional events? */
770-
if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
770+
if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
771771
mask |= EPOLLERR |
772772
(sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);
773773

@@ -777,7 +777,7 @@ __poll_t datagram_poll(struct file *file, struct socket *sock,
777777
mask |= EPOLLHUP;
778778

779779
/* readable? */
780-
if (!skb_queue_empty(&sk->sk_receive_queue))
780+
if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
781781
mask |= EPOLLIN | EPOLLRDNORM;
782782

783783
/* Connection-based need to check for termination and startup */

net/core/sock.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3600,7 +3600,7 @@ bool sk_busy_loop_end(void *p, unsigned long start_time)
36003600
{
36013601
struct sock *sk = p;
36023602

3603-
return !skb_queue_empty(&sk->sk_receive_queue) ||
3603+
return !skb_queue_empty_lockless(&sk->sk_receive_queue) ||
36043604
sk_busy_loop_timeout(sk, start_time);
36053605
}
36063606
EXPORT_SYMBOL(sk_busy_loop_end);

net/decnet/af_decnet.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1205,7 +1205,7 @@ static __poll_t dn_poll(struct file *file, struct socket *sock, poll_table *wai
12051205
struct dn_scp *scp = DN_SK(sk);
12061206
__poll_t mask = datagram_poll(file, sock, wait);
12071207

1208-
if (!skb_queue_empty(&scp->other_receive_queue))
1208+
if (!skb_queue_empty_lockless(&scp->other_receive_queue))
12091209
mask |= EPOLLRDBAND;
12101210

12111211
return mask;

net/ipv4/tcp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ __poll_t tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
584584
}
585585
/* This barrier is coupled with smp_wmb() in tcp_reset() */
586586
smp_rmb();
587-
if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
587+
if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
588588
mask |= EPOLLERR;
589589

590590
return mask;
@@ -1964,7 +1964,7 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock,
19641964
if (unlikely(flags & MSG_ERRQUEUE))
19651965
return inet_recv_error(sk, msg, len, addr_len);
19661966

1967-
if (sk_can_busy_loop(sk) && skb_queue_empty(&sk->sk_receive_queue) &&
1967+
if (sk_can_busy_loop(sk) && skb_queue_empty_lockless(&sk->sk_receive_queue) &&
19681968
(sk->sk_state == TCP_ESTABLISHED))
19691969
sk_busy_loop(sk, nonblock);
19701970

net/ipv4/udp.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1577,7 +1577,7 @@ static int first_packet_length(struct sock *sk)
15771577

15781578
spin_lock_bh(&rcvq->lock);
15791579
skb = __first_packet_length(sk, rcvq, &total);
1580-
if (!skb && !skb_queue_empty(sk_queue)) {
1580+
if (!skb && !skb_queue_empty_lockless(sk_queue)) {
15811581
spin_lock(&sk_queue->lock);
15821582
skb_queue_splice_tail_init(sk_queue, rcvq);
15831583
spin_unlock(&sk_queue->lock);
@@ -1650,7 +1650,7 @@ struct sk_buff *__skb_recv_udp(struct sock *sk, unsigned int flags,
16501650
return skb;
16511651
}
16521652

1653-
if (skb_queue_empty(sk_queue)) {
1653+
if (skb_queue_empty_lockless(sk_queue)) {
16541654
spin_unlock_bh(&queue->lock);
16551655
goto busy_check;
16561656
}
@@ -1676,7 +1676,7 @@ struct sk_buff *__skb_recv_udp(struct sock *sk, unsigned int flags,
16761676
break;
16771677

16781678
sk_busy_loop(sk, flags & MSG_DONTWAIT);
1679-
} while (!skb_queue_empty(sk_queue));
1679+
} while (!skb_queue_empty_lockless(sk_queue));
16801680

16811681
/* sk_queue is empty, reader_queue may contain peeked packets */
16821682
} while (timeo &&
@@ -2712,7 +2712,7 @@ __poll_t udp_poll(struct file *file, struct socket *sock, poll_table *wait)
27122712
__poll_t mask = datagram_poll(file, sock, wait);
27132713
struct sock *sk = sock->sk;
27142714

2715-
if (!skb_queue_empty(&udp_sk(sk)->reader_queue))
2715+
if (!skb_queue_empty_lockless(&udp_sk(sk)->reader_queue))
27162716
mask |= EPOLLIN | EPOLLRDNORM;
27172717

27182718
/* Check for false positives due to checksum errors */

net/nfc/llcp_sock.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -554,11 +554,11 @@ static __poll_t llcp_sock_poll(struct file *file, struct socket *sock,
554554
if (sk->sk_state == LLCP_LISTEN)
555555
return llcp_accept_poll(sk);
556556

557-
if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
557+
if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
558558
mask |= EPOLLERR |
559559
(sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);
560560

561-
if (!skb_queue_empty(&sk->sk_receive_queue))
561+
if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
562562
mask |= EPOLLIN | EPOLLRDNORM;
563563

564564
if (sk->sk_state == LLCP_CLOSED)

net/phonet/socket.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,9 +338,9 @@ static __poll_t pn_socket_poll(struct file *file, struct socket *sock,
338338

339339
if (sk->sk_state == TCP_CLOSE)
340340
return EPOLLERR;
341-
if (!skb_queue_empty(&sk->sk_receive_queue))
341+
if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
342342
mask |= EPOLLIN | EPOLLRDNORM;
343-
if (!skb_queue_empty(&pn->ctrlreq_queue))
343+
if (!skb_queue_empty_lockless(&pn->ctrlreq_queue))
344344
mask |= EPOLLPRI;
345345
if (!mask && sk->sk_state == TCP_CLOSE_WAIT)
346346
return EPOLLHUP;

net/sctp/socket.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8476,7 +8476,7 @@ __poll_t sctp_poll(struct file *file, struct socket *sock, poll_table *wait)
84768476
mask = 0;
84778477

84788478
/* Is there any exceptional events? */
8479-
if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
8479+
if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
84808480
mask |= EPOLLERR |
84818481
(sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);
84828482
if (sk->sk_shutdown & RCV_SHUTDOWN)
@@ -8485,7 +8485,7 @@ __poll_t sctp_poll(struct file *file, struct socket *sock, poll_table *wait)
84858485
mask |= EPOLLHUP;
84868486

84878487
/* Is it readable? Reconsider this code with TCP-style support. */
8488-
if (!skb_queue_empty(&sk->sk_receive_queue))
8488+
if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
84898489
mask |= EPOLLIN | EPOLLRDNORM;
84908490

84918491
/* The association is either gone or not ready. */
@@ -8871,7 +8871,7 @@ struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags,
88718871
if (sk_can_busy_loop(sk)) {
88728872
sk_busy_loop(sk, noblock);
88738873

8874-
if (!skb_queue_empty(&sk->sk_receive_queue))
8874+
if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
88758875
continue;
88768876
}
88778877

net/tipc/socket.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -740,15 +740,15 @@ static __poll_t tipc_poll(struct file *file, struct socket *sock,
740740
/* fall through */
741741
case TIPC_LISTEN:
742742
case TIPC_CONNECTING:
743-
if (!skb_queue_empty(&sk->sk_receive_queue))
743+
if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
744744
revents |= EPOLLIN | EPOLLRDNORM;
745745
break;
746746
case TIPC_OPEN:
747747
if (tsk->group_is_open && !tsk->cong_link_cnt)
748748
revents |= EPOLLOUT;
749749
if (!tipc_sk_type_connectionless(sk))
750750
break;
751-
if (skb_queue_empty(&sk->sk_receive_queue))
751+
if (skb_queue_empty_lockless(&sk->sk_receive_queue))
752752
break;
753753
revents |= EPOLLIN | EPOLLRDNORM;
754754
break;

net/unix/af_unix.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2599,7 +2599,7 @@ static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wa
25992599
mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;
26002600

26012601
/* readable? */
2602-
if (!skb_queue_empty(&sk->sk_receive_queue))
2602+
if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
26032603
mask |= EPOLLIN | EPOLLRDNORM;
26042604

26052605
/* Connection-based need to check for termination and startup */
@@ -2628,7 +2628,7 @@ static __poll_t unix_dgram_poll(struct file *file, struct socket *sock,
26282628
mask = 0;
26292629

26302630
/* exceptional events? */
2631-
if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
2631+
if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
26322632
mask |= EPOLLERR |
26332633
(sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);
26342634

@@ -2638,7 +2638,7 @@ static __poll_t unix_dgram_poll(struct file *file, struct socket *sock,
26382638
mask |= EPOLLHUP;
26392639

26402640
/* readable? */
2641-
if (!skb_queue_empty(&sk->sk_receive_queue))
2641+
if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
26422642
mask |= EPOLLIN | EPOLLRDNORM;
26432643

26442644
/* Connection-based need to check for termination and startup */

net/vmw_vsock/af_vsock.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -870,7 +870,7 @@ static __poll_t vsock_poll(struct file *file, struct socket *sock,
870870
* the queue and write as long as the socket isn't shutdown for
871871
* sending.
872872
*/
873-
if (!skb_queue_empty(&sk->sk_receive_queue) ||
873+
if (!skb_queue_empty_lockless(&sk->sk_receive_queue) ||
874874
(sk->sk_shutdown & RCV_SHUTDOWN)) {
875875
mask |= EPOLLIN | EPOLLRDNORM;
876876
}

0 commit comments

Comments
 (0)