diff options
author | Tejun Heo <tj@kernel.org> | 2012-07-12 17:46:37 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2012-07-12 17:46:37 -0400 |
commit | 11ebea50dbc1ade5994b2c838a096078d4c02399 (patch) | |
tree | c0553ac78d52512ee1c2dfe65049554898dd6638 /kernel/workqueue.c | |
parent | 63d95a9150ee3bbd4117fcd609dee40313b454d9 (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.c | 47 |
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 | ||
47 | enum { | 47 | enum { |
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 | ||
143 | struct worker_pool { | 145 | struct 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) | |||
583 | static bool __need_more_worker(struct worker_pool *pool) | 586 | static 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) | |||
625 | static bool need_to_manage_workers(struct worker_pool *pool) | 628 | static 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? */ |
632 | static bool too_many_workers(struct worker_pool *pool) | 635 | static 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; |