aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/workqueue.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2012-07-12 17:46:37 -0400
committerTejun Heo <tj@kernel.org>2012-07-12 17:46:37 -0400
commit11ebea50dbc1ade5994b2c838a096078d4c02399 (patch)
treec0553ac78d52512ee1c2dfe65049554898dd6638 /kernel/workqueue.c
parent63d95a9150ee3bbd4117fcd609dee40313b454d9 (diff)
workqueue: separate out worker_pool flags
GCWQ_MANAGE_WORKERS, GCWQ_MANAGING_WORKERS and GCWQ_HIGHPRI_PENDING are per-pool properties. Add worker_pool->flags and make the above three flags per-pool flags. The changes in this patch are mechanical and don't caues any functional difference. This is to prepare for multiple pools per gcwq. Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'kernel/workqueue.c')
-rw-r--r--kernel/workqueue.c47
1 files changed, 25 insertions, 22 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 2d82f7b193a0..7a98bae635fa 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -46,11 +46,13 @@
46 46
47enum { 47enum {
48 /* global_cwq flags */ 48 /* global_cwq flags */
49 GCWQ_MANAGE_WORKERS = 1 << 0, /* need to manage workers */ 49 GCWQ_DISASSOCIATED = 1 << 0, /* cpu can't serve workers */
50 GCWQ_MANAGING_WORKERS = 1 << 1, /* managing workers */ 50 GCWQ_FREEZING = 1 << 1, /* freeze in progress */
51 GCWQ_DISASSOCIATED = 1 << 2, /* cpu can't serve workers */ 51
52 GCWQ_FREEZING = 1 << 3, /* freeze in progress */ 52 /* pool flags */
53 GCWQ_HIGHPRI_PENDING = 1 << 4, /* highpri works on queue */ 53 POOL_MANAGE_WORKERS = 1 << 0, /* need to manage workers */
54 POOL_MANAGING_WORKERS = 1 << 1, /* managing workers */
55 POOL_HIGHPRI_PENDING = 1 << 2, /* highpri works on queue */
54 56
55 /* worker flags */ 57 /* worker flags */
56 WORKER_STARTED = 1 << 0, /* started */ 58 WORKER_STARTED = 1 << 0, /* started */
@@ -142,6 +144,7 @@ struct worker {
142 144
143struct worker_pool { 145struct worker_pool {
144 struct global_cwq *gcwq; /* I: the owning gcwq */ 146 struct global_cwq *gcwq; /* I: the owning gcwq */
147 unsigned int flags; /* X: flags */
145 148
146 struct list_head worklist; /* L: list of pending works */ 149 struct list_head worklist; /* L: list of pending works */
147 int nr_workers; /* L: total number of workers */ 150 int nr_workers; /* L: total number of workers */
@@ -583,7 +586,7 @@ static struct global_cwq *get_work_gcwq(struct work_struct *work)
583static bool __need_more_worker(struct worker_pool *pool) 586static bool __need_more_worker(struct worker_pool *pool)
584{ 587{
585 return !atomic_read(get_pool_nr_running(pool)) || 588 return !atomic_read(get_pool_nr_running(pool)) ||
586 pool->gcwq->flags & GCWQ_HIGHPRI_PENDING; 589 (pool->flags & POOL_HIGHPRI_PENDING);
587} 590}
588 591
589/* 592/*
@@ -612,7 +615,7 @@ static bool keep_working(struct worker_pool *pool)
612 615
613 return !list_empty(&pool->worklist) && 616 return !list_empty(&pool->worklist) &&
614 (atomic_read(nr_running) <= 1 || 617 (atomic_read(nr_running) <= 1 ||
615 pool->gcwq->flags & GCWQ_HIGHPRI_PENDING); 618 (pool->flags & POOL_HIGHPRI_PENDING));
616} 619}
617 620
618/* Do we need a new worker? Called from manager. */ 621/* Do we need a new worker? Called from manager. */
@@ -625,13 +628,13 @@ static bool need_to_create_worker(struct worker_pool *pool)
625static bool need_to_manage_workers(struct worker_pool *pool) 628static bool need_to_manage_workers(struct worker_pool *pool)
626{ 629{
627 return need_to_create_worker(pool) || 630 return need_to_create_worker(pool) ||
628 pool->gcwq->flags & GCWQ_MANAGE_WORKERS; 631 (pool->flags & POOL_MANAGE_WORKERS);
629} 632}
630 633
631/* Do we have too many workers and should some go away? */ 634/* Do we have too many workers and should some go away? */
632static bool too_many_workers(struct worker_pool *pool) 635static bool too_many_workers(struct worker_pool *pool)
633{ 636{
634 bool managing = pool->gcwq->flags & GCWQ_MANAGING_WORKERS; 637 bool managing = pool->flags & POOL_MANAGING_WORKERS;
635 int nr_idle = pool->nr_idle + managing; /* manager is considered idle */ 638 int nr_idle = pool->nr_idle + managing; /* manager is considered idle */
636 int nr_busy = pool->nr_workers - nr_idle; 639 int nr_busy = pool->nr_workers - nr_idle;
637 640
@@ -889,7 +892,7 @@ static struct worker *find_worker_executing_work(struct global_cwq *gcwq,
889 * position for the work. If @cwq is for HIGHPRI wq, the work is 892 * position for the work. If @cwq is for HIGHPRI wq, the work is
890 * queued at the head of the queue but in FIFO order with respect to 893 * queued at the head of the queue but in FIFO order with respect to
891 * other HIGHPRI works; otherwise, at the end of the queue. This 894 * other HIGHPRI works; otherwise, at the end of the queue. This
892 * function also sets GCWQ_HIGHPRI_PENDING flag to hint @pool that 895 * function also sets POOL_HIGHPRI_PENDING flag to hint @pool that
893 * there are HIGHPRI works pending. 896 * there are HIGHPRI works pending.
894 * 897 *
895 * CONTEXT: 898 * CONTEXT:
@@ -913,7 +916,7 @@ static inline struct list_head *pool_determine_ins_pos(struct worker_pool *pool,
913 break; 916 break;
914 } 917 }
915 918
916 pool->gcwq->flags |= GCWQ_HIGHPRI_PENDING; 919 pool->flags |= POOL_HIGHPRI_PENDING;
917 return &twork->entry; 920 return &twork->entry;
918} 921}
919 922
@@ -1500,7 +1503,7 @@ static void idle_worker_timeout(unsigned long __pool)
1500 mod_timer(&pool->idle_timer, expires); 1503 mod_timer(&pool->idle_timer, expires);
1501 else { 1504 else {
1502 /* it's been idle for too long, wake up manager */ 1505 /* it's been idle for too long, wake up manager */
1503 gcwq->flags |= GCWQ_MANAGE_WORKERS; 1506 pool->flags |= POOL_MANAGE_WORKERS;
1504 wake_up_worker(pool); 1507 wake_up_worker(pool);
1505 } 1508 }
1506 } 1509 }
@@ -1680,11 +1683,11 @@ static bool manage_workers(struct worker *worker)
1680 struct global_cwq *gcwq = pool->gcwq; 1683 struct global_cwq *gcwq = pool->gcwq;
1681 bool ret = false; 1684 bool ret = false;
1682 1685
1683 if (gcwq->flags & GCWQ_MANAGING_WORKERS) 1686 if (pool->flags & POOL_MANAGING_WORKERS)
1684 return ret; 1687 return ret;
1685 1688
1686 gcwq->flags &= ~GCWQ_MANAGE_WORKERS; 1689 pool->flags &= ~POOL_MANAGE_WORKERS;
1687 gcwq->flags |= GCWQ_MANAGING_WORKERS; 1690 pool->flags |= POOL_MANAGING_WORKERS;
1688 1691
1689 /* 1692 /*
1690 * Destroy and then create so that may_start_working() is true 1693 * Destroy and then create so that may_start_working() is true
@@ -1693,7 +1696,7 @@ static bool manage_workers(struct worker *worker)
1693 ret |= maybe_destroy_workers(pool); 1696 ret |= maybe_destroy_workers(pool);
1694 ret |= maybe_create_worker(pool); 1697 ret |= maybe_create_worker(pool);
1695 1698
1696 gcwq->flags &= ~GCWQ_MANAGING_WORKERS; 1699 pool->flags &= ~POOL_MANAGING_WORKERS;
1697 1700
1698 /* 1701 /*
1699 * The trustee might be waiting to take over the manager 1702 * The trustee might be waiting to take over the manager
@@ -1872,7 +1875,7 @@ __acquires(&gcwq->lock)
1872 * If HIGHPRI_PENDING, check the next work, and, if HIGHPRI, 1875 * If HIGHPRI_PENDING, check the next work, and, if HIGHPRI,
1873 * wake up another worker; otherwise, clear HIGHPRI_PENDING. 1876 * wake up another worker; otherwise, clear HIGHPRI_PENDING.
1874 */ 1877 */
1875 if (unlikely(gcwq->flags & GCWQ_HIGHPRI_PENDING)) { 1878 if (unlikely(pool->flags & POOL_HIGHPRI_PENDING)) {
1876 struct work_struct *nwork = list_first_entry(&pool->worklist, 1879 struct work_struct *nwork = list_first_entry(&pool->worklist,
1877 struct work_struct, entry); 1880 struct work_struct, entry);
1878 1881
@@ -1880,7 +1883,7 @@ __acquires(&gcwq->lock)
1880 get_work_cwq(nwork)->wq->flags & WQ_HIGHPRI) 1883 get_work_cwq(nwork)->wq->flags & WQ_HIGHPRI)
1881 wake_up_worker(pool); 1884 wake_up_worker(pool);
1882 else 1885 else
1883 gcwq->flags &= ~GCWQ_HIGHPRI_PENDING; 1886 pool->flags &= ~POOL_HIGHPRI_PENDING;
1884 } 1887 }
1885 1888
1886 /* 1889 /*
@@ -3360,10 +3363,10 @@ static int __cpuinit trustee_thread(void *__gcwq)
3360 * cancelled. 3363 * cancelled.
3361 */ 3364 */
3362 BUG_ON(gcwq->cpu != smp_processor_id()); 3365 BUG_ON(gcwq->cpu != smp_processor_id());
3363 rc = trustee_wait_event(!(gcwq->flags & GCWQ_MANAGING_WORKERS)); 3366 rc = trustee_wait_event(!(gcwq->pool.flags & POOL_MANAGING_WORKERS));
3364 BUG_ON(rc < 0); 3367 BUG_ON(rc < 0);
3365 3368
3366 gcwq->flags |= GCWQ_MANAGING_WORKERS; 3369 gcwq->pool.flags |= POOL_MANAGING_WORKERS;
3367 3370
3368 list_for_each_entry(worker, &gcwq->pool.idle_list, entry) 3371 list_for_each_entry(worker, &gcwq->pool.idle_list, entry)
3369 worker->flags |= WORKER_ROGUE; 3372 worker->flags |= WORKER_ROGUE;
@@ -3487,7 +3490,7 @@ static int __cpuinit trustee_thread(void *__gcwq)
3487 } 3490 }
3488 3491
3489 /* relinquish manager role */ 3492 /* relinquish manager role */
3490 gcwq->flags &= ~GCWQ_MANAGING_WORKERS; 3493 gcwq->pool.flags &= ~POOL_MANAGING_WORKERS;
3491 3494
3492 /* notify completion */ 3495 /* notify completion */
3493 gcwq->trustee = NULL; 3496 gcwq->trustee = NULL;
@@ -3604,7 +3607,7 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb,
3604 spin_unlock_irq(&gcwq->lock); 3607 spin_unlock_irq(&gcwq->lock);
3605 kthread_bind(gcwq->pool.first_idle->task, cpu); 3608 kthread_bind(gcwq->pool.first_idle->task, cpu);
3606 spin_lock_irq(&gcwq->lock); 3609 spin_lock_irq(&gcwq->lock);
3607 gcwq->flags |= GCWQ_MANAGE_WORKERS; 3610 gcwq->pool.flags |= POOL_MANAGE_WORKERS;
3608 start_worker(gcwq->pool.first_idle); 3611 start_worker(gcwq->pool.first_idle);
3609 gcwq->pool.first_idle = NULL; 3612 gcwq->pool.first_idle = NULL;
3610 break; 3613 break;