net: Generalise wq_has_sleeper helper
authorHerbert Xu <herbert@gondor.apana.org.au>
Thu, 26 Nov 2015 05:55:39 +0000 (13:55 +0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 30 Nov 2015 19:47:33 +0000 (14:47 -0500)
The memory barrier in the helper wq_has_sleeper is needed by just
about every user of waitqueue_active.  This patch generalises it
by making it take a wait_queue_head_t directly.  The existing
helper is renamed to skwq_has_sleeper.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
13 files changed:
crypto/algif_aead.c
crypto/algif_skcipher.c
include/linux/wait.h
include/net/sock.h
net/atm/common.c
net/core/sock.c
net/core/stream.c
net/dccp/output.c
net/iucv/af_iucv.c
net/rxrpc/af_rxrpc.c
net/sctp/socket.c
net/tipc/socket.c
net/unix/af_unix.c

index 0aa6fdfb448a8c4081e06aa9dcb041433dc280a5..fb99f30849d25b81f4a8b5128d4542a69545add0 100644 (file)
@@ -106,7 +106,7 @@ static void aead_wmem_wakeup(struct sock *sk)
 
        rcu_read_lock();
        wq = rcu_dereference(sk->sk_wq);
-       if (wq_has_sleeper(wq))
+       if (skwq_has_sleeper(wq))
                wake_up_interruptible_sync_poll(&wq->wait, POLLIN |
                                                           POLLRDNORM |
                                                           POLLRDBAND);
@@ -157,7 +157,7 @@ static void aead_data_wakeup(struct sock *sk)
 
        rcu_read_lock();
        wq = rcu_dereference(sk->sk_wq);
-       if (wq_has_sleeper(wq))
+       if (skwq_has_sleeper(wq))
                wake_up_interruptible_sync_poll(&wq->wait, POLLOUT |
                                                           POLLRDNORM |
                                                           POLLRDBAND);
index af31a0ee4057370593536cb9f8cc0a4343ab91b8..0e6702e41472bda0680068217b5c7414fa8d3699 100644 (file)
@@ -238,7 +238,7 @@ static void skcipher_wmem_wakeup(struct sock *sk)
 
        rcu_read_lock();
        wq = rcu_dereference(sk->sk_wq);
-       if (wq_has_sleeper(wq))
+       if (skwq_has_sleeper(wq))
                wake_up_interruptible_sync_poll(&wq->wait, POLLIN |
                                                           POLLRDNORM |
                                                           POLLRDBAND);
@@ -288,7 +288,7 @@ static void skcipher_data_wakeup(struct sock *sk)
 
        rcu_read_lock();
        wq = rcu_dereference(sk->sk_wq);
-       if (wq_has_sleeper(wq))
+       if (skwq_has_sleeper(wq))
                wake_up_interruptible_sync_poll(&wq->wait, POLLOUT |
                                                           POLLRDNORM |
                                                           POLLRDBAND);
index 1e1bf9f963a947fc686125d0a2809ad63b8a13ed..6aa09a875fbdcafdeadebde4a70556efeed0f266 100644 (file)
@@ -107,6 +107,27 @@ static inline int waitqueue_active(wait_queue_head_t *q)
        return !list_empty(&q->task_list);
 }
 
+/**
+ * wq_has_sleeper - check if there are any waiting processes
+ * @wq: wait queue head
+ *
+ * Returns true if wq has waiting processes
+ *
+ * Please refer to the comment for waitqueue_active.
+ */
+static inline bool wq_has_sleeper(wait_queue_head_t *wq)
+{
+       /*
+        * We need to be sure we are in sync with the
+        * add_wait_queue modifications to the wait queue.
+        *
+        * This memory barrier should be paired with one on the
+        * waiting side.
+        */
+       smp_mb();
+       return waitqueue_active(wq);
+}
+
 extern void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
 extern void add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t *wait);
 extern void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
index 7f89e4ba18d11ee6a9261edf85cac743d9f8d5ea..62d35afcb3ac33b40357f20dc96b7cf1dac7fdfe 100644 (file)
@@ -58,6 +58,7 @@
 #include <linux/memcontrol.h>
 #include <linux/static_key.h>
 #include <linux/sched.h>
+#include <linux/wait.h>
 
 #include <linux/filter.h>
 #include <linux/rculist_nulls.h>
@@ -1879,12 +1880,12 @@ static inline bool sk_has_allocations(const struct sock *sk)
 }
 
 /**
- * wq_has_sleeper - check if there are any waiting processes
+ * skwq_has_sleeper - check if there are any waiting processes
  * @wq: struct socket_wq
  *
  * Returns true if socket_wq has waiting processes
  *
- * The purpose of the wq_has_sleeper and sock_poll_wait is to wrap the memory
+ * The purpose of the skwq_has_sleeper and sock_poll_wait is to wrap the memory
  * barrier call. They were added due to the race found within the tcp code.
  *
  * Consider following tcp code paths:
@@ -1910,15 +1911,9 @@ static inline bool sk_has_allocations(const struct sock *sk)
  * data on the socket.
  *
  */
-static inline bool wq_has_sleeper(struct socket_wq *wq)
+static inline bool skwq_has_sleeper(struct socket_wq *wq)
 {
-       /* We need to be sure we are in sync with the
-        * add_wait_queue modifications to the wait queue.
-        *
-        * This memory barrier is paired in the sock_poll_wait.
-        */
-       smp_mb();
-       return wq && waitqueue_active(&wq->wait);
+       return wq && wq_has_sleeper(&wq->wait);
 }
 
 /**
index 49a872db7e42581853cc2e8c1a6585285a3172d4..6dc12305799e45180bc8091ee2a99f11e3400fa7 100644 (file)
@@ -96,7 +96,7 @@ static void vcc_def_wakeup(struct sock *sk)
 
        rcu_read_lock();
        wq = rcu_dereference(sk->sk_wq);
-       if (wq_has_sleeper(wq))
+       if (skwq_has_sleeper(wq))
                wake_up(&wq->wait);
        rcu_read_unlock();
 }
@@ -117,7 +117,7 @@ static void vcc_write_space(struct sock *sk)
 
        if (vcc_writable(sk)) {
                wq = rcu_dereference(sk->sk_wq);
-               if (wq_has_sleeper(wq))
+               if (skwq_has_sleeper(wq))
                        wake_up_interruptible(&wq->wait);
 
                sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
index 1e4dd54bfb5a525ef6070905f07472f60e9f137f..2769bd3a4d7c75e46d82380703b776a53d468d65 100644 (file)
@@ -2283,7 +2283,7 @@ static void sock_def_wakeup(struct sock *sk)
 
        rcu_read_lock();
        wq = rcu_dereference(sk->sk_wq);
-       if (wq_has_sleeper(wq))
+       if (skwq_has_sleeper(wq))
                wake_up_interruptible_all(&wq->wait);
        rcu_read_unlock();
 }
@@ -2294,7 +2294,7 @@ static void sock_def_error_report(struct sock *sk)
 
        rcu_read_lock();
        wq = rcu_dereference(sk->sk_wq);
-       if (wq_has_sleeper(wq))
+       if (skwq_has_sleeper(wq))
                wake_up_interruptible_poll(&wq->wait, POLLERR);
        sk_wake_async(sk, SOCK_WAKE_IO, POLL_ERR);
        rcu_read_unlock();
@@ -2306,7 +2306,7 @@ static void sock_def_readable(struct sock *sk)
 
        rcu_read_lock();
        wq = rcu_dereference(sk->sk_wq);
-       if (wq_has_sleeper(wq))
+       if (skwq_has_sleeper(wq))
                wake_up_interruptible_sync_poll(&wq->wait, POLLIN | POLLPRI |
                                                POLLRDNORM | POLLRDBAND);
        sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
@@ -2324,7 +2324,7 @@ static void sock_def_write_space(struct sock *sk)
         */
        if ((atomic_read(&sk->sk_wmem_alloc) << 1) <= sk->sk_sndbuf) {
                wq = rcu_dereference(sk->sk_wq);
-               if (wq_has_sleeper(wq))
+               if (skwq_has_sleeper(wq))
                        wake_up_interruptible_sync_poll(&wq->wait, POLLOUT |
                                                POLLWRNORM | POLLWRBAND);
 
index d70f77a0c8898582e0adabd24c6165675d12dce7..8ff9d63b4265896abe972cab68ad32ccf19beecb 100644 (file)
@@ -35,7 +35,7 @@ void sk_stream_write_space(struct sock *sk)
 
                rcu_read_lock();
                wq = rcu_dereference(sk->sk_wq);
-               if (wq_has_sleeper(wq))
+               if (skwq_has_sleeper(wq))
                        wake_up_interruptible_poll(&wq->wait, POLLOUT |
                                                POLLWRNORM | POLLWRBAND);
                if (wq && wq->fasync_list && !(sk->sk_shutdown & SEND_SHUTDOWN))
index 4ce912e691d03e925e3fef59d53b0724bd13ce83..b66c84db0766f5a1c6cda0db144a8511ed0d325c 100644 (file)
@@ -201,7 +201,7 @@ void dccp_write_space(struct sock *sk)
 
        rcu_read_lock();
        wq = rcu_dereference(sk->sk_wq);
-       if (wq_has_sleeper(wq))
+       if (skwq_has_sleeper(wq))
                wake_up_interruptible(&wq->wait);
        /* Should agree with poll, otherwise some programs break */
        if (sock_writeable(sk))
index fcb2752419c6635b06706d4cec542cb30ae3c85c..4f0aa91470c6a1db3d45d1af9d3a6b7ae8ad1fac 100644 (file)
@@ -303,7 +303,7 @@ static void iucv_sock_wake_msglim(struct sock *sk)
 
        rcu_read_lock();
        wq = rcu_dereference(sk->sk_wq);
-       if (wq_has_sleeper(wq))
+       if (skwq_has_sleeper(wq))
                wake_up_interruptible_all(&wq->wait);
        sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
        rcu_read_unlock();
index 1f8a144a5dc2c7b15a2f7f9724758b38ab4146d9..7e2d1057d8bc1cd89ed9041b4c658b58626f26aa 100644 (file)
@@ -67,7 +67,7 @@ static void rxrpc_write_space(struct sock *sk)
        if (rxrpc_writable(sk)) {
                struct socket_wq *wq = rcu_dereference(sk->sk_wq);
 
-               if (wq_has_sleeper(wq))
+               if (skwq_has_sleeper(wq))
                        wake_up_interruptible(&wq->wait);
                sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
        }
index 897c01c029cab3d5805cc56b0964c70e06f4143a..ec10b66354b8884c0fa2821250ae2a8a4ae2a80e 100644 (file)
@@ -6978,7 +6978,7 @@ void sctp_data_ready(struct sock *sk)
 
        rcu_read_lock();
        wq = rcu_dereference(sk->sk_wq);
-       if (wq_has_sleeper(wq))
+       if (skwq_has_sleeper(wq))
                wake_up_interruptible_sync_poll(&wq->wait, POLLIN |
                                                POLLRDNORM | POLLRDBAND);
        sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
index 552dbaba9cf386a07e6c4f499fda27ca1f8a8f4a..525acf6dd1c6f8be4a66b607c94c1acc66c02356 100644 (file)
@@ -1492,7 +1492,7 @@ static void tipc_write_space(struct sock *sk)
 
        rcu_read_lock();
        wq = rcu_dereference(sk->sk_wq);
-       if (wq_has_sleeper(wq))
+       if (skwq_has_sleeper(wq))
                wake_up_interruptible_sync_poll(&wq->wait, POLLOUT |
                                                POLLWRNORM | POLLWRBAND);
        rcu_read_unlock();
@@ -1509,7 +1509,7 @@ static void tipc_data_ready(struct sock *sk)
 
        rcu_read_lock();
        wq = rcu_dereference(sk->sk_wq);
-       if (wq_has_sleeper(wq))
+       if (skwq_has_sleeper(wq))
                wake_up_interruptible_sync_poll(&wq->wait, POLLIN |
                                                POLLRDNORM | POLLRDBAND);
        rcu_read_unlock();
index 955ec152cb71eac8c91e06f1c922d1df20f6e1f0..efb706e1d1c0c611512bc1785d67cf9651fae5e4 100644 (file)
@@ -339,7 +339,7 @@ static void unix_write_space(struct sock *sk)
        rcu_read_lock();
        if (unix_writable(sk)) {
                wq = rcu_dereference(sk->sk_wq);
-               if (wq_has_sleeper(wq))
+               if (skwq_has_sleeper(wq))
                        wake_up_interruptible_sync_poll(&wq->wait,
                                POLLOUT | POLLWRNORM | POLLWRBAND);
                sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);