From: Herbert Xu <herb...@gondor.apana.org.au>

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 <herb...@gondor.apana.org.au>
Signed-off-by: David S. Miller <da...@davemloft.net>

Changes when porting to vz7:
- skip rypto/algif_aead.c hunks

https://jira.sw.ru/browse/PSBM-141883
(cherry picked from commit 1ce0bf50ae2233c7115a18c0c623662d177b434c)
Signed-off-by: Pavel Tikhomirov <ptikhomi...@virtuozzo.com>
---
 crypto/algif_skcipher.c |  4 ++--
 include/linux/wait.h    | 21 +++++++++++++++++++++
 include/net/sock.h      | 15 +++++----------
 net/atm/common.c        |  4 ++--
 net/core/sock.c         |  8 ++++----
 net/core/stream.c       |  2 +-
 net/dccp/output.c       |  2 +-
 net/iucv/af_iucv.c      |  2 +-
 net/rxrpc/af_rxrpc.c    |  2 +-
 net/sctp/socket.c       |  2 +-
 net/tipc/socket.c       |  4 ++--
 net/unix/af_unix.c      |  2 +-
 12 files changed, 42 insertions(+), 26 deletions(-)

diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index 9a62fa9e02ec..ad4a88628f95 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -186,7 +186,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);
@@ -236,7 +236,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);
diff --git a/include/linux/wait.h b/include/linux/wait.h
index b52741b1775a..2cd2201fc1e4 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -123,6 +123,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);
diff --git a/include/net/sock.h b/include/net/sock.h
index e67f4de07c6b..a8609a8c04a1 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -59,6 +59,7 @@
 #include <linux/static_key.h>
 #include <linux/aio.h>
 #include <linux/sched.h>
+#include <linux/wait.h>
 
 #include <linux/filter.h>
 #include <linux/rculist_nulls.h>
@@ -2054,12 +2055,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:
@@ -2085,15 +2086,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);
 }
 
 /**
diff --git a/net/atm/common.c b/net/atm/common.c
index ecaface2878d..6325ab578401 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -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);
diff --git a/net/core/sock.c b/net/core/sock.c
index 937b705e2c82..130ac5ae3107 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -2396,7 +2396,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();
 }
@@ -2407,7 +2407,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();
@@ -2419,7 +2419,7 @@ static void sock_def_readable(struct sock *sk, int len)
 
        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);
@@ -2437,7 +2437,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);
 
diff --git a/net/core/stream.c b/net/core/stream.c
index d70f77a0c889..8ff9d63b4265 100644
--- a/net/core/stream.c
+++ b/net/core/stream.c
@@ -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))
diff --git a/net/dccp/output.c b/net/dccp/output.c
index 8876078859da..c60ddcdcc6c9 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -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))
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index af877285f5e0..a7ba44d17c84 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -305,7 +305,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();
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
index e61aa6001c65..73d2767d530a 100644
--- a/net/rxrpc/af_rxrpc.c
+++ b/net/rxrpc/af_rxrpc.c
@@ -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);
        }
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 67f083895cdd..2b524f9939ce 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -7625,7 +7625,7 @@ void sctp_data_ready(struct sock *sk, int len)
 
        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);
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 2b1d7c2d677d..2b1c75efba7f 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -1116,7 +1116,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();
@@ -1133,7 +1133,7 @@ static void tipc_data_ready(struct sock *sk, int len)
 
        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();
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 2ecdf86ce707..44f7d932b23e 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -441,7 +441,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);
-- 
2.37.1

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to