workqueues: shift kthread_bind() from CPU_UP_PREPARE to CPU_ONLINE
PATCH 1/1 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 <[email protected]>
kernel/workqueue.c renamed from kernel/workqueue.c~2_BIND +15 -8
@@ -631,15 +631,21 @@ static int create_workqueue_thread(struc cwq->thread = p; cwq->should_stop =0 ; -if (!is_single_threaded (wq)) -kthread_bind (p, cpu); - -if (is_single_threaded (wq) ||cpu_online (cpu)) -wake_up_process (p);return 0 ; } +static void start_workqueue_thread (struct cpu_workqueue_struct *cwq,int cpu) +{ +struct task_struct *p = cwq->thread; + +if (p !=NULL ) { +if (cpu >=0 ) +kthread_bind (p, cpu); +wake_up_process (p); + } +} +struct workqueue_struct *__create_workqueue (const char *name,int singlethread,int freezeable) {
@@ -665,6 +671,7 @@ struct workqueue_struct *__create_workquif (singlethread) { cwq =init_cpu_workqueue (wq, singlethread_cpu); err =create_workqueue_thread (cwq, singlethread_cpu); +start_workqueue_thread (cwq,-1 ); }else {mutex_lock (&workqueue_mutex);list_add (&wq->list, &workqueues);
@@ -674,6 +681,7 @@ struct workqueue_struct *__create_workquif (err || !cpu_online (cpu))continue ; err =create_workqueue_thread (cwq, cpu); +start_workqueue_thread (cwq, cpu); }mutex_unlock (&workqueue_mutex); }
@@ -773,12 +781,11 @@ static int __devinit workqueue_cpu_callbreturn NOTIFY_BAD ;case CPU_ONLINE : -wake_up_process (cwq->thread); +start_workqueue_thread (cwq, cpu);break ;case CPU_UP_CANCELED : -if (cwq->thread) -wake_up_process (cwq->thread); +start_workqueue_thread (cwq,-1 );case CPU_DEAD :cleanup_workqueue_thread (cwq, cpu);break ;