• L
    workqueue: fix possible idle worker depletion across CPU hotplug · ee378aa4
    Lai Jiangshan 提交于
    To simplify both normal and CPU hotplug paths, worker management is
    prevented while CPU hoplug is in progress.  This is achieved by CPU
    hotplug holding the same exclusion mechanism used by workers to ensure
    there's only one manager per pool.
    
    If someone else seems to be performing the manager role, workers
    proceed to execute work items.  CPU hotplug using the same mechanism
    can lead to idle worker depletion because all workers could proceed to
    execute work items while CPU hotplug is in progress and CPU hotplug
    itself wouldn't actually perform the worker management duty - it
    doesn't guarantee that there's an idle worker left when it releases
    management.
    
    This idle worker depletion, under extreme circumstances, can break
    forward-progress guarantee and thus lead to deadlock.
    
    This patch fixes the bug by using separate mechanisms for manager
    exclusion among workers and hotplug exclusion.  For manager exclusion,
    POOL_MANAGING_WORKERS which was restored by the previous patch is
    used.  pool->manager_mutex is now only used for exclusion between the
    elected manager and CPU hotplug.  The elected manager won't proceed
    without holding pool->manager_mutex.
    
    This ensures that the worker which won the manager position can't skip
    managing while CPU hotplug is in progress.  It will block on
    manager_mutex and perform management after CPU hotplug is complete.
    
    Note that hotplug may happen while waiting for manager_mutex.  A
    manager isn't either on idle or busy list and thus the hoplug code
    can't unbind/rebind it.  Make the manager handle its own un/rebinding.
    
    tj: Updated comment and description.
    Signed-off-by: NLai Jiangshan <laijs@cn.fujitsu.com>
    Signed-off-by: NTejun Heo <tj@kernel.org>
    ee378aa4
workqueue.c 104.4 KB