diff options
author | WANG Cong <xiyou.wangcong@gmail.com> | 2016-11-11 19:20:50 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-11-14 19:17:21 +0100 |
commit | d9dc8b0f8b4ec8cdc48ad5a20a3105387138be82 (patch) | |
tree | a28c86da1c3ba7fef0f3fa82a5c7fc5bbb6fe2bf /net/llc | |
parent | Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next (diff) | |
download | linux-d9dc8b0f8b4ec8cdc48ad5a20a3105387138be82.tar.xz linux-d9dc8b0f8b4ec8cdc48ad5a20a3105387138be82.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>
Diffstat (limited to 'net/llc')
-rw-r--r-- | net/llc/af_llc.c | 24 |
1 files changed, 12 insertions, 12 deletions
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index db916cf51ffe..5e9296382420 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c @@ -532,12 +532,12 @@ out: static int llc_ui_wait_for_disc(struct sock *sk, long timeout) { - DEFINE_WAIT(wait); + DEFINE_WAIT_FUNC(wait, woken_wake_function); int rc = 0; + add_wait_queue(sk_sleep(sk), &wait); while (1) { - prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); - if (sk_wait_event(sk, &timeout, sk->sk_state == TCP_CLOSE)) + if (sk_wait_event(sk, &timeout, sk->sk_state == TCP_CLOSE, &wait)) break; rc = -ERESTARTSYS; if (signal_pending(current)) @@ -547,39 +547,39 @@ static int llc_ui_wait_for_disc(struct sock *sk, long timeout) break; rc = 0; } - finish_wait(sk_sleep(sk), &wait); + remove_wait_queue(sk_sleep(sk), &wait); return rc; } static bool llc_ui_wait_for_conn(struct sock *sk, long timeout) { - DEFINE_WAIT(wait); + DEFINE_WAIT_FUNC(wait, woken_wake_function); + add_wait_queue(sk_sleep(sk), &wait); while (1) { - prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); - if (sk_wait_event(sk, &timeout, sk->sk_state != TCP_SYN_SENT)) + if (sk_wait_event(sk, &timeout, sk->sk_state != TCP_SYN_SENT, &wait)) break; if (signal_pending(current) || !timeout) break; } - finish_wait(sk_sleep(sk), &wait); + remove_wait_queue(sk_sleep(sk), &wait); return timeout; } static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout) { - DEFINE_WAIT(wait); + DEFINE_WAIT_FUNC(wait, woken_wake_function); struct llc_sock *llc = llc_sk(sk); int rc; + add_wait_queue(sk_sleep(sk), &wait); while (1) { - prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); rc = 0; if (sk_wait_event(sk, &timeout, (sk->sk_shutdown & RCV_SHUTDOWN) || (!llc_data_accept_state(llc->state) && !llc->remote_busy_flag && - !llc->p_flag))) + !llc->p_flag), &wait)) break; rc = -ERESTARTSYS; if (signal_pending(current)) @@ -588,7 +588,7 @@ static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout) if (!timeout) break; } - finish_wait(sk_sleep(sk), &wait); + remove_wait_queue(sk_sleep(sk), &wait); return rc; } |