History

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.

Lai Jiangshan committed 12 years ago

Commit 3347fc91 parent 60f5a4b1 file · +5 −62Browse files

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

Unified · Split

kernel/workqueue.c+5−62
@@ -68,7 +68,6 @@ enum { · 67 unmodified lines
68 * manager_mutex to avoid changing binding state while68 * 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) · 677 unmodified lines
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) · 1103 unmodified lines
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) · 1 unmodified line
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);
@@ -2000,44 +1991,6 @@ restart: · 111 unmodified lines
2000 return true;1991 return true;
2001}1992}
2002 1993
2003/**
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/**1994/**
2042 * manage_workers - manage worker pool1995 * manage_workers - manage worker pool
2043 * @worker: self1996 * @worker: self
@@ -2101,13 +2054,6 @@ static bool manage_workers(struct worker *worker) · 57 unmodified lines
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: · 235 unmodified lines
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 to2299 * pool->lock is held and there's no work to process and no need to
2357 * manage, sleep. Workers are woken up only while holding2300 * manage, sleep. Workers are woken up only while holding