diff options
| author | WANG Cong <xiyou.wangcong@gmail.com> | 2016-11-11 13:20:50 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2016-11-14 13:17:21 -0500 |
| commit | d9dc8b0f8b4ec8cdc48ad5a20a3105387138be82 (patch) | |
| tree | a28c86da1c3ba7fef0f3fa82a5c7fc5bbb6fe2bf /crypto/algif_skcipher.c | |
| parent | 7d384846b9987f7b611357adf3cdfecfdcf0c402 (diff) | |
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 'crypto/algif_skcipher.c')
| -rw-r--r-- | crypto/algif_skcipher.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index 28556fce4267..1e38aaa8303e 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c | |||
| @@ -199,26 +199,26 @@ static void skcipher_free_sgl(struct sock *sk) | |||
| 199 | 199 | ||
| 200 | static int skcipher_wait_for_wmem(struct sock *sk, unsigned flags) | 200 | static int skcipher_wait_for_wmem(struct sock *sk, unsigned flags) |
| 201 | { | 201 | { |
| 202 | long timeout; | 202 | DEFINE_WAIT_FUNC(wait, woken_wake_function); |
| 203 | DEFINE_WAIT(wait); | ||
| 204 | int err = -ERESTARTSYS; | 203 | int err = -ERESTARTSYS; |
| 204 | long timeout; | ||
| 205 | 205 | ||
| 206 | if (flags & MSG_DONTWAIT) | 206 | if (flags & MSG_DONTWAIT) |
| 207 | return -EAGAIN; | 207 | return -EAGAIN; |
| 208 | 208 | ||
| 209 | sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk); | 209 | sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk); |
| 210 | 210 | ||
| 211 | add_wait_queue(sk_sleep(sk), &wait); | ||
| 211 | for (;;) { | 212 | for (;;) { |
| 212 | if (signal_pending(current)) | 213 | if (signal_pending(current)) |
| 213 | break; | 214 | break; |
| 214 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | ||
| 215 | timeout = MAX_SCHEDULE_TIMEOUT; | 215 | timeout = MAX_SCHEDULE_TIMEOUT; |
| 216 | if (sk_wait_event(sk, &timeout, skcipher_writable(sk))) { | 216 | if (sk_wait_event(sk, &timeout, skcipher_writable(sk), &wait)) { |
| 217 | err = 0; | 217 | err = 0; |
| 218 | break; | 218 | break; |
| 219 | } | 219 | } |
| 220 | } | 220 | } |
| 221 | finish_wait(sk_sleep(sk), &wait); | 221 | remove_wait_queue(sk_sleep(sk), &wait); |
| 222 | 222 | ||
| 223 | return err; | 223 | return err; |
| 224 | } | 224 | } |
| @@ -242,10 +242,10 @@ static void skcipher_wmem_wakeup(struct sock *sk) | |||
| 242 | 242 | ||
| 243 | static int skcipher_wait_for_data(struct sock *sk, unsigned flags) | 243 | static int skcipher_wait_for_data(struct sock *sk, unsigned flags) |
| 244 | { | 244 | { |
| 245 | DEFINE_WAIT_FUNC(wait, woken_wake_function); | ||
| 245 | struct alg_sock *ask = alg_sk(sk); | 246 | struct alg_sock *ask = alg_sk(sk); |
| 246 | struct skcipher_ctx *ctx = ask->private; | 247 | struct skcipher_ctx *ctx = ask->private; |
| 247 | long timeout; | 248 | long timeout; |
| 248 | DEFINE_WAIT(wait); | ||
| 249 | int err = -ERESTARTSYS; | 249 | int err = -ERESTARTSYS; |
| 250 | 250 | ||
| 251 | if (flags & MSG_DONTWAIT) { | 251 | if (flags & MSG_DONTWAIT) { |
| @@ -254,17 +254,17 @@ static int skcipher_wait_for_data(struct sock *sk, unsigned flags) | |||
| 254 | 254 | ||
| 255 | sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk); | 255 | sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk); |
| 256 | 256 | ||
| 257 | add_wait_queue(sk_sleep(sk), &wait); | ||
| 257 | for (;;) { | 258 | for (;;) { |
| 258 | if (signal_pending(current)) | 259 | if (signal_pending(current)) |
| 259 | break; | 260 | break; |
| 260 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | ||
| 261 | timeout = MAX_SCHEDULE_TIMEOUT; | 261 | timeout = MAX_SCHEDULE_TIMEOUT; |
| 262 | if (sk_wait_event(sk, &timeout, ctx->used)) { | 262 | if (sk_wait_event(sk, &timeout, ctx->used, &wait)) { |
| 263 | err = 0; | 263 | err = 0; |
| 264 | break; | 264 | break; |
| 265 | } | 265 | } |
| 266 | } | 266 | } |
| 267 | finish_wait(sk_sleep(sk), &wait); | 267 | remove_wait_queue(sk_sleep(sk), &wait); |
| 268 | 268 | ||
| 269 | sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk); | 269 | sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk); |
| 270 | 270 | ||
