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.
Showing the changes to kernel/workqueue.c (1 of 1 file). Show all
Unified · Split
| @@ -68,7 +68,6 @@ enum { · 67 unmodified lines | |||
| 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) · 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? */ | ||
| 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) · 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 | */ | ||
| 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 | /** | 1994 | /** |
| 2042 | * manage_workers - manage worker pool | 1995 | * manage_workers - manage worker pool |
| 2043 | * @worker: self | 1996 | * @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); |
| 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 |