Merge branch 'for-4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 24 Aug 2018 20:16:36 +0000 (13:16 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 24 Aug 2018 20:16:36 +0000 (13:16 -0700)
Pull workqueue updates from Tejun Heo:
 "Over the lockdep cross-release churn, workqueue lost some of the
  existing annotations. Johannes Berg restored it and also improved
  them"

* 'for-4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq:
  workqueue: re-add lockdep dependencies for flushing
  workqueue: skip lockdep wq dependency in cancel_work_sync()

1  2 
kernel/workqueue.c

diff --combined kernel/workqueue.c
index 78b192071ef7b58a4d92bbc65943fdaad7ccf735,661184fcd50300f56504370155f8a173ba597479..60e80198c3df2af0b12df2e5edda9d6b2db80b88
@@@ -2652,6 -2652,9 +2652,9 @@@ void flush_workqueue(struct workqueue_s
        if (WARN_ON(!wq_online))
                return;
  
+       lock_map_acquire(&wq->lockdep_map);
+       lock_map_release(&wq->lockdep_map);
        mutex_lock(&wq->mutex);
  
        /*
@@@ -2843,7 -2846,8 +2846,8 @@@ reflush
  }
  EXPORT_SYMBOL_GPL(drain_workqueue);
  
- static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr)
+ static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr,
+                            bool from_cancel)
  {
        struct worker *worker = NULL;
        struct worker_pool *pool;
         * workqueues the deadlock happens when the rescuer stalls, blocking
         * forward progress.
         */
-       if (pwq->wq->saved_max_active == 1 || pwq->wq->rescuer) {
+       if (!from_cancel &&
+           (pwq->wq->saved_max_active == 1 || pwq->wq->rescuer)) {
                lock_map_acquire(&pwq->wq->lockdep_map);
                lock_map_release(&pwq->wq->lockdep_map);
        }
@@@ -2896,6 -2901,27 +2901,27 @@@ already_gone
        return false;
  }
  
+ static bool __flush_work(struct work_struct *work, bool from_cancel)
+ {
+       struct wq_barrier barr;
+       if (WARN_ON(!wq_online))
+               return false;
+       if (!from_cancel) {
+               lock_map_acquire(&work->lockdep_map);
+               lock_map_release(&work->lockdep_map);
+       }
+       if (start_flush_work(work, &barr, from_cancel)) {
+               wait_for_completion(&barr.done);
+               destroy_work_on_stack(&barr.work);
+               return true;
+       } else {
+               return false;
+       }
+ }
  /**
   * flush_work - wait for a work to finish executing the last queueing instance
   * @work: the work to flush
   */
  bool flush_work(struct work_struct *work)
  {
-       struct wq_barrier barr;
-       if (WARN_ON(!wq_online))
-               return false;
-       if (start_flush_work(work, &barr)) {
-               wait_for_completion(&barr.done);
-               destroy_work_on_stack(&barr.work);
-               return true;
-       } else {
-               return false;
-       }
+       return __flush_work(work, false);
  }
  EXPORT_SYMBOL_GPL(flush_work);
  
@@@ -2986,7 -3001,7 +3001,7 @@@ static bool __cancel_work_timer(struct 
         * isn't executing.
         */
        if (wq_online)
-               flush_work(work);
+               __flush_work(work, true);
  
        clear_work_data(work);
  
@@@ -3714,7 -3729,8 +3729,7 @@@ apply_wqattrs_prepare(struct workqueue_
  
        lockdep_assert_held(&wq_pool_mutex);
  
 -      ctx = kzalloc(sizeof(*ctx) + nr_node_ids * sizeof(ctx->pwq_tbl[0]),
 -                    GFP_KERNEL);
 +      ctx = kzalloc(struct_size(ctx, pwq_tbl, nr_node_ids), GFP_KERNEL);
  
        new_attrs = alloc_workqueue_attrs(GFP_KERNEL);
        tmp_attrs = alloc_workqueue_attrs(GFP_KERNEL);
@@@ -4362,7 -4378,6 +4377,7 @@@ void set_worker_desc(const char *fmt, .
                va_end(args);
        }
  }
 +EXPORT_SYMBOL_GPL(set_worker_desc);
  
  /**
   * print_worker_info - print out worker information and description
@@@ -5638,7 -5653,7 +5653,7 @@@ static void __init wq_numa_init(void
         * available.  Build one from cpu_to_node() which should have been
         * fully initialized by now.
         */
 -      tbl = kzalloc(nr_node_ids * sizeof(tbl[0]), GFP_KERNEL);
 +      tbl = kcalloc(nr_node_ids, sizeof(tbl[0]), GFP_KERNEL);
        BUG_ON(!tbl);
  
        for_each_node(node)