X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=kernel%2Fworkqueue.c;h=193e977a10eaeb6a7f9ca5927d08f558d68df434;hb=18f2af2d68815e1c4d5c275ebd030e27ef627582;hp=82ef9f3b7473a81ef5004362c7281ae9f4aea82a;hpb=5c2740280fef1c2da7835dea3856b5e9fc2a4bfd;p=~andy%2Flinux diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 82ef9f3b747..193e977a10e 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -1851,6 +1851,12 @@ static void destroy_worker(struct worker *worker) if (worker->flags & WORKER_IDLE) pool->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; @@ -1859,6 +1865,7 @@ static void destroy_worker(struct worker *worker) spin_unlock_irq(&pool->lock); kthread_stop(worker->task); + put_task_struct(worker->task); kfree(worker); spin_lock_irq(&pool->lock);