Skip to content

Commit 9022ada

Browse files
committed
Merge branch 'for-4.19' of git://git.kernel.org/pub/scm/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()
2 parents 18b8bfd + 87915ad commit 9022ada

File tree

1 file changed

+30
-15
lines changed

1 file changed

+30
-15
lines changed

kernel/workqueue.c

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2652,6 +2652,9 @@ void flush_workqueue(struct workqueue_struct *wq)
26522652
if (WARN_ON(!wq_online))
26532653
return;
26542654

2655+
lock_map_acquire(&wq->lockdep_map);
2656+
lock_map_release(&wq->lockdep_map);
2657+
26552658
mutex_lock(&wq->mutex);
26562659

26572660
/*
@@ -2843,7 +2846,8 @@ void drain_workqueue(struct workqueue_struct *wq)
28432846
}
28442847
EXPORT_SYMBOL_GPL(drain_workqueue);
28452848

2846-
static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr)
2849+
static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr,
2850+
bool from_cancel)
28472851
{
28482852
struct worker *worker = NULL;
28492853
struct worker_pool *pool;
@@ -2885,7 +2889,8 @@ static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr)
28852889
* workqueues the deadlock happens when the rescuer stalls, blocking
28862890
* forward progress.
28872891
*/
2888-
if (pwq->wq->saved_max_active == 1 || pwq->wq->rescuer) {
2892+
if (!from_cancel &&
2893+
(pwq->wq->saved_max_active == 1 || pwq->wq->rescuer)) {
28892894
lock_map_acquire(&pwq->wq->lockdep_map);
28902895
lock_map_release(&pwq->wq->lockdep_map);
28912896
}
@@ -2896,6 +2901,27 @@ static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr)
28962901
return false;
28972902
}
28982903

2904+
static bool __flush_work(struct work_struct *work, bool from_cancel)
2905+
{
2906+
struct wq_barrier barr;
2907+
2908+
if (WARN_ON(!wq_online))
2909+
return false;
2910+
2911+
if (!from_cancel) {
2912+
lock_map_acquire(&work->lockdep_map);
2913+
lock_map_release(&work->lockdep_map);
2914+
}
2915+
2916+
if (start_flush_work(work, &barr, from_cancel)) {
2917+
wait_for_completion(&barr.done);
2918+
destroy_work_on_stack(&barr.work);
2919+
return true;
2920+
} else {
2921+
return false;
2922+
}
2923+
}
2924+
28992925
/**
29002926
* flush_work - wait for a work to finish executing the last queueing instance
29012927
* @work: the work to flush
@@ -2909,18 +2935,7 @@ static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr)
29092935
*/
29102936
bool flush_work(struct work_struct *work)
29112937
{
2912-
struct wq_barrier barr;
2913-
2914-
if (WARN_ON(!wq_online))
2915-
return false;
2916-
2917-
if (start_flush_work(work, &barr)) {
2918-
wait_for_completion(&barr.done);
2919-
destroy_work_on_stack(&barr.work);
2920-
return true;
2921-
} else {
2922-
return false;
2923-
}
2938+
return __flush_work(work, false);
29242939
}
29252940
EXPORT_SYMBOL_GPL(flush_work);
29262941

@@ -2986,7 +3001,7 @@ static bool __cancel_work_timer(struct work_struct *work, bool is_dwork)
29863001
* isn't executing.
29873002
*/
29883003
if (wq_online)
2989-
flush_work(work);
3004+
__flush_work(work, true);
29903005

29913006
clear_work_data(work);
29923007

0 commit comments

Comments
 (0)