Skip to content

Commit 4d595b8

Browse files
Lai Jiangshanhtejun
authored andcommitted
workqueue: make rescuer_thread() empty wq->maydays list before exiting
After a @pwq is scheduled for emergency execution, other workers may consume the affectd work items before the rescuer gets to them. This means that a workqueue many have pwqs queued on @wq->maydays list while not having any work item pending or in-flight. If destroy_workqueue() executes in such condition, the rescuer may exit without emptying @wq->maydays. This currently doesn't cause any actual harm. destroy_workqueue() can safely destroy all the involved data structures whether @wq->maydays is populated or not as nobody access the list once the rescuer exits. However, this is nasty and makes future development difficult. Let's update rescuer_thread() so that it empties @wq->maydays after seeing should_stop to guarantee that the list is empty on rescuer exit. tj: Updated comment and patch description. Signed-off-by: Lai Jiangshan <[email protected]> Signed-off-by: Tejun Heo <[email protected]> Cc: [email protected] # v3.10+
1 parent 77f300b commit 4d595b8

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

kernel/workqueue.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2398,6 +2398,7 @@ static int rescuer_thread(void *__rescuer)
23982398
struct worker *rescuer = __rescuer;
23992399
struct workqueue_struct *wq = rescuer->rescue_wq;
24002400
struct list_head *scheduled = &rescuer->scheduled;
2401+
bool should_stop;
24012402

24022403
set_user_nice(current, RESCUER_NICE_LEVEL);
24032404

@@ -2409,11 +2410,15 @@ static int rescuer_thread(void *__rescuer)
24092410
repeat:
24102411
set_current_state(TASK_INTERRUPTIBLE);
24112412

2412-
if (kthread_should_stop()) {
2413-
__set_current_state(TASK_RUNNING);
2414-
rescuer->task->flags &= ~PF_WQ_WORKER;
2415-
return 0;
2416-
}
2413+
/*
2414+
* By the time the rescuer is requested to stop, the workqueue
2415+
* shouldn't have any work pending, but @wq->maydays may still have
2416+
* pwq(s) queued. This can happen by non-rescuer workers consuming
2417+
* all the work items before the rescuer got to them. Go through
2418+
* @wq->maydays processing before acting on should_stop so that the
2419+
* list is always empty on exit.
2420+
*/
2421+
should_stop = kthread_should_stop();
24172422

24182423
/* see whether any pwq is asking for help */
24192424
spin_lock_irq(&wq_mayday_lock);
@@ -2459,6 +2464,12 @@ static int rescuer_thread(void *__rescuer)
24592464

24602465
spin_unlock_irq(&wq_mayday_lock);
24612466

2467+
if (should_stop) {
2468+
__set_current_state(TASK_RUNNING);
2469+
rescuer->task->flags &= ~PF_WQ_WORKER;
2470+
return 0;
2471+
}
2472+
24622473
/* rescuers should never participate in concurrency management */
24632474
WARN_ON_ONCE(!(rescuer->flags & WORKER_NOT_RUNNING));
24642475
schedule();

0 commit comments

Comments
 (0)