@@ -248,7 +248,7 @@ struct workqueue_struct {
248248 struct list_head flusher_overflow ; /* WQ: flush overflow list */
249249
250250 struct list_head maydays ; /* MD: pwqs requesting rescue */
251- struct worker * rescuer ; /* I : rescue worker */
251+ struct worker * rescuer ; /* MD : rescue worker */
252252
253253 int nr_drainers ; /* WQ: drain in progress */
254254 int saved_max_active ; /* WQ: saved pwq max_active */
@@ -355,6 +355,7 @@ EXPORT_SYMBOL_GPL(system_freezable_power_efficient_wq);
355355
356356static int worker_thread (void * __worker );
357357static void workqueue_sysfs_unregister (struct workqueue_struct * wq );
358+ static void show_pwq (struct pool_workqueue * pwq );
358359
359360#define CREATE_TRACE_POINTS
360361#include <trace/events/workqueue.h>
@@ -425,7 +426,8 @@ static void workqueue_sysfs_unregister(struct workqueue_struct *wq);
425426 * ignored.
426427 */
427428#define for_each_pwq (pwq , wq ) \
428- list_for_each_entry_rcu((pwq), &(wq)->pwqs, pwqs_node) \
429+ list_for_each_entry_rcu((pwq), &(wq)->pwqs, pwqs_node, \
430+ lockdep_is_held(&wq->mutex)) \
429431 if (({ assert_rcu_or_wq_mutex(wq); false; })) { } \
430432 else
431433
@@ -2532,8 +2534,14 @@ static int rescuer_thread(void *__rescuer)
25322534 */
25332535 if (need_to_create_worker (pool )) {
25342536 spin_lock (& wq_mayday_lock );
2535- get_pwq (pwq );
2536- list_move_tail (& pwq -> mayday_node , & wq -> maydays );
2537+ /*
2538+ * Queue iff we aren't racing destruction
2539+ * and somebody else hasn't queued it already.
2540+ */
2541+ if (wq -> rescuer && list_empty (& pwq -> mayday_node )) {
2542+ get_pwq (pwq );
2543+ list_add_tail (& pwq -> mayday_node , & wq -> maydays );
2544+ }
25372545 spin_unlock (& wq_mayday_lock );
25382546 }
25392547 }
@@ -4314,6 +4322,22 @@ struct workqueue_struct *alloc_workqueue(const char *fmt,
43144322}
43154323EXPORT_SYMBOL_GPL (alloc_workqueue );
43164324
4325+ static bool pwq_busy (struct pool_workqueue * pwq )
4326+ {
4327+ int i ;
4328+
4329+ for (i = 0 ; i < WORK_NR_COLORS ; i ++ )
4330+ if (pwq -> nr_in_flight [i ])
4331+ return true;
4332+
4333+ if ((pwq != pwq -> wq -> dfl_pwq ) && (pwq -> refcnt > 1 ))
4334+ return true;
4335+ if (pwq -> nr_active || !list_empty (& pwq -> delayed_works ))
4336+ return true;
4337+
4338+ return false;
4339+ }
4340+
43174341/**
43184342 * destroy_workqueue - safely terminate a workqueue
43194343 * @wq: target workqueue
@@ -4325,31 +4349,51 @@ void destroy_workqueue(struct workqueue_struct *wq)
43254349 struct pool_workqueue * pwq ;
43264350 int node ;
43274351
4352+ /*
4353+ * Remove it from sysfs first so that sanity check failure doesn't
4354+ * lead to sysfs name conflicts.
4355+ */
4356+ workqueue_sysfs_unregister (wq );
4357+
43284358 /* drain it before proceeding with destruction */
43294359 drain_workqueue (wq );
43304360
4331- /* sanity checks */
4332- mutex_lock (& wq -> mutex );
4333- for_each_pwq (pwq , wq ) {
4334- int i ;
4361+ /* kill rescuer, if sanity checks fail, leave it w/o rescuer */
4362+ if (wq -> rescuer ) {
4363+ struct worker * rescuer = wq -> rescuer ;
43354364
4336- for (i = 0 ; i < WORK_NR_COLORS ; i ++ ) {
4337- if (WARN_ON (pwq -> nr_in_flight [i ])) {
4338- mutex_unlock (& wq -> mutex );
4339- show_workqueue_state ();
4340- return ;
4341- }
4342- }
4365+ /* this prevents new queueing */
4366+ spin_lock_irq (& wq_mayday_lock );
4367+ wq -> rescuer = NULL ;
4368+ spin_unlock_irq (& wq_mayday_lock );
4369+
4370+ /* rescuer will empty maydays list before exiting */
4371+ kthread_stop (rescuer -> task );
4372+ kfree (rescuer );
4373+ }
43434374
4344- if (WARN_ON ((pwq != wq -> dfl_pwq ) && (pwq -> refcnt > 1 )) ||
4345- WARN_ON (pwq -> nr_active ) ||
4346- WARN_ON (!list_empty (& pwq -> delayed_works ))) {
4375+ /*
4376+ * Sanity checks - grab all the locks so that we wait for all
4377+ * in-flight operations which may do put_pwq().
4378+ */
4379+ mutex_lock (& wq_pool_mutex );
4380+ mutex_lock (& wq -> mutex );
4381+ for_each_pwq (pwq , wq ) {
4382+ spin_lock_irq (& pwq -> pool -> lock );
4383+ if (WARN_ON (pwq_busy (pwq ))) {
4384+ pr_warning ("%s: %s has the following busy pwq\n" ,
4385+ __func__ , wq -> name );
4386+ show_pwq (pwq );
4387+ spin_unlock_irq (& pwq -> pool -> lock );
43474388 mutex_unlock (& wq -> mutex );
4389+ mutex_unlock (& wq_pool_mutex );
43484390 show_workqueue_state ();
43494391 return ;
43504392 }
4393+ spin_unlock_irq (& pwq -> pool -> lock );
43514394 }
43524395 mutex_unlock (& wq -> mutex );
4396+ mutex_unlock (& wq_pool_mutex );
43534397
43544398 /*
43554399 * wq list is used to freeze wq, remove from list after
@@ -4359,11 +4403,6 @@ void destroy_workqueue(struct workqueue_struct *wq)
43594403 list_del_rcu (& wq -> list );
43604404 mutex_unlock (& wq_pool_mutex );
43614405
4362- workqueue_sysfs_unregister (wq );
4363-
4364- if (wq -> rescuer )
4365- kthread_stop (wq -> rescuer -> task );
4366-
43674406 if (!(wq -> flags & WQ_UNBOUND )) {
43684407 wq_unregister_lockdep (wq );
43694408 /*
@@ -4638,7 +4677,8 @@ static void show_pwq(struct pool_workqueue *pwq)
46384677 pr_info (" pwq %d:" , pool -> id );
46394678 pr_cont_pool_info (pool );
46404679
4641- pr_cont (" active=%d/%d%s\n" , pwq -> nr_active , pwq -> max_active ,
4680+ pr_cont (" active=%d/%d refcnt=%d%s\n" ,
4681+ pwq -> nr_active , pwq -> max_active , pwq -> refcnt ,
46424682 !list_empty (& pwq -> mayday_node ) ? " MAYDAY" : "" );
46434683
46444684 hash_for_each (pool -> busy_hash , bkt , worker , hentry ) {
@@ -4657,7 +4697,7 @@ static void show_pwq(struct pool_workqueue *pwq)
46574697
46584698 pr_cont ("%s %d%s:%ps" , comma ? "," : "" ,
46594699 task_pid_nr (worker -> task ),
4660- worker == pwq -> wq -> rescuer ? "(RESCUER)" : "" ,
4700+ worker -> rescue_wq ? "(RESCUER)" : "" ,
46614701 worker -> current_func );
46624702 list_for_each_entry (work , & worker -> scheduled , entry )
46634703 pr_cont_work (false, work );
0 commit comments