• Tejun Heo's avatar
    workqueue: consider work function when searching for busy work items · a2c1c57b
    Tejun Heo authored
    To avoid executing the same work item concurrenlty, workqueue hashes
    currently busy workers according to their current work items and looks
    up the the table when it wants to execute a new work item.  If there
    already is a worker which is executing the new work item, the new item
    is queued to the found worker so that it gets executed only after the
    current execution finishes.
    
    Unfortunately, a work item may be freed while being executed and thus
    recycled for different purposes.  If it gets recycled for a different
    work item and queued while the previous execution is still in
    progress, workqueue may make the new work item wait for the old one
    although the two aren't really related in any way.
    
    In extreme cases, this false dependency may lead to deadlock although
    it's extremely unlikely given that there aren't too many self-freeing
    work item users and they usually don't wait for other work items.
    
    To alleviate the problem, record the current work function in each
    busy worker and match it together with the work item address in
    find_worker_executing_work().  While this isn't complete, it ensures
    that unrelated work items don't interact with each other and in the
    very unlikely case where a twisted wq user triggers it, it's always
    onto itself making the culprit easy to spot.
    Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    Reported-by: default avatarAndrey Isakov <andy51@gmx.ru>
    Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=51701
    Cc: stable@vger.kernel.org
    a2c1c57b
workqueue.c 106 KB