diff options
-rw-r--r-- | kernel/workqueue.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index af00e63182d0..ab0aca0ccc8f 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -5467,12 +5467,6 @@ static int alloc_and_link_pwqs(struct workqueue_struct *wq) } cpus_read_unlock(); - /* for unbound pwq, flush the pwq_release_worker ensures that the - * pwq_release_workfn() completes before calling kfree(wq). - */ - if (ret) - kthread_flush_worker(pwq_release_worker); - return ret; enomem: @@ -5705,8 +5699,15 @@ struct workqueue_struct *alloc_workqueue(const char *fmt, return wq; err_free_node_nr_active: - if (wq->flags & WQ_UNBOUND) + /* + * Failed alloc_and_link_pwqs() may leave pending pwq->release_work, + * flushing the pwq_release_worker ensures that the pwq_release_workfn() + * completes before calling kfree(wq). + */ + if (wq->flags & WQ_UNBOUND) { + kthread_flush_worker(pwq_release_worker); free_node_nr_active(wq->node_nr_active); + } err_unreg_lockdep: wq_unregister_lockdep(wq); wq_free_lockdep(wq); |