diff options
| author | Breno Leitao <leitao@debian.org> | 2026-06-26 02:57:53 -0700 |
|---|---|---|
| committer | Tejun Heo <tj@kernel.org> | 2026-06-29 08:07:10 -1000 |
| commit | 1ad5dcee7c819031cf02eaf5e1e03728d0ffeb09 (patch) | |
| tree | da2924804f9fe054beb38a17f4ee85e5c44a5363 /kernel | |
| parent | 4d9be388910e5fbdb3f2794ed20737515ca6b96d (diff) | |
workqueue: split kick_pool() into kick_pool_pick()
Factor the worker selection out of kick_pool() into kick_pool_pick(),
which picks and claims the worker under pool->lock but, instead of waking
it, returns the worker's task via an out-param so the caller can issue
the wakeup after dropping pool->lock. BH kicks and wake_cpu setup still
happen under the lock.
kick_pool() becomes a thin wrapper that wakes the returned task, so all
existing callers keep waking under pool->lock.
Pure refactor, no functional change.
Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/workqueue.c | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 78068ae8f28a..49770093e785 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -1258,19 +1258,27 @@ static void kick_bh_pool(struct worker_pool *pool) } /** - * kick_pool - wake up an idle worker if necessary + * kick_pool_pick - select an idle worker to kick, deferring the wakeup * @pool: pool to kick + * @wakep: out-param, set to the task to wake after pool->lock is dropped * - * @pool may have pending work items. Wake up worker if necessary. Returns - * whether a worker was woken up. + * Like kick_pool() but, for a regular (non-BH) pool, returns the picked + * worker's task via @wakep instead of waking it, so the caller can issue the + * wakeup after dropping pool->lock (the wakeup takes rq->lock). Worker + * selection, wake_cpu setup and the BH kick still happen under the lock. + * Returns whether a worker was selected or kicked. + * + * Must be called with @pool->lock held. */ -static bool kick_pool(struct worker_pool *pool) +static bool kick_pool_pick(struct worker_pool *pool, struct task_struct **wakep) { struct worker *worker = first_idle_worker(pool); struct task_struct *p; lockdep_assert_held(&pool->lock); + *wakep = NULL; + if (!need_more_worker(pool) || !worker) return false; @@ -1310,10 +1318,27 @@ static bool kick_pool(struct worker_pool *pool) } } #endif - wake_up_process(p); + *wakep = p; return true; } +/** + * kick_pool - wake up an idle worker if necessary + * @pool: pool to kick + * + * @pool may have pending work items. Wake up worker if necessary. Returns + * whether a worker was woken up. + */ +static bool kick_pool(struct worker_pool *pool) +{ + struct task_struct *p; + bool kicked = kick_pool_pick(pool, &p); + + if (p) + wake_up_process(p); + return kicked; +} + #ifdef CONFIG_WQ_CPU_INTENSIVE_REPORT /* |
