diff options
author | Lai Jiangshan <laijs@cn.fujitsu.com> | 2014-05-20 05:46:30 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2014-05-20 10:59:31 -0400 |
commit | 3347fc9f36e7e5d3ebe504fc4034745b5d8971d3 (patch) | |
tree | b34e2b7870748208668f7cef162d9d8f489ced55 | |
parent | 60f5a4bcf852b5dec698b08cd34efc302ea72f2b (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.c | 67 |
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? */ | ||
756 | static 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? */ |
763 | static bool too_many_workers(struct worker_pool *pool) | 755 | static 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 | */ | ||
2018 | static 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); |
2351 | sleep: | 2297 | sleep: |
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 |