History

workqueue: Fix spurious sanity check failures in destroy_workqueue()

Before actually destrying a workqueue, destroy_workqueue() checks whether it's actually idle. If it isn't, it prints out a bunch of warning messages and leaves the workqueue dangling. It unfortunately has a couple issues. * Mayday list queueing increments pwq's refcnts which gets detected as busy and fails the sanity checks. However, because mayday list queueing is asynchronous, this condition can happen without any actual work items left in the workqueue. * Sanity check failure leaves the sysfs interface behind too which can lead to init failure of newer instances of the workqueue. This patch fixes the above two by * If a workqueue has a rescuer, disable and kill the rescuer before sanity checks. Disabling and killing is guaranteed to flush the existing mayday list. * Remove sysfs interface before sanity checks.

Tejun Heo committed 7 years ago

Commit def98c81 parent f60c55a1 file · +19 −5Browse files

Showing the changes to kernel/workqueue.c (1 of 1 file). Show all

Unified · Split

kernel/workqueue.c+19−5
@@ -4325,9 +4325,28 @@ void destroy_workqueue(struct workqueue_struct *wq) · 4324 unmodified lines
4325 struct pool_workqueue *pwq;4325 struct pool_workqueue *pwq;
4326 int node;4326 int node;
4327 4327
4328 /*
4329 * Remove it from sysfs first so that sanity check failure doesn't
4330 * lead to sysfs name conflicts.
4331 */
4332 workqueue_sysfs_unregister(wq);
4333
4328 /* drain it before proceeding with destruction */4334 /* drain it before proceeding with destruction */
4329 drain_workqueue(wq);4335 drain_workqueue(wq);
4330 4336
4337 /* kill rescuer, if sanity checks fail, leave it w/o rescuer */
4338 if (wq->rescuer) {
4339 struct worker *rescuer = wq->rescuer;
4340
4341 /* this prevents new queueing */
4342 spin_lock_irq(&wq_mayday_lock);
4343 wq->rescuer = NULL;
4344 spin_unlock_irq(&wq_mayday_lock);
4345
4346 /* rescuer will empty maydays list before exiting */
4347 kthread_stop(rescuer->task);
4348 }
4349
4331 /* sanity checks */4350 /* sanity checks */
4332 mutex_lock(&wq->mutex);4351 mutex_lock(&wq->mutex);
4333 for_each_pwq(pwq, wq) {4352 for_each_pwq(pwq, wq) {
@@ -4359,11 +4378,6 @@ void destroy_workqueue(struct workqueue_struct *wq) · 25 unmodified lines
4359 list_del_rcu(&wq->list);4378 list_del_rcu(&wq->list);
4360 mutex_unlock(&wq_pool_mutex);4379 mutex_unlock(&wq_pool_mutex);
4361 4380
4362 workqueue_sysfs_unregister(wq);
4363
4364 if (wq->rescuer)
4365 kthread_stop(wq->rescuer->task);
4366
4367 if (!(wq->flags & WQ_UNBOUND)) {4381 if (!(wq->flags & WQ_UNBOUND)) {
4368 wq_unregister_lockdep(wq);4382 wq_unregister_lockdep(wq);
4369 /*4383 /*