net: fix sleeping for sk_wait_event()
Similar to commit 14135f30e3
("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>
This commit is contained in:

committed by
David S. Miller

parent
7d384846b9
commit
d9dc8b0f8b
@@ -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);
|
||||
|
||||
|
Reference in New Issue
Block a user