Commit 06ba38a9a0f6ceffe70343f684c5a690e3710ef4
Committed by
Linus Torvalds
1 parent
c12920d190
Exists in
master
and in
39 other branches
workqueues: shift kthread_bind() from CPU_UP_PREPARE to CPU_ONLINE
CPU_UP_PREPARE binds cwq->thread to the new CPU. So CPU_UP_CANCELED tries to wake up the task which is bound to the failed CPU. With this patch we don't bind cwq->thread until CPU becomes online. The first wake_up() after kthread_create() is a bit special, make a simple helper for that. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Gautham R Shenoy <ego@in.ibm.com> Cc: "Rafael J. Wysocki" <rjw@sisk.pl> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 1 changed file with 15 additions and 8 deletions Side-by-side Diff
kernel/workqueue.c
... | ... | @@ -668,15 +668,21 @@ |
668 | 668 | |
669 | 669 | cwq->thread = p; |
670 | 670 | cwq->should_stop = 0; |
671 | - if (!is_single_threaded(wq)) | |
672 | - kthread_bind(p, cpu); | |
673 | 671 | |
674 | - if (is_single_threaded(wq) || cpu_online(cpu)) | |
675 | - wake_up_process(p); | |
676 | - | |
677 | 672 | return 0; |
678 | 673 | } |
679 | 674 | |
675 | +static void start_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu) | |
676 | +{ | |
677 | + struct task_struct *p = cwq->thread; | |
678 | + | |
679 | + if (p != NULL) { | |
680 | + if (cpu >= 0) | |
681 | + kthread_bind(p, cpu); | |
682 | + wake_up_process(p); | |
683 | + } | |
684 | +} | |
685 | + | |
680 | 686 | struct workqueue_struct *__create_workqueue(const char *name, |
681 | 687 | int singlethread, int freezeable) |
682 | 688 | { |
... | ... | @@ -702,6 +708,7 @@ |
702 | 708 | if (singlethread) { |
703 | 709 | cwq = init_cpu_workqueue(wq, singlethread_cpu); |
704 | 710 | err = create_workqueue_thread(cwq, singlethread_cpu); |
711 | + start_workqueue_thread(cwq, -1); | |
705 | 712 | } else { |
706 | 713 | mutex_lock(&workqueue_mutex); |
707 | 714 | list_add(&wq->list, &workqueues); |
... | ... | @@ -711,6 +718,7 @@ |
711 | 718 | if (err || !cpu_online(cpu)) |
712 | 719 | continue; |
713 | 720 | err = create_workqueue_thread(cwq, cpu); |
721 | + start_workqueue_thread(cwq, cpu); | |
714 | 722 | } |
715 | 723 | mutex_unlock(&workqueue_mutex); |
716 | 724 | } |
717 | 725 | |
... | ... | @@ -808,12 +816,11 @@ |
808 | 816 | return NOTIFY_BAD; |
809 | 817 | |
810 | 818 | case CPU_ONLINE: |
811 | - wake_up_process(cwq->thread); | |
819 | + start_workqueue_thread(cwq, cpu); | |
812 | 820 | break; |
813 | 821 | |
814 | 822 | case CPU_UP_CANCELED: |
815 | - if (cwq->thread) | |
816 | - wake_up_process(cwq->thread); | |
823 | + start_workqueue_thread(cwq, -1); | |
817 | 824 | case CPU_DEAD: |
818 | 825 | cleanup_workqueue_thread(cwq, cpu); |
819 | 826 | break; |