• Tejun Heo's avatar
    workqueue: reimplement cancel_delayed_work() using try_to_grab_pending() · 57b30ae7
    Tejun Heo authored
    cancel_delayed_work() can't be called from IRQ handlers due to its use
    of del_timer_sync() and can't cancel work items which are already
    transferred from timer to worklist.
    
    Also, unlike other flush and cancel functions, a canceled delayed_work
    would still point to the last associated cpu_workqueue.  If the
    workqueue is destroyed afterwards and the work item is re-used on a
    different workqueue, the queueing code can oops trying to dereference
    already freed cpu_workqueue.
    
    This patch reimplements cancel_delayed_work() using
    try_to_grab_pending() and set_work_cpu_and_clear_pending().  This
    allows the function to be called from IRQ handlers and makes its
    behavior consistent with other flush / cancel functions.
    Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Ingo Molnar <mingo@redhat.com>
    Cc: Andrew Morton <akpm@linux-foundation.org>
    57b30ae7
workqueue.c 106 KB