• Tejun Heo's avatar
    workqueue: use shared worklist and pool all workers per cpu · 7e11629d
    Tejun Heo authored
    Use gcwq->worklist instead of cwq->worklist and break the strict
    association between a cwq and its worker.  All works queued on a cpu
    are queued on gcwq->worklist and processed by any available worker on
    the gcwq.
    
    As there no longer is strict association between a cwq and its worker,
    whether a work is executing can now only be determined by calling
    [__]find_worker_executing_work().
    
    After this change, the only association between a cwq and its worker
    is that a cwq puts a worker into shared worker pool on creation and
    kills it on destruction.  As all workqueues are still limited to
    max_active of one, this means that there are always at least as many
    workers as active works and thus there's no danger for deadlock.
    
    The break of strong association between cwqs and workers requires
    somewhat clumsy changes to current_is_keventd() and
    destroy_workqueue().  Dynamic worker pool management will remove both
    clumsy changes.  current_is_keventd() won't be necessary at all as the
    only reason it exists is to avoid queueing a work from a work which
    will be allowed just fine.  The clumsy part of destroy_workqueue() is
    added because a worker can only be destroyed while idle and there's no
    guarantee a worker is idle when its wq is going down.  With dynamic
    pool management, workers are not associated with workqueues at all and
    only idle ones will be submitted to destroy_workqueue() so the code
    won't be necessary anymore.
    Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    7e11629d
workqueue.c 67 KB