mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	workqueue: restore POOL_MANAGING_WORKERS
This patch restores POOL_MANAGING_WORKERS which was replaced by
pool->manager_mutex by 6037315269 "workqueue: use mutex for global_cwq
manager exclusion".
There's a subtle idle worker depletion bug across CPU hotplug events
and we need to distinguish an actual manager and CPU hotplug
preventing management.  POOL_MANAGING_WORKERS will be used for the
former and manager_mutex the later.
This patch just lays POOL_MANAGING_WORKERS on top of the existing
manager_mutex and doesn't introduce any synchronization changes.  The
next patch will update it.
Note that this patch fixes a non-critical anomaly where
too_many_workers() may return %true spuriously while CPU hotplug is in
progress.  While the issue could schedule idle timer spuriously, it
didn't trigger any actual misbehavior.
tj: Rewrote patch description.
Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
			
			
This commit is contained in:
		
							parent
							
								
									ec58815ab0
								
							
						
					
					
						commit
						552a37e936
					
				
					 1 changed files with 4 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -66,6 +66,7 @@ enum {
 | 
			
		|||
 | 
			
		||||
	/* pool flags */
 | 
			
		||||
	POOL_MANAGE_WORKERS	= 1 << 0,	/* need to manage workers */
 | 
			
		||||
	POOL_MANAGING_WORKERS   = 1 << 1,       /* managing workers */
 | 
			
		||||
 | 
			
		||||
	/* worker flags */
 | 
			
		||||
	WORKER_STARTED		= 1 << 0,	/* started */
 | 
			
		||||
| 
						 | 
				
			
			@ -652,7 +653,7 @@ static bool need_to_manage_workers(struct worker_pool *pool)
 | 
			
		|||
/* Do we have too many workers and should some go away? */
 | 
			
		||||
static bool too_many_workers(struct worker_pool *pool)
 | 
			
		||||
{
 | 
			
		||||
	bool managing = mutex_is_locked(&pool->manager_mutex);
 | 
			
		||||
	bool managing = pool->flags & POOL_MANAGING_WORKERS;
 | 
			
		||||
	int nr_idle = pool->nr_idle + managing; /* manager is considered idle */
 | 
			
		||||
	int nr_busy = pool->nr_workers - nr_idle;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1827,6 +1828,7 @@ static bool manage_workers(struct worker *worker)
 | 
			
		|||
	if (!mutex_trylock(&pool->manager_mutex))
 | 
			
		||||
		return ret;
 | 
			
		||||
 | 
			
		||||
	pool->flags |= POOL_MANAGING_WORKERS;
 | 
			
		||||
	pool->flags &= ~POOL_MANAGE_WORKERS;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
| 
						 | 
				
			
			@ -1836,6 +1838,7 @@ static bool manage_workers(struct worker *worker)
 | 
			
		|||
	ret |= maybe_destroy_workers(pool);
 | 
			
		||||
	ret |= maybe_create_worker(pool);
 | 
			
		||||
 | 
			
		||||
	pool->flags &= ~POOL_MANAGING_WORKERS;
 | 
			
		||||
	mutex_unlock(&pool->manager_mutex);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue