From: Linus Torvalds Date: Fri, 24 Aug 2018 20:16:36 +0000 (-0700) Subject: Merge branch 'for-4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq X-Git-Tag: v4.19-rc1~20 X-Git-Url: http://git.samba.org/samba.git/?p=sfrench%2Fcifs-2.6.git;a=commitdiff_plain;h=9022ada8ab6f1f1a932a3c93815061042e6548a5;hp=-c Merge branch 'for-4.19' of git://git./linux/kernel/git/tj/wq 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() --- 9022ada8ab6f1f1a932a3c93815061042e6548a5 diff --combined kernel/workqueue.c index 78b192071ef7,661184fcd503..60e80198c3df --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@@ -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; @@@ -2885,7 -2889,8 +2889,8 @@@ * 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 @@@ -2909,18 -2935,7 +2935,7 @@@ */ 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)