Message ID | 1393421120-6681-1-git-send-email-luis.henriques@canonical.com |
---|---|
State | New |
Headers | show |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 89743ae..d19727f 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -1472,12 +1472,19 @@ static void destroy_worker(struct worker *worker) if (worker->flags & WORKER_IDLE) gcwq->nr_idle--; + /* + * Once WORKER_DIE is set, the kworker may destroy itself at any + * point. Pin to ensure the task stays until we're done with it. + */ + get_task_struct(worker->task); + list_del_init(&worker->entry); worker->flags |= WORKER_DIE; spin_unlock_irq(&gcwq->lock); kthread_stop(worker->task); + put_task_struct(worker->task); kfree(worker); spin_lock_irq(&gcwq->lock);