summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWANG Cong <xiyou.wangcong@gmail.com>2016-11-11 10:20:50 -0800
committerDavid S. Miller <davem@davemloft.net>2016-11-14 13:17:21 -0500
commit10fe7c8870c1566685f0a8ecf45bc1811a344d99 (patch)
treebd4a45622642022ecb6a80820402eda493217c23
parent736d25df198dddeec82f61fee130f7d0e4212a9c (diff)
downloadlinux-crypto-10fe7c8870c1566685f0a8ecf45bc1811a344d99.tar.gz
linux-crypto-10fe7c8870c1566685f0a8ecf45bc1811a344d99.zip
net: fix sleeping for sk_wait_event()
Similar to commit 14135f30e33c ("inet: fix sleeping inside inet_wait_for_connect()"), sk_wait_event() needs to fix too, because release_sock() is blocking, it changes the process state back to running after sleep, which breaks the previous prepare_to_wait(). Switch to the new wait API. Cc: Eric Dumazet <eric.dumazet@gmail.com> Cc: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--crypto/algif_aead.c9
-rw-r--r--crypto/algif_skcipher.c18
2 files changed, 13 insertions, 14 deletions
diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
index 80a0f1a7..8948392c 100644
--- a/crypto/algif_aead.c
+++ b/crypto/algif_aead.c
@@ -132,28 +132,27 @@ static void aead_wmem_wakeup(struct sock *sk)
static int aead_wait_for_data(struct sock *sk, unsigned flags)
{
+ DEFINE_WAIT_FUNC(wait, woken_wake_function);
struct alg_sock *ask = alg_sk(sk);
struct aead_ctx *ctx = ask->private;
long timeout;
- DEFINE_WAIT(wait);
int err = -ERESTARTSYS;
if (flags & MSG_DONTWAIT)
return -EAGAIN;
sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
-
+ add_wait_queue(sk_sleep(sk), &wait);
for (;;) {
if (signal_pending(current))
break;
- prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
timeout = MAX_SCHEDULE_TIMEOUT;
- if (sk_wait_event(sk, &timeout, !ctx->more)) {
+ if (sk_wait_event(sk, &timeout, !ctx->more, &wait)) {
err = 0;
break;
}
}
- finish_wait(sk_sleep(sk), &wait);
+ remove_wait_queue(sk_sleep(sk), &wait);
sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index 28556fce..1e38aaa8 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -199,26 +199,26 @@ static void skcipher_free_sgl(struct sock *sk)
static int skcipher_wait_for_wmem(struct sock *sk, unsigned flags)
{
- long timeout;
- DEFINE_WAIT(wait);
+ DEFINE_WAIT_FUNC(wait, woken_wake_function);
int err = -ERESTARTSYS;
+ long timeout;
if (flags & MSG_DONTWAIT)
return -EAGAIN;
sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
+ add_wait_queue(sk_sleep(sk), &wait);
for (;;) {
if (signal_pending(current))
break;
- prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
timeout = MAX_SCHEDULE_TIMEOUT;
- if (sk_wait_event(sk, &timeout, skcipher_writable(sk))) {
+ if (sk_wait_event(sk, &timeout, skcipher_writable(sk), &wait)) {
err = 0;
break;
}
}
- finish_wait(sk_sleep(sk), &wait);
+ remove_wait_queue(sk_sleep(sk), &wait);
return err;
}
@@ -242,10 +242,10 @@ static void skcipher_wmem_wakeup(struct sock *sk)
static int skcipher_wait_for_data(struct sock *sk, unsigned flags)
{
+ DEFINE_WAIT_FUNC(wait, woken_wake_function);
struct alg_sock *ask = alg_sk(sk);
struct skcipher_ctx *ctx = ask->private;
long timeout;
- DEFINE_WAIT(wait);
int err = -ERESTARTSYS;
if (flags & MSG_DONTWAIT) {
@@ -254,17 +254,17 @@ static int skcipher_wait_for_data(struct sock *sk, unsigned flags)
sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
+ add_wait_queue(sk_sleep(sk), &wait);
for (;;) {
if (signal_pending(current))
break;
- prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
timeout = MAX_SCHEDULE_TIMEOUT;
- if (sk_wait_event(sk, &timeout, ctx->used)) {
+ if (sk_wait_event(sk, &timeout, ctx->used, &wait)) {
err = 0;
break;
}
}
- finish_wait(sk_sleep(sk), &wait);
+ remove_wait_queue(sk_sleep(sk), &wait);
sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);