diff options
author | Eric Dumazet <edumazet@google.com> | 2019-10-24 01:44:51 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-10-28 16:33:41 -0400 |
commit | 3f926af3f4d688e2e11e7f8ed04e277a14d4d4a4 (patch) | |
tree | 3cdc7bbab6fc9caa1282afe98eddd91add1aabd7 /net | |
parent | 3ef7cf57c72f32f61e97f8fa401bc39ea1f1a5d4 (diff) |
net: use skb_queue_empty_lockless() in busy poll contexts
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>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/datagram.c | 2 | ||||
-rw-r--r-- | net/core/sock.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 2 | ||||
-rw-r--r-- | net/sctp/socket.c | 2 |
4 files changed, 4 insertions, 4 deletions
diff --git a/net/core/datagram.c b/net/core/datagram.c index 5b685e110aff..03515e46a49a 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c | |||
@@ -278,7 +278,7 @@ struct sk_buff *__skb_try_recv_datagram(struct sock *sk, unsigned int flags, | |||
278 | break; | 278 | break; |
279 | 279 | ||
280 | sk_busy_loop(sk, flags & MSG_DONTWAIT); | 280 | 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); |
282 | 282 | ||
283 | error = -EAGAIN; | 283 | error = -EAGAIN; |
284 | 284 | ||
diff --git a/net/core/sock.c b/net/core/sock.c index a515392ba84b..b8e758bcb6ad 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -3600,7 +3600,7 @@ bool sk_busy_loop_end(void *p, unsigned long start_time) | |||
3600 | { | 3600 | { |
3601 | struct sock *sk = p; | 3601 | struct sock *sk = p; |
3602 | 3602 | ||
3603 | return !skb_queue_empty(&sk->sk_receive_queue) || | 3603 | return !skb_queue_empty_lockless(&sk->sk_receive_queue) || |
3604 | sk_busy_loop_timeout(sk, start_time); | 3604 | sk_busy_loop_timeout(sk, start_time); |
3605 | } | 3605 | } |
3606 | EXPORT_SYMBOL(sk_busy_loop_end); | 3606 | EXPORT_SYMBOL(sk_busy_loop_end); |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index ffef502f5292..d8876f0e9672 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -1964,7 +1964,7 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock, | |||
1964 | if (unlikely(flags & MSG_ERRQUEUE)) | 1964 | if (unlikely(flags & MSG_ERRQUEUE)) |
1965 | return inet_recv_error(sk, msg, len, addr_len); | 1965 | return inet_recv_error(sk, msg, len, addr_len); |
1966 | 1966 | ||
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) && |
1968 | (sk->sk_state == TCP_ESTABLISHED)) | 1968 | (sk->sk_state == TCP_ESTABLISHED)) |
1969 | sk_busy_loop(sk, nonblock); | 1969 | sk_busy_loop(sk, nonblock); |
1970 | 1970 | ||
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index cfb25391b8b0..ca81e06df165 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -8871,7 +8871,7 @@ struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, | |||
8871 | if (sk_can_busy_loop(sk)) { | 8871 | if (sk_can_busy_loop(sk)) { |
8872 | sk_busy_loop(sk, noblock); | 8872 | sk_busy_loop(sk, noblock); |
8873 | 8873 | ||
8874 | if (!skb_queue_empty(&sk->sk_receive_queue)) | 8874 | if (!skb_queue_empty_lockless(&sk->sk_receive_queue)) |
8875 | continue; | 8875 | continue; |
8876 | } | 8876 | } |
8877 | 8877 | ||