• Stephen Boyd's avatar
    workqueue: Catch more locking problems with flush_work() · 0976dfc1
    Stephen Boyd authored
    If a workqueue is flushed with flush_work() lockdep checking can
    be circumvented. For example:
    
     static DEFINE_MUTEX(mutex);
    
     static void my_work(struct work_struct *w)
     {
             mutex_lock(&mutex);
             mutex_unlock(&mutex);
     }
    
     static DECLARE_WORK(work, my_work);
    
     static int __init start_test_module(void)
     {
             schedule_work(&work);
             return 0;
     }
     module_init(start_test_module);
    
     static void __exit stop_test_module(void)
     {
             mutex_lock(&mutex);
             flush_work(&work);
             mutex_unlock(&mutex);
     }
     module_exit(stop_test_module);
    
    would not always print a warning when flush_work() was called.
    In this trivial example nothing could go wrong since we are
    guaranteed module_init() and module_exit() don't run concurrently,
    but if the work item is schedule asynchronously we could have a
    scenario where the work item is running just at the time flush_work()
    is called resulting in a classic ABBA locking problem.
    
    Add a lockdep hint by acquiring and releasing the work item
    lockdep_map in flush_work() so that we always catch this
    potential deadlock scenario.
    Signed-off-by: default avatarStephen Boyd <sboyd@codeaurora.org>
    Reviewed-by: default avatarYong Zhang <yong.zhang0@gmail.com>
    Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    0976dfc1
workqueue.c 104 KB