Skip to content

Commit 51697d3

Browse files
Lai Jiangshanhtejun
authored andcommitted
workqueue: use generic attach/detach routine for rescuers
There are several problems with the code that rescuers use to bind themselve to the target pool's cpumask. 1) It is very different from how the normal workers bind to cpumask, increasing code complexity and maintenance overhead. 2) The code of cpu-binding for rescuers is complicated. 3) If one or more cpu hotplugs happen while a rescuer is processing its scheduled work items, the rescuer may not stay bound to the cpumask of the pool. This is an allowed behavior, but is still hairy. It will be better if the cpumask of the rescuer is always kept synchronized with the pool across cpu hotplugs. Using generic attach/detach routine will solve the above problems and results in much simpler code. tj: Minor description updates. Signed-off-by: Lai Jiangshan <[email protected]> Signed-off-by: Tejun Heo <[email protected]>
1 parent 4736cbf commit 51697d3

File tree

1 file changed

+8
-66
lines changed

1 file changed

+8
-66
lines changed

kernel/workqueue.c

Lines changed: 8 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1603,70 +1603,6 @@ static void worker_leave_idle(struct worker *worker)
16031603
list_del_init(&worker->entry);
16041604
}
16051605

1606-
/**
1607-
* worker_maybe_bind_and_lock - try to bind %current to worker_pool and lock it
1608-
* @pool: target worker_pool
1609-
*
1610-
* Bind %current to the cpu of @pool if it is associated and lock @pool.
1611-
*
1612-
* Works which are scheduled while the cpu is online must at least be
1613-
* scheduled to a worker which is bound to the cpu so that if they are
1614-
* flushed from cpu callbacks while cpu is going down, they are
1615-
* guaranteed to execute on the cpu.
1616-
*
1617-
* This function is to be used by unbound workers and rescuers to bind
1618-
* themselves to the target cpu and may race with cpu going down or
1619-
* coming online. kthread_bind() can't be used because it may put the
1620-
* worker to already dead cpu and set_cpus_allowed_ptr() can't be used
1621-
* verbatim as it's best effort and blocking and pool may be
1622-
* [dis]associated in the meantime.
1623-
*
1624-
* This function tries set_cpus_allowed() and locks pool and verifies the
1625-
* binding against %POOL_DISASSOCIATED which is set during
1626-
* %CPU_DOWN_PREPARE and cleared during %CPU_ONLINE, so if the worker
1627-
* enters idle state or fetches works without dropping lock, it can
1628-
* guarantee the scheduling requirement described in the first paragraph.
1629-
*
1630-
* CONTEXT:
1631-
* Might sleep. Called without any lock but returns with pool->lock
1632-
* held.
1633-
*
1634-
* Return:
1635-
* %true if the associated pool is online (@worker is successfully
1636-
* bound), %false if offline.
1637-
*/
1638-
static bool worker_maybe_bind_and_lock(struct worker_pool *pool)
1639-
__acquires(&pool->lock)
1640-
{
1641-
while (true) {
1642-
/*
1643-
* The following call may fail, succeed or succeed
1644-
* without actually migrating the task to the cpu if
1645-
* it races with cpu hotunplug operation. Verify
1646-
* against POOL_DISASSOCIATED.
1647-
*/
1648-
if (!(pool->flags & POOL_DISASSOCIATED))
1649-
set_cpus_allowed_ptr(current, pool->attrs->cpumask);
1650-
1651-
spin_lock_irq(&pool->lock);
1652-
if (pool->flags & POOL_DISASSOCIATED)
1653-
return false;
1654-
if (task_cpu(current) == pool->cpu &&
1655-
cpumask_equal(&current->cpus_allowed, pool->attrs->cpumask))
1656-
return true;
1657-
spin_unlock_irq(&pool->lock);
1658-
1659-
/*
1660-
* We've raced with CPU hot[un]plug. Give it a breather
1661-
* and retry migration. cond_resched() is required here;
1662-
* otherwise, we might deadlock against cpu_stop trying to
1663-
* bring down the CPU on non-preemptive kernel.
1664-
*/
1665-
cpu_relax();
1666-
cond_resched();
1667-
}
1668-
}
1669-
16701606
static struct worker *alloc_worker(void)
16711607
{
16721608
struct worker *worker;
@@ -2361,8 +2297,9 @@ static int rescuer_thread(void *__rescuer)
23612297

23622298
spin_unlock_irq(&wq_mayday_lock);
23632299

2364-
/* migrate to the target cpu if possible */
2365-
worker_maybe_bind_and_lock(pool);
2300+
worker_attach_to_pool(rescuer, pool);
2301+
2302+
spin_lock_irq(&pool->lock);
23662303
rescuer->pool = pool;
23672304

23682305
/*
@@ -2375,6 +2312,11 @@ static int rescuer_thread(void *__rescuer)
23752312
move_linked_works(work, scheduled, &n);
23762313

23772314
process_scheduled_works(rescuer);
2315+
spin_unlock_irq(&pool->lock);
2316+
2317+
worker_detach_from_pool(rescuer, pool);
2318+
2319+
spin_lock_irq(&pool->lock);
23782320

23792321
/*
23802322
* Put the reference grabbed by send_mayday(). @pool won't

0 commit comments

Comments
 (0)