]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
net: use skb_queue_empty_lockless() in busy poll contexts
authorEric Dumazet <edumazet@google.com>
Thu, 24 Oct 2019 05:44:51 +0000 (22:44 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 10 Nov 2019 10:25:35 +0000 (11:25 +0100)
[ Upstream commit 3f926af3f4d688e2e11e7f8ed04e277a14d4d4a4 ]

Busy polling usually runs without locks.
Let's use skb_queue_empty_lockless() instead of skb_queue_empty()

Also uses READ_ONCE() in __skb_try_recv_datagram() to address
a similar potential problem.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/core/datagram.c
net/core/sock.c
net/ipv4/tcp.c
net/sctp/socket.c

index 4336c720ce4bfbc75038d5d0c3c3eadbd1bbdbbe..85fcca395fad97a409def96472c673a5ec1f717e 100644 (file)
@@ -281,7 +281,7 @@ struct sk_buff *__skb_try_recv_datagram(struct sock *sk, unsigned int flags,
                        break;
 
                sk_busy_loop(sk, flags & MSG_DONTWAIT);
-       } while (sk->sk_receive_queue.prev != *last);
+       } while (READ_ONCE(sk->sk_receive_queue.prev) != *last);
 
        error = -EAGAIN;
 
index a6f33a717f41369feba4d14b1388c034ffca5b84..7ccbcd853cbce7bdc9bfab6c1b9682fbc0c7557d 100644 (file)
@@ -3381,7 +3381,7 @@ bool sk_busy_loop_end(void *p, unsigned long start_time)
 {
        struct sock *sk = p;
 
-       return !skb_queue_empty(&sk->sk_receive_queue) ||
+       return !skb_queue_empty_lockless(&sk->sk_receive_queue) ||
               sk_busy_loop_timeout(sk, start_time);
 }
 EXPORT_SYMBOL(sk_busy_loop_end);
index ee0669d0d867141f338229e17d4ea9fe95c2ed6e..8f07655718f3463853c72b2104eb3c70544eea7b 100644 (file)
@@ -1787,7 +1787,7 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock,
        if (unlikely(flags & MSG_ERRQUEUE))
                return inet_recv_error(sk, msg, len, addr_len);
 
-       if (sk_can_busy_loop(sk) && skb_queue_empty(&sk->sk_receive_queue) &&
+       if (sk_can_busy_loop(sk) && skb_queue_empty_lockless(&sk->sk_receive_queue) &&
            (sk->sk_state == TCP_ESTABLISHED))
                sk_busy_loop(sk, nonblock);
 
index 8bcce38521dacb3fb57ded876ed03bb07e737fb6..d1c917851b0c9a04dbf98e4eea03278b44904ecc 100644 (file)
@@ -7716,7 +7716,7 @@ struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags,
                if (sk_can_busy_loop(sk)) {
                        sk_busy_loop(sk, noblock);
 
-                       if (!skb_queue_empty(&sk->sk_receive_queue))
+                       if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
                                continue;
                }