From 4e9a37389ec2d062e02f6647d1d60c3d11150896 Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Thu, 4 Jul 2024 11:49:12 +0800 Subject: [PATCH] workqueue: Move kthread_flush_worker() out of alloc_and_link_pwqs() kthread_flush_worker() can't be called with wq_pool_mutex held. Prepare for moving wq_pool_mutex and cpu hotplug lock out of alloc_and_link_pwqs(). Cc: Zqiang Link: https://lore.kernel.org/lkml/20230920060704.24981-1-qiang.zhang1211@gmail.com/ Signed-off-by: Lai Jiangshan Signed-off-by: Tejun Heo --- kernel/workqueue.c | 15 ++++++++------- 1 file 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);