• Lai Jiangshan's avatar
    workqueue: async worker destruction · 60f5a4bc
    Lai Jiangshan authored
    worker destruction includes these parts of code:
    	adjust pool's stats
    	remove the worker from idle list
    	detach the worker from the pool
    	kthread_stop() to wait for the worker's task exit
    	free the worker struct
    
    We can find out that there is no essential work to do after
    kthread_stop(), which means destroy_worker() doesn't need to wait for
    the worker's task exit, so we can remove kthread_stop() and free the
    worker struct in the worker exiting path.
    
    However, put_unbound_pool() still needs to sync the all the workers'
    destruction before destroying the pool; otherwise, the workers may
    access to the invalid pool when they are exiting.
    
    So we also move the code of "detach the worker" to the exiting
    path and let put_unbound_pool() to sync with this code via
    detach_completion.
    
    The code of "detach the worker" is wrapped in a new function
    "worker_detach_from_pool()" although worker_detach_from_pool() is only
    called once (in worker_thread()) after this patch, but we need to wrap
    it for these reasons:
    
      1) The code of "detach the worker" is not short enough to unfold them
         in worker_thread().
      2) the name of "worker_detach_from_pool()" is self-comment, and we add
         some comments above the function.
      3) it will be shared by rescuer in later patch which allows rescuer
         and normal thread use the same attach/detach frameworks.
    
    The worker id is freed when detaching which happens before the worker
    is fully dead, but this id of the dying worker may be re-used for a
    new worker, so the dying worker's task name is changed to
    "worker/dying" to avoid two or several workers having the same name.
    
    Since "detach the worker" is moved out from destroy_worker(),
    destroy_worker() doesn't require manager_mutex, so the
    "lockdep_assert_held(&pool->manager_mutex)" in destroy_worker() is
    removed, and destroy_worker() is not protected by manager_mutex in
    put_unbound_pool().
    
    tj: Minor description updates.
    Signed-off-by: default avatarLai Jiangshan <laijs@cn.fujitsu.com>
    Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    60f5a4bc
workqueue.c 142 KB