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 /net/llc | |
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 '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: | |||
532 | 532 | ||
533 | static int llc_ui_wait_for_disc(struct sock *sk, long timeout) | 533 | static int llc_ui_wait_for_disc(struct sock *sk, long timeout) |
534 | { | 534 | { |
535 | DEFINE_WAIT(wait); | 535 | DEFINE_WAIT_FUNC(wait, woken_wake_function); |
536 | int rc = 0; | 536 | int rc = 0; |
537 | 537 | ||
538 | add_wait_queue(sk_sleep(sk), &wait); | ||
538 | while (1) { | 539 | while (1) { |
539 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | 540 | if (sk_wait_event(sk, &timeout, sk->sk_state == TCP_CLOSE, &wait)) |
540 | if (sk_wait_event(sk, &timeout, sk->sk_state == TCP_CLOSE)) | ||
541 | break; | 541 | break; |
542 | rc = -ERESTARTSYS; | 542 | rc = -ERESTARTSYS; |
543 | if (signal_pending(current)) | 543 | if (signal_pending(current)) |
@@ -547,39 +547,39 @@ static int llc_ui_wait_for_disc(struct sock *sk, long timeout) | |||
547 | break; | 547 | break; |
548 | rc = 0; | 548 | rc = 0; |
549 | } | 549 | } |
550 | finish_wait(sk_sleep(sk), &wait); | 550 | remove_wait_queue(sk_sleep(sk), &wait); |
551 | return rc; | 551 | return rc; |
552 | } | 552 | } |
553 | 553 | ||
554 | static bool llc_ui_wait_for_conn(struct sock *sk, long timeout) | 554 | static bool llc_ui_wait_for_conn(struct sock *sk, long timeout) |
555 | { | 555 | { |
556 | DEFINE_WAIT(wait); | 556 | DEFINE_WAIT_FUNC(wait, woken_wake_function); |
557 | 557 | ||
558 | add_wait_queue(sk_sleep(sk), &wait); | ||
558 | while (1) { | 559 | while (1) { |
559 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | 560 | if (sk_wait_event(sk, &timeout, sk->sk_state != TCP_SYN_SENT, &wait)) |
560 | if (sk_wait_event(sk, &timeout, sk->sk_state != TCP_SYN_SENT)) | ||
561 | break; | 561 | break; |
562 | if (signal_pending(current) || !timeout) | 562 | if (signal_pending(current) || !timeout) |
563 | break; | 563 | break; |
564 | } | 564 | } |
565 | finish_wait(sk_sleep(sk), &wait); | 565 | remove_wait_queue(sk_sleep(sk), &wait); |
566 | return timeout; | 566 | return timeout; |
567 | } | 567 | } |
568 | 568 | ||
569 | static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout) | 569 | static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout) |
570 | { | 570 | { |
571 | DEFINE_WAIT(wait); | 571 | DEFINE_WAIT_FUNC(wait, woken_wake_function); |
572 | struct llc_sock *llc = llc_sk(sk); | 572 | struct llc_sock *llc = llc_sk(sk); |
573 | int rc; | 573 | int rc; |
574 | 574 | ||
575 | add_wait_queue(sk_sleep(sk), &wait); | ||
575 | while (1) { | 576 | while (1) { |
576 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | ||
577 | rc = 0; | 577 | rc = 0; |
578 | if (sk_wait_event(sk, &timeout, | 578 | if (sk_wait_event(sk, &timeout, |
579 | (sk->sk_shutdown & RCV_SHUTDOWN) || | 579 | (sk->sk_shutdown & RCV_SHUTDOWN) || |
580 | (!llc_data_accept_state(llc->state) && | 580 | (!llc_data_accept_state(llc->state) && |
581 | !llc->remote_busy_flag && | 581 | !llc->remote_busy_flag && |
582 | !llc->p_flag))) | 582 | !llc->p_flag), &wait)) |
583 | break; | 583 | break; |
584 | rc = -ERESTARTSYS; | 584 | rc = -ERESTARTSYS; |
585 | if (signal_pending(current)) | 585 | if (signal_pending(current)) |
@@ -588,7 +588,7 @@ static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout) | |||
588 | if (!timeout) | 588 | if (!timeout) |
589 | break; | 589 | break; |
590 | } | 590 | } |
591 | finish_wait(sk_sleep(sk), &wait); | 591 | remove_wait_queue(sk_sleep(sk), &wait); |
592 | return rc; | 592 | return rc; |
593 | } | 593 | } |
594 | 594 | ||