History

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.

Lai Jiangshan committed 14 years ago

Commit 552a37e1 parent ec588151 file · +4 −1Browse files

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

Unified · Split

kernel/workqueue.c+4−1
@@ -66,6 +66,7 @@ enum { · 65 unmodified lines
6666
6767 /* pool flags */
6868 POOL_MANAGE_WORKERS = 1 << 0, /* need to manage workers */
69+ POOL_MANAGING_WORKERS = 1 << 1, /* managing workers */
6970
7071 /* worker flags */
7172 WORKER_STARTED = 1 << 0, /* started */
@@ -652,7 +653,7 @@ static bool need_to_manage_workers(struct worker_pool *pool) · 580 unmodified lines
652653 /* Do we have too many workers and should some go away? */
653654 static bool too_many_workers(struct worker_pool *pool)
654655 {
655− bool managing = mutex_is_locked(&pool->manager_mutex);
656+ bool managing = pool->flags & POOL_MANAGING_WORKERS;
656657 int nr_idle = pool->nr_idle + managing; /* manager is considered idle */
657658 int nr_busy = pool->nr_workers - nr_idle;
658659
@@ -1827,6 +1828,7 @@ static bool manage_workers(struct worker *worker) · 1168 unmodified lines
18271828 if (!mutex_trylock(&pool->manager_mutex))
18281829 return ret;
18291830
1831+ pool->flags |= POOL_MANAGING_WORKERS;
18301832 pool->flags &= ~POOL_MANAGE_WORKERS;
18311833
18321834 /*
@@ -1836,6 +1838,7 @@ static bool manage_workers(struct worker *worker) · 3 unmodified lines
18361838 ret |= maybe_destroy_workers(pool);
18371839 ret |= maybe_create_worker(pool);
18381840
1841+ pool->flags &= ~POOL_MANAGING_WORKERS;
18391842 mutex_unlock(&pool->manager_mutex);
18401843 return ret;
18411844 }