aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLai Jiangshan <laijs@cn.fujitsu.com>2014-05-20 05:46:30 -0400
committerTejun Heo <tj@kernel.org>2014-05-20 10:59:31 -0400
commit3347fc9f36e7e5d3ebe504fc4034745b5d8971d3 (patch)
treeb34e2b7870748208668f7cef162d9d8f489ced55
parent60f5a4bcf852b5dec698b08cd34efc302ea72f2b (diff)
workqueue: destroy worker directly in the idle timeout handler
Since destroy_worker() doesn't need to sleep nor require manager_mutex, destroy_worker() can be directly called in the idle timeout handler, it helps us remove POOL_MANAGE_WORKERS and maybe_destroy_worker() and simplify the manage_workers() After POOL_MANAGE_WORKERS is removed, worker_thread() doesn't need to test whether it needs to manage after processed works. So we can remove the test branch. Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
-rw-r--r--kernel/workqueue.c67
1 files changed, 5 insertions, 62 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index c458d73022bb..938836bc6207 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -68,7 +68,6 @@ enum {
68 * manager_mutex to avoid changing binding state while 68 * manager_mutex to avoid changing binding state while
69 * create_worker() is in progress. 69 * create_worker() is in progress.
70 */ 70 */
71 POOL_MANAGE_WORKERS = 1 << 0, /* need to manage workers */
72 POOL_DISASSOCIATED = 1 << 2, /* cpu can't serve workers */ 71 POOL_DISASSOCIATED = 1 << 2, /* cpu can't serve workers */
73 POOL_FREEZING = 1 << 3, /* freeze in progress */ 72 POOL_FREEZING = 1 << 3, /* freeze in progress */
74 73
@@ -752,13 +751,6 @@ static bool need_to_create_worker(struct worker_pool *pool)
752 return need_more_worker(pool) && !may_start_working(pool); 751 return need_more_worker(pool) && !may_start_working(pool);
753} 752}
754 753
755/* Do I need to be the manager? */
756static bool need_to_manage_workers(struct worker_pool *pool)
757{
758 return need_to_create_worker(pool) ||
759 (pool->flags & POOL_MANAGE_WORKERS);
760}
761
762/* Do we have too many workers and should some go away? */ 754/* Do we have too many workers and should some go away? */
763static bool too_many_workers(struct worker_pool *pool) 755static bool too_many_workers(struct worker_pool *pool)
764{ 756{
@@ -1868,7 +1860,7 @@ static void idle_worker_timeout(unsigned long __pool)
1868 1860
1869 spin_lock_irq(&pool->lock); 1861 spin_lock_irq(&pool->lock);
1870 1862
1871 if (too_many_workers(pool)) { 1863 while (too_many_workers(pool)) {
1872 struct worker *worker; 1864 struct worker *worker;
1873 unsigned long expires; 1865 unsigned long expires;
1874 1866
@@ -1876,13 +1868,12 @@ static void idle_worker_timeout(unsigned long __pool)
1876 worker = list_entry(pool->idle_list.prev, struct worker, entry); 1868 worker = list_entry(pool->idle_list.prev, struct worker, entry);
1877 expires = worker->last_active + IDLE_WORKER_TIMEOUT; 1869 expires = worker->last_active + IDLE_WORKER_TIMEOUT;
1878 1870
1879 if (time_before(jiffies, expires)) 1871 if (time_before(jiffies, expires)) {
1880 mod_timer(&pool->idle_timer, expires); 1872 mod_timer(&pool->idle_timer, expires);
1881 else { 1873 break;
1882 /* it's been idle for too long, wake up manager */
1883 pool->flags |= POOL_MANAGE_WORKERS;
1884 wake_up_worker(pool);
1885 } 1874 }
1875
1876 destroy_worker(worker);
1886 } 1877 }
1887 1878
1888 spin_unlock_irq(&pool->lock); 1879 spin_unlock_irq(&pool->lock);
@@ -2001,44 +1992,6 @@ restart:
2001} 1992}
2002 1993
2003/** 1994/**
2004 * maybe_destroy_worker - destroy workers which have been idle for a while
2005 * @pool: pool to destroy workers for
2006 *
2007 * Destroy @pool workers which have been idle for longer than
2008 * IDLE_WORKER_TIMEOUT.
2009 *
2010 * LOCKING:
2011 * spin_lock_irq(pool->lock) which may be released and regrabbed
2012 * multiple times. Called only from manager.
2013 *
2014 * Return:
2015 * %false if no action was taken and pool->lock stayed locked, %true
2016 * otherwise.
2017 */
2018static bool maybe_destroy_workers(struct worker_pool *pool)
2019{
2020 bool ret = false;
2021
2022 while (too_many_workers(pool)) {
2023 struct worker *worker;
2024 unsigned long expires;
2025
2026 worker = list_entry(pool->idle_list.prev, struct worker, entry);
2027 expires = worker->last_active + IDLE_WORKER_TIMEOUT;
2028
2029 if (time_before(jiffies, expires)) {
2030 mod_timer(&pool->idle_timer, expires);
2031 break;
2032 }
2033
2034 destroy_worker(worker);
2035 ret = true;
2036 }
2037
2038 return ret;
2039}
2040
2041/**
2042 * manage_workers - manage worker pool 1995 * manage_workers - manage worker pool
2043 * @worker: self 1996 * @worker: self
2044 * 1997 *
@@ -2101,13 +2054,6 @@ static bool manage_workers(struct worker *worker)
2101 ret = true; 2054 ret = true;
2102 } 2055 }
2103 2056
2104 pool->flags &= ~POOL_MANAGE_WORKERS;
2105
2106 /*
2107 * Destroy and then create so that may_start_working() is true
2108 * on return.
2109 */
2110 ret |= maybe_destroy_workers(pool);
2111 ret |= maybe_create_worker(pool); 2057 ret |= maybe_create_worker(pool);
2112 2058
2113 mutex_unlock(&pool->manager_mutex); 2059 mutex_unlock(&pool->manager_mutex);
@@ -2349,9 +2295,6 @@ recheck:
2349 2295
2350 worker_set_flags(worker, WORKER_PREP, false); 2296 worker_set_flags(worker, WORKER_PREP, false);
2351sleep: 2297sleep:
2352 if (unlikely(need_to_manage_workers(pool)) && manage_workers(worker))
2353 goto recheck;
2354
2355 /* 2298 /*
2356 * pool->lock is held and there's no work to process and no need to 2299 * pool->lock is held and there's no work to process and no need to
2357 * manage, sleep. Workers are woken up only while holding 2300 * manage, sleep. Workers are woken up only while holding