68
68
* attach_mutex to avoid changing binding state while
69
69
* worker_attach_to_pool() is in progress.
70
70
*/
71
+ POOL_MANAGER_ACTIVE = 1 << 0 , /* being managed */
71
72
POOL_DISASSOCIATED = 1 << 2 , /* cpu can't serve workers */
72
73
73
74
/* worker flags */
@@ -165,7 +166,6 @@ struct worker_pool {
165
166
/* L: hash of busy workers */
166
167
167
168
/* see manage_workers() for details on the two manager mutexes */
168
- struct mutex manager_arb ; /* manager arbitration */
169
169
struct worker * manager ; /* L: purely informational */
170
170
struct mutex attach_mutex ; /* attach/detach exclusion */
171
171
struct list_head workers ; /* A: attached workers */
@@ -299,6 +299,7 @@ static struct workqueue_attrs *wq_update_unbound_numa_attrs_buf;
299
299
300
300
static DEFINE_MUTEX (wq_pool_mutex ); /* protects pools and workqueues list */
301
301
static DEFINE_SPINLOCK (wq_mayday_lock ); /* protects wq->maydays list */
302
+ static DECLARE_WAIT_QUEUE_HEAD (wq_manager_wait ); /* wait for manager to go away */
302
303
303
304
static LIST_HEAD (workqueues ); /* PR: list of all workqueues */
304
305
static bool workqueue_freezing ; /* PL: have wqs started freezing? */
@@ -801,7 +802,7 @@ static bool need_to_create_worker(struct worker_pool *pool)
801
802
/* Do we have too many workers and should some go away? */
802
803
static bool too_many_workers (struct worker_pool * pool )
803
804
{
804
- bool managing = mutex_is_locked ( & pool -> manager_arb ) ;
805
+ bool managing = pool -> flags & POOL_MANAGER_ACTIVE ;
805
806
int nr_idle = pool -> nr_idle + managing ; /* manager is considered idle */
806
807
int nr_busy = pool -> nr_workers - nr_idle ;
807
808
@@ -1980,24 +1981,17 @@ static bool manage_workers(struct worker *worker)
1980
1981
{
1981
1982
struct worker_pool * pool = worker -> pool ;
1982
1983
1983
- /*
1984
- * Anyone who successfully grabs manager_arb wins the arbitration
1985
- * and becomes the manager. mutex_trylock() on pool->manager_arb
1986
- * failure while holding pool->lock reliably indicates that someone
1987
- * else is managing the pool and the worker which failed trylock
1988
- * can proceed to executing work items. This means that anyone
1989
- * grabbing manager_arb is responsible for actually performing
1990
- * manager duties. If manager_arb is grabbed and released without
1991
- * actual management, the pool may stall indefinitely.
1992
- */
1993
- if (!mutex_trylock (& pool -> manager_arb ))
1984
+ if (pool -> flags & POOL_MANAGER_ACTIVE )
1994
1985
return false;
1986
+
1987
+ pool -> flags |= POOL_MANAGER_ACTIVE ;
1995
1988
pool -> manager = worker ;
1996
1989
1997
1990
maybe_create_worker (pool );
1998
1991
1999
1992
pool -> manager = NULL ;
2000
- mutex_unlock (& pool -> manager_arb );
1993
+ pool -> flags &= ~POOL_MANAGER_ACTIVE ;
1994
+ wake_up (& wq_manager_wait );
2001
1995
return true;
2002
1996
}
2003
1997
@@ -3248,7 +3242,6 @@ static int init_worker_pool(struct worker_pool *pool)
3248
3242
setup_timer (& pool -> mayday_timer , pool_mayday_timeout ,
3249
3243
(unsigned long )pool );
3250
3244
3251
- mutex_init (& pool -> manager_arb );
3252
3245
mutex_init (& pool -> attach_mutex );
3253
3246
INIT_LIST_HEAD (& pool -> workers );
3254
3247
@@ -3318,13 +3311,15 @@ static void put_unbound_pool(struct worker_pool *pool)
3318
3311
hash_del (& pool -> hash_node );
3319
3312
3320
3313
/*
3321
- * Become the manager and destroy all workers. Grabbing
3322
- * manager_arb prevents @pool's workers from blocking on
3323
- * attach_mutex .
3314
+ * Become the manager and destroy all workers. This prevents
3315
+ * @pool's workers from blocking on attach_mutex. We're the last
3316
+ * manager and @pool gets freed with the flag set .
3324
3317
*/
3325
- mutex_lock (& pool -> manager_arb );
3326
-
3327
3318
spin_lock_irq (& pool -> lock );
3319
+ wait_event_lock_irq (wq_manager_wait ,
3320
+ !(pool -> flags & POOL_MANAGER_ACTIVE ), pool -> lock );
3321
+ pool -> flags |= POOL_MANAGER_ACTIVE ;
3322
+
3328
3323
while ((worker = first_idle_worker (pool )))
3329
3324
destroy_worker (worker );
3330
3325
WARN_ON (pool -> nr_workers || pool -> nr_idle );
@@ -3338,8 +3333,6 @@ static void put_unbound_pool(struct worker_pool *pool)
3338
3333
if (pool -> detach_completion )
3339
3334
wait_for_completion (pool -> detach_completion );
3340
3335
3341
- mutex_unlock (& pool -> manager_arb );
3342
-
3343
3336
/* shut down the timers */
3344
3337
del_timer_sync (& pool -> idle_timer );
3345
3338
del_timer_sync (& pool -> mayday_timer );
0 commit comments