diff options
| -rw-r--r-- | include/trace/events/workqueue.h | 2 | ||||
| -rw-r--r-- | kernel/workqueue.c | 216 |
2 files changed, 118 insertions, 100 deletions
diff --git a/include/trace/events/workqueue.h b/include/trace/events/workqueue.h index 4018f5058f27..f28d1b65f178 100644 --- a/include/trace/events/workqueue.h +++ b/include/trace/events/workqueue.h | |||
| @@ -54,7 +54,7 @@ TRACE_EVENT(workqueue_queue_work, | |||
| 54 | __entry->function = work->func; | 54 | __entry->function = work->func; |
| 55 | __entry->workqueue = cwq->wq; | 55 | __entry->workqueue = cwq->wq; |
| 56 | __entry->req_cpu = req_cpu; | 56 | __entry->req_cpu = req_cpu; |
| 57 | __entry->cpu = cwq->gcwq->cpu; | 57 | __entry->cpu = cwq->pool->gcwq->cpu; |
| 58 | ), | 58 | ), |
| 59 | 59 | ||
| 60 | TP_printk("work struct=%p function=%pf workqueue=%p req_cpu=%u cpu=%u", | 60 | TP_printk("work struct=%p function=%pf workqueue=%p req_cpu=%u cpu=%u", |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 27637c284cb9..61f154467026 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
| @@ -115,6 +115,7 @@ enum { | |||
| 115 | */ | 115 | */ |
| 116 | 116 | ||
| 117 | struct global_cwq; | 117 | struct global_cwq; |
| 118 | struct worker_pool; | ||
| 118 | 119 | ||
| 119 | /* | 120 | /* |
| 120 | * The poor guys doing the actual heavy lifting. All on-duty workers | 121 | * The poor guys doing the actual heavy lifting. All on-duty workers |
| @@ -131,7 +132,7 @@ struct worker { | |||
| 131 | struct cpu_workqueue_struct *current_cwq; /* L: current_work's cwq */ | 132 | struct cpu_workqueue_struct *current_cwq; /* L: current_work's cwq */ |
| 132 | struct list_head scheduled; /* L: scheduled works */ | 133 | struct list_head scheduled; /* L: scheduled works */ |
| 133 | struct task_struct *task; /* I: worker task */ | 134 | struct task_struct *task; /* I: worker task */ |
| 134 | struct global_cwq *gcwq; /* I: the associated gcwq */ | 135 | struct worker_pool *pool; /* I: the associated pool */ |
| 135 | /* 64 bytes boundary on 64bit, 32 on 32bit */ | 136 | /* 64 bytes boundary on 64bit, 32 on 32bit */ |
| 136 | unsigned long last_active; /* L: last active timestamp */ | 137 | unsigned long last_active; /* L: last active timestamp */ |
| 137 | unsigned int flags; /* X: flags */ | 138 | unsigned int flags; /* X: flags */ |
| @@ -139,6 +140,21 @@ struct worker { | |||
| 139 | struct work_struct rebind_work; /* L: rebind worker to cpu */ | 140 | struct work_struct rebind_work; /* L: rebind worker to cpu */ |
| 140 | }; | 141 | }; |
| 141 | 142 | ||
| 143 | struct worker_pool { | ||
| 144 | struct global_cwq *gcwq; /* I: the owning gcwq */ | ||
| 145 | |||
| 146 | struct list_head worklist; /* L: list of pending works */ | ||
| 147 | int nr_workers; /* L: total number of workers */ | ||
| 148 | int nr_idle; /* L: currently idle ones */ | ||
| 149 | |||
| 150 | struct list_head idle_list; /* X: list of idle workers */ | ||
| 151 | struct timer_list idle_timer; /* L: worker idle timeout */ | ||
| 152 | struct timer_list mayday_timer; /* L: SOS timer for workers */ | ||
| 153 | |||
| 154 | struct ida worker_ida; /* L: for worker IDs */ | ||
| 155 | struct worker *first_idle; /* L: first idle worker */ | ||
| 156 | }; | ||
| 157 | |||
| 142 | /* | 158 | /* |
| 143 | * Global per-cpu workqueue. There's one and only one for each cpu | 159 | * Global per-cpu workqueue. There's one and only one for each cpu |
| 144 | * and all works are queued and processed here regardless of their | 160 | * and all works are queued and processed here regardless of their |
| @@ -146,27 +162,18 @@ struct worker { | |||
| 146 | */ | 162 | */ |
| 147 | struct global_cwq { | 163 | struct global_cwq { |
| 148 | spinlock_t lock; /* the gcwq lock */ | 164 | spinlock_t lock; /* the gcwq lock */ |
| 149 | struct list_head worklist; /* L: list of pending works */ | ||
| 150 | unsigned int cpu; /* I: the associated cpu */ | 165 | unsigned int cpu; /* I: the associated cpu */ |
| 151 | unsigned int flags; /* L: GCWQ_* flags */ | 166 | unsigned int flags; /* L: GCWQ_* flags */ |
| 152 | 167 | ||
| 153 | int nr_workers; /* L: total number of workers */ | 168 | /* workers are chained either in busy_hash or pool idle_list */ |
| 154 | int nr_idle; /* L: currently idle ones */ | ||
| 155 | |||
| 156 | /* workers are chained either in the idle_list or busy_hash */ | ||
| 157 | struct list_head idle_list; /* X: list of idle workers */ | ||
| 158 | struct hlist_head busy_hash[BUSY_WORKER_HASH_SIZE]; | 169 | struct hlist_head busy_hash[BUSY_WORKER_HASH_SIZE]; |
| 159 | /* L: hash of busy workers */ | 170 | /* L: hash of busy workers */ |
| 160 | 171 | ||
| 161 | struct timer_list idle_timer; /* L: worker idle timeout */ | 172 | struct worker_pool pool; /* the worker pools */ |
| 162 | struct timer_list mayday_timer; /* L: SOS timer for dworkers */ | ||
| 163 | |||
| 164 | struct ida worker_ida; /* L: for worker IDs */ | ||
| 165 | 173 | ||
| 166 | struct task_struct *trustee; /* L: for gcwq shutdown */ | 174 | struct task_struct *trustee; /* L: for gcwq shutdown */ |
| 167 | unsigned int trustee_state; /* L: trustee state */ | 175 | unsigned int trustee_state; /* L: trustee state */ |
| 168 | wait_queue_head_t trustee_wait; /* trustee wait */ | 176 | wait_queue_head_t trustee_wait; /* trustee wait */ |
| 169 | struct worker *first_idle; /* L: first idle worker */ | ||
| 170 | } ____cacheline_aligned_in_smp; | 177 | } ____cacheline_aligned_in_smp; |
| 171 | 178 | ||
| 172 | /* | 179 | /* |
| @@ -175,7 +182,7 @@ struct global_cwq { | |||
| 175 | * aligned at two's power of the number of flag bits. | 182 | * aligned at two's power of the number of flag bits. |
| 176 | */ | 183 | */ |
| 177 | struct cpu_workqueue_struct { | 184 | struct cpu_workqueue_struct { |
| 178 | struct global_cwq *gcwq; /* I: the associated gcwq */ | 185 | struct worker_pool *pool; /* I: the associated pool */ |
| 179 | struct workqueue_struct *wq; /* I: the owning workqueue */ | 186 | struct workqueue_struct *wq; /* I: the owning workqueue */ |
| 180 | int work_color; /* L: current color */ | 187 | int work_color; /* L: current color */ |
| 181 | int flush_color; /* L: flushing color */ | 188 | int flush_color; /* L: flushing color */ |
| @@ -555,7 +562,7 @@ static struct global_cwq *get_work_gcwq(struct work_struct *work) | |||
| 555 | 562 | ||
| 556 | if (data & WORK_STRUCT_CWQ) | 563 | if (data & WORK_STRUCT_CWQ) |
| 557 | return ((struct cpu_workqueue_struct *) | 564 | return ((struct cpu_workqueue_struct *) |
| 558 | (data & WORK_STRUCT_WQ_DATA_MASK))->gcwq; | 565 | (data & WORK_STRUCT_WQ_DATA_MASK))->pool->gcwq; |
| 559 | 566 | ||
| 560 | cpu = data >> WORK_STRUCT_FLAG_BITS; | 567 | cpu = data >> WORK_STRUCT_FLAG_BITS; |
| 561 | if (cpu == WORK_CPU_NONE) | 568 | if (cpu == WORK_CPU_NONE) |
| @@ -587,13 +594,13 @@ static bool __need_more_worker(struct global_cwq *gcwq) | |||
| 587 | */ | 594 | */ |
| 588 | static bool need_more_worker(struct global_cwq *gcwq) | 595 | static bool need_more_worker(struct global_cwq *gcwq) |
| 589 | { | 596 | { |
| 590 | return !list_empty(&gcwq->worklist) && __need_more_worker(gcwq); | 597 | return !list_empty(&gcwq->pool.worklist) && __need_more_worker(gcwq); |
| 591 | } | 598 | } |
| 592 | 599 | ||
| 593 | /* Can I start working? Called from busy but !running workers. */ | 600 | /* Can I start working? Called from busy but !running workers. */ |
| 594 | static bool may_start_working(struct global_cwq *gcwq) | 601 | static bool may_start_working(struct global_cwq *gcwq) |
| 595 | { | 602 | { |
| 596 | return gcwq->nr_idle; | 603 | return gcwq->pool.nr_idle; |
| 597 | } | 604 | } |
| 598 | 605 | ||
| 599 | /* Do I need to keep working? Called from currently running workers. */ | 606 | /* Do I need to keep working? Called from currently running workers. */ |
| @@ -601,7 +608,7 @@ static bool keep_working(struct global_cwq *gcwq) | |||
| 601 | { | 608 | { |
| 602 | atomic_t *nr_running = get_gcwq_nr_running(gcwq->cpu); | 609 | atomic_t *nr_running = get_gcwq_nr_running(gcwq->cpu); |
| 603 | 610 | ||
| 604 | return !list_empty(&gcwq->worklist) && | 611 | return !list_empty(&gcwq->pool.worklist) && |
| 605 | (atomic_read(nr_running) <= 1 || | 612 | (atomic_read(nr_running) <= 1 || |
| 606 | gcwq->flags & GCWQ_HIGHPRI_PENDING); | 613 | gcwq->flags & GCWQ_HIGHPRI_PENDING); |
| 607 | } | 614 | } |
| @@ -622,8 +629,8 @@ static bool need_to_manage_workers(struct global_cwq *gcwq) | |||
| 622 | static bool too_many_workers(struct global_cwq *gcwq) | 629 | static bool too_many_workers(struct global_cwq *gcwq) |
| 623 | { | 630 | { |
| 624 | bool managing = gcwq->flags & GCWQ_MANAGING_WORKERS; | 631 | bool managing = gcwq->flags & GCWQ_MANAGING_WORKERS; |
| 625 | int nr_idle = gcwq->nr_idle + managing; /* manager is considered idle */ | 632 | int nr_idle = gcwq->pool.nr_idle + managing; /* manager is considered idle */ |
| 626 | int nr_busy = gcwq->nr_workers - nr_idle; | 633 | int nr_busy = gcwq->pool.nr_workers - nr_idle; |
| 627 | 634 | ||
| 628 | return nr_idle > 2 && (nr_idle - 2) * MAX_IDLE_WORKERS_RATIO >= nr_busy; | 635 | return nr_idle > 2 && (nr_idle - 2) * MAX_IDLE_WORKERS_RATIO >= nr_busy; |
| 629 | } | 636 | } |
| @@ -635,10 +642,10 @@ static bool too_many_workers(struct global_cwq *gcwq) | |||
| 635 | /* Return the first worker. Safe with preemption disabled */ | 642 | /* Return the first worker. Safe with preemption disabled */ |
| 636 | static struct worker *first_worker(struct global_cwq *gcwq) | 643 | static struct worker *first_worker(struct global_cwq *gcwq) |
| 637 | { | 644 | { |
| 638 | if (unlikely(list_empty(&gcwq->idle_list))) | 645 | if (unlikely(list_empty(&gcwq->pool.idle_list))) |
| 639 | return NULL; | 646 | return NULL; |
| 640 | 647 | ||
| 641 | return list_first_entry(&gcwq->idle_list, struct worker, entry); | 648 | return list_first_entry(&gcwq->pool.idle_list, struct worker, entry); |
| 642 | } | 649 | } |
| 643 | 650 | ||
| 644 | /** | 651 | /** |
| @@ -696,7 +703,8 @@ struct task_struct *wq_worker_sleeping(struct task_struct *task, | |||
| 696 | unsigned int cpu) | 703 | unsigned int cpu) |
| 697 | { | 704 | { |
| 698 | struct worker *worker = kthread_data(task), *to_wakeup = NULL; | 705 | struct worker *worker = kthread_data(task), *to_wakeup = NULL; |
| 699 | struct global_cwq *gcwq = get_gcwq(cpu); | 706 | struct worker_pool *pool = worker->pool; |
| 707 | struct global_cwq *gcwq = pool->gcwq; | ||
| 700 | atomic_t *nr_running = get_gcwq_nr_running(cpu); | 708 | atomic_t *nr_running = get_gcwq_nr_running(cpu); |
| 701 | 709 | ||
| 702 | if (worker->flags & WORKER_NOT_RUNNING) | 710 | if (worker->flags & WORKER_NOT_RUNNING) |
| @@ -716,7 +724,7 @@ struct task_struct *wq_worker_sleeping(struct task_struct *task, | |||
| 716 | * could be manipulating idle_list, so dereferencing idle_list | 724 | * could be manipulating idle_list, so dereferencing idle_list |
| 717 | * without gcwq lock is safe. | 725 | * without gcwq lock is safe. |
| 718 | */ | 726 | */ |
| 719 | if (atomic_dec_and_test(nr_running) && !list_empty(&gcwq->worklist)) | 727 | if (atomic_dec_and_test(nr_running) && !list_empty(&pool->worklist)) |
| 720 | to_wakeup = first_worker(gcwq); | 728 | to_wakeup = first_worker(gcwq); |
| 721 | return to_wakeup ? to_wakeup->task : NULL; | 729 | return to_wakeup ? to_wakeup->task : NULL; |
| 722 | } | 730 | } |
| @@ -737,7 +745,8 @@ struct task_struct *wq_worker_sleeping(struct task_struct *task, | |||
| 737 | static inline void worker_set_flags(struct worker *worker, unsigned int flags, | 745 | static inline void worker_set_flags(struct worker *worker, unsigned int flags, |
| 738 | bool wakeup) | 746 | bool wakeup) |
| 739 | { | 747 | { |
| 740 | struct global_cwq *gcwq = worker->gcwq; | 748 | struct worker_pool *pool = worker->pool; |
| 749 | struct global_cwq *gcwq = pool->gcwq; | ||
| 741 | 750 | ||
| 742 | WARN_ON_ONCE(worker->task != current); | 751 | WARN_ON_ONCE(worker->task != current); |
| 743 | 752 | ||
| @@ -752,7 +761,7 @@ static inline void worker_set_flags(struct worker *worker, unsigned int flags, | |||
| 752 | 761 | ||
| 753 | if (wakeup) { | 762 | if (wakeup) { |
| 754 | if (atomic_dec_and_test(nr_running) && | 763 | if (atomic_dec_and_test(nr_running) && |
| 755 | !list_empty(&gcwq->worklist)) | 764 | !list_empty(&pool->worklist)) |
| 756 | wake_up_worker(gcwq); | 765 | wake_up_worker(gcwq); |
| 757 | } else | 766 | } else |
| 758 | atomic_dec(nr_running); | 767 | atomic_dec(nr_running); |
| @@ -773,7 +782,7 @@ static inline void worker_set_flags(struct worker *worker, unsigned int flags, | |||
| 773 | */ | 782 | */ |
| 774 | static inline void worker_clr_flags(struct worker *worker, unsigned int flags) | 783 | static inline void worker_clr_flags(struct worker *worker, unsigned int flags) |
| 775 | { | 784 | { |
| 776 | struct global_cwq *gcwq = worker->gcwq; | 785 | struct global_cwq *gcwq = worker->pool->gcwq; |
| 777 | unsigned int oflags = worker->flags; | 786 | unsigned int oflags = worker->flags; |
| 778 | 787 | ||
| 779 | WARN_ON_ONCE(worker->task != current); | 788 | WARN_ON_ONCE(worker->task != current); |
| @@ -894,9 +903,9 @@ static inline struct list_head *gcwq_determine_ins_pos(struct global_cwq *gcwq, | |||
| 894 | struct work_struct *twork; | 903 | struct work_struct *twork; |
| 895 | 904 | ||
| 896 | if (likely(!(cwq->wq->flags & WQ_HIGHPRI))) | 905 | if (likely(!(cwq->wq->flags & WQ_HIGHPRI))) |
| 897 | return &gcwq->worklist; | 906 | return &gcwq->pool.worklist; |
| 898 | 907 | ||
| 899 | list_for_each_entry(twork, &gcwq->worklist, entry) { | 908 | list_for_each_entry(twork, &gcwq->pool.worklist, entry) { |
| 900 | struct cpu_workqueue_struct *tcwq = get_work_cwq(twork); | 909 | struct cpu_workqueue_struct *tcwq = get_work_cwq(twork); |
| 901 | 910 | ||
| 902 | if (!(tcwq->wq->flags & WQ_HIGHPRI)) | 911 | if (!(tcwq->wq->flags & WQ_HIGHPRI)) |
| @@ -924,7 +933,7 @@ static void insert_work(struct cpu_workqueue_struct *cwq, | |||
| 924 | struct work_struct *work, struct list_head *head, | 933 | struct work_struct *work, struct list_head *head, |
| 925 | unsigned int extra_flags) | 934 | unsigned int extra_flags) |
| 926 | { | 935 | { |
| 927 | struct global_cwq *gcwq = cwq->gcwq; | 936 | struct global_cwq *gcwq = cwq->pool->gcwq; |
| 928 | 937 | ||
| 929 | /* we own @work, set data and link */ | 938 | /* we own @work, set data and link */ |
| 930 | set_work_cwq(work, cwq, extra_flags); | 939 | set_work_cwq(work, cwq, extra_flags); |
| @@ -1196,7 +1205,8 @@ EXPORT_SYMBOL_GPL(queue_delayed_work_on); | |||
| 1196 | */ | 1205 | */ |
| 1197 | static void worker_enter_idle(struct worker *worker) | 1206 | static void worker_enter_idle(struct worker *worker) |
| 1198 | { | 1207 | { |
| 1199 | struct global_cwq *gcwq = worker->gcwq; | 1208 | struct worker_pool *pool = worker->pool; |
| 1209 | struct global_cwq *gcwq = pool->gcwq; | ||
| 1200 | 1210 | ||
| 1201 | BUG_ON(worker->flags & WORKER_IDLE); | 1211 | BUG_ON(worker->flags & WORKER_IDLE); |
| 1202 | BUG_ON(!list_empty(&worker->entry) && | 1212 | BUG_ON(!list_empty(&worker->entry) && |
| @@ -1204,15 +1214,15 @@ static void worker_enter_idle(struct worker *worker) | |||
| 1204 | 1214 | ||
| 1205 | /* can't use worker_set_flags(), also called from start_worker() */ | 1215 | /* can't use worker_set_flags(), also called from start_worker() */ |
| 1206 | worker->flags |= WORKER_IDLE; | 1216 | worker->flags |= WORKER_IDLE; |
| 1207 | gcwq->nr_idle++; | 1217 | pool->nr_idle++; |
| 1208 | worker->last_active = jiffies; | 1218 | worker->last_active = jiffies; |
| 1209 | 1219 | ||
| 1210 | /* idle_list is LIFO */ | 1220 | /* idle_list is LIFO */ |
| 1211 | list_add(&worker->entry, &gcwq->idle_list); | 1221 | list_add(&worker->entry, &pool->idle_list); |
| 1212 | 1222 | ||
| 1213 | if (likely(!(worker->flags & WORKER_ROGUE))) { | 1223 | if (likely(!(worker->flags & WORKER_ROGUE))) { |
| 1214 | if (too_many_workers(gcwq) && !timer_pending(&gcwq->idle_timer)) | 1224 | if (too_many_workers(gcwq) && !timer_pending(&pool->idle_timer)) |
| 1215 | mod_timer(&gcwq->idle_timer, | 1225 | mod_timer(&pool->idle_timer, |
| 1216 | jiffies + IDLE_WORKER_TIMEOUT); | 1226 | jiffies + IDLE_WORKER_TIMEOUT); |
| 1217 | } else | 1227 | } else |
| 1218 | wake_up_all(&gcwq->trustee_wait); | 1228 | wake_up_all(&gcwq->trustee_wait); |
| @@ -1223,7 +1233,7 @@ static void worker_enter_idle(struct worker *worker) | |||
| 1223 | * warning may trigger spuriously. Check iff trustee is idle. | 1233 | * warning may trigger spuriously. Check iff trustee is idle. |
| 1224 | */ | 1234 | */ |
| 1225 | WARN_ON_ONCE(gcwq->trustee_state == TRUSTEE_DONE && | 1235 | WARN_ON_ONCE(gcwq->trustee_state == TRUSTEE_DONE && |
| 1226 | gcwq->nr_workers == gcwq->nr_idle && | 1236 | pool->nr_workers == pool->nr_idle && |
| 1227 | atomic_read(get_gcwq_nr_running(gcwq->cpu))); | 1237 | atomic_read(get_gcwq_nr_running(gcwq->cpu))); |
| 1228 | } | 1238 | } |
| 1229 | 1239 | ||
| @@ -1238,11 +1248,11 @@ static void worker_enter_idle(struct worker *worker) | |||
| 1238 | */ | 1248 | */ |
| 1239 | static void worker_leave_idle(struct worker *worker) | 1249 | static void worker_leave_idle(struct worker *worker) |
| 1240 | { | 1250 | { |
| 1241 | struct global_cwq *gcwq = worker->gcwq; | 1251 | struct worker_pool *pool = worker->pool; |
| 1242 | 1252 | ||
| 1243 | BUG_ON(!(worker->flags & WORKER_IDLE)); | 1253 | BUG_ON(!(worker->flags & WORKER_IDLE)); |
| 1244 | worker_clr_flags(worker, WORKER_IDLE); | 1254 | worker_clr_flags(worker, WORKER_IDLE); |
| 1245 | gcwq->nr_idle--; | 1255 | pool->nr_idle--; |
| 1246 | list_del_init(&worker->entry); | 1256 | list_del_init(&worker->entry); |
| 1247 | } | 1257 | } |
| 1248 | 1258 | ||
| @@ -1279,7 +1289,7 @@ static void worker_leave_idle(struct worker *worker) | |||
| 1279 | static bool worker_maybe_bind_and_lock(struct worker *worker) | 1289 | static bool worker_maybe_bind_and_lock(struct worker *worker) |
| 1280 | __acquires(&gcwq->lock) | 1290 | __acquires(&gcwq->lock) |
| 1281 | { | 1291 | { |
| 1282 | struct global_cwq *gcwq = worker->gcwq; | 1292 | struct global_cwq *gcwq = worker->pool->gcwq; |
| 1283 | struct task_struct *task = worker->task; | 1293 | struct task_struct *task = worker->task; |
| 1284 | 1294 | ||
| 1285 | while (true) { | 1295 | while (true) { |
| @@ -1321,7 +1331,7 @@ __acquires(&gcwq->lock) | |||
| 1321 | static void worker_rebind_fn(struct work_struct *work) | 1331 | static void worker_rebind_fn(struct work_struct *work) |
| 1322 | { | 1332 | { |
| 1323 | struct worker *worker = container_of(work, struct worker, rebind_work); | 1333 | struct worker *worker = container_of(work, struct worker, rebind_work); |
| 1324 | struct global_cwq *gcwq = worker->gcwq; | 1334 | struct global_cwq *gcwq = worker->pool->gcwq; |
| 1325 | 1335 | ||
| 1326 | if (worker_maybe_bind_and_lock(worker)) | 1336 | if (worker_maybe_bind_and_lock(worker)) |
| 1327 | worker_clr_flags(worker, WORKER_REBIND); | 1337 | worker_clr_flags(worker, WORKER_REBIND); |
| @@ -1362,13 +1372,14 @@ static struct worker *alloc_worker(void) | |||
| 1362 | static struct worker *create_worker(struct global_cwq *gcwq, bool bind) | 1372 | static struct worker *create_worker(struct global_cwq *gcwq, bool bind) |
| 1363 | { | 1373 | { |
| 1364 | bool on_unbound_cpu = gcwq->cpu == WORK_CPU_UNBOUND; | 1374 | bool on_unbound_cpu = gcwq->cpu == WORK_CPU_UNBOUND; |
| 1375 | struct worker_pool *pool = &gcwq->pool; | ||
| 1365 | struct worker *worker = NULL; | 1376 | struct worker *worker = NULL; |
| 1366 | int id = -1; | 1377 | int id = -1; |
| 1367 | 1378 | ||
| 1368 | spin_lock_irq(&gcwq->lock); | 1379 | spin_lock_irq(&gcwq->lock); |
| 1369 | while (ida_get_new(&gcwq->worker_ida, &id)) { | 1380 | while (ida_get_new(&pool->worker_ida, &id)) { |
| 1370 | spin_unlock_irq(&gcwq->lock); | 1381 | spin_unlock_irq(&gcwq->lock); |
| 1371 | if (!ida_pre_get(&gcwq->worker_ida, GFP_KERNEL)) | 1382 | if (!ida_pre_get(&pool->worker_ida, GFP_KERNEL)) |
| 1372 | goto fail; | 1383 | goto fail; |
| 1373 | spin_lock_irq(&gcwq->lock); | 1384 | spin_lock_irq(&gcwq->lock); |
| 1374 | } | 1385 | } |
| @@ -1378,7 +1389,7 @@ static struct worker *create_worker(struct global_cwq *gcwq, bool bind) | |||
| 1378 | if (!worker) | 1389 | if (!worker) |
| 1379 | goto fail; | 1390 | goto fail; |
| 1380 | 1391 | ||
| 1381 | worker->gcwq = gcwq; | 1392 | worker->pool = pool; |
| 1382 | worker->id = id; | 1393 | worker->id = id; |
| 1383 | 1394 | ||
| 1384 | if (!on_unbound_cpu) | 1395 | if (!on_unbound_cpu) |
| @@ -1409,7 +1420,7 @@ static struct worker *create_worker(struct global_cwq *gcwq, bool bind) | |||
| 1409 | fail: | 1420 | fail: |
| 1410 | if (id >= 0) { | 1421 | if (id >= 0) { |
| 1411 | spin_lock_irq(&gcwq->lock); | 1422 | spin_lock_irq(&gcwq->lock); |
| 1412 | ida_remove(&gcwq->worker_ida, id); | 1423 | ida_remove(&pool->worker_ida, id); |
| 1413 | spin_unlock_irq(&gcwq->lock); | 1424 | spin_unlock_irq(&gcwq->lock); |
| 1414 | } | 1425 | } |
| 1415 | kfree(worker); | 1426 | kfree(worker); |
| @@ -1428,7 +1439,7 @@ fail: | |||
| 1428 | static void start_worker(struct worker *worker) | 1439 | static void start_worker(struct worker *worker) |
| 1429 | { | 1440 | { |
| 1430 | worker->flags |= WORKER_STARTED; | 1441 | worker->flags |= WORKER_STARTED; |
| 1431 | worker->gcwq->nr_workers++; | 1442 | worker->pool->nr_workers++; |
| 1432 | worker_enter_idle(worker); | 1443 | worker_enter_idle(worker); |
| 1433 | wake_up_process(worker->task); | 1444 | wake_up_process(worker->task); |
| 1434 | } | 1445 | } |
| @@ -1444,7 +1455,8 @@ static void start_worker(struct worker *worker) | |||
| 1444 | */ | 1455 | */ |
| 1445 | static void destroy_worker(struct worker *worker) | 1456 | static void destroy_worker(struct worker *worker) |
| 1446 | { | 1457 | { |
| 1447 | struct global_cwq *gcwq = worker->gcwq; | 1458 | struct worker_pool *pool = worker->pool; |
| 1459 | struct global_cwq *gcwq = pool->gcwq; | ||
| 1448 | int id = worker->id; | 1460 | int id = worker->id; |
| 1449 | 1461 | ||
| 1450 | /* sanity check frenzy */ | 1462 | /* sanity check frenzy */ |
| @@ -1452,9 +1464,9 @@ static void destroy_worker(struct worker *worker) | |||
| 1452 | BUG_ON(!list_empty(&worker->scheduled)); | 1464 | BUG_ON(!list_empty(&worker->scheduled)); |
| 1453 | 1465 | ||
| 1454 | if (worker->flags & WORKER_STARTED) | 1466 | if (worker->flags & WORKER_STARTED) |
| 1455 | gcwq->nr_workers--; | 1467 | pool->nr_workers--; |
| 1456 | if (worker->flags & WORKER_IDLE) | 1468 | if (worker->flags & WORKER_IDLE) |
| 1457 | gcwq->nr_idle--; | 1469 | pool->nr_idle--; |
| 1458 | 1470 | ||
| 1459 | list_del_init(&worker->entry); | 1471 | list_del_init(&worker->entry); |
| 1460 | worker->flags |= WORKER_DIE; | 1472 | worker->flags |= WORKER_DIE; |
| @@ -1465,7 +1477,7 @@ static void destroy_worker(struct worker *worker) | |||
| 1465 | kfree(worker); | 1477 | kfree(worker); |
| 1466 | 1478 | ||
| 1467 | spin_lock_irq(&gcwq->lock); | 1479 | spin_lock_irq(&gcwq->lock); |
| 1468 | ida_remove(&gcwq->worker_ida, id); | 1480 | ida_remove(&pool->worker_ida, id); |
| 1469 | } | 1481 | } |
| 1470 | 1482 | ||
| 1471 | static void idle_worker_timeout(unsigned long __gcwq) | 1483 | static void idle_worker_timeout(unsigned long __gcwq) |
| @@ -1479,11 +1491,12 @@ static void idle_worker_timeout(unsigned long __gcwq) | |||
| 1479 | unsigned long expires; | 1491 | unsigned long expires; |
| 1480 | 1492 | ||
| 1481 | /* idle_list is kept in LIFO order, check the last one */ | 1493 | /* idle_list is kept in LIFO order, check the last one */ |
| 1482 | worker = list_entry(gcwq->idle_list.prev, struct worker, entry); | 1494 | worker = list_entry(gcwq->pool.idle_list.prev, struct worker, |
| 1495 | entry); | ||
| 1483 | expires = worker->last_active + IDLE_WORKER_TIMEOUT; | 1496 | expires = worker->last_active + IDLE_WORKER_TIMEOUT; |
| 1484 | 1497 | ||
| 1485 | if (time_before(jiffies, expires)) | 1498 | if (time_before(jiffies, expires)) |
| 1486 | mod_timer(&gcwq->idle_timer, expires); | 1499 | mod_timer(&gcwq->pool.idle_timer, expires); |
| 1487 | else { | 1500 | else { |
| 1488 | /* it's been idle for too long, wake up manager */ | 1501 | /* it's been idle for too long, wake up manager */ |
| 1489 | gcwq->flags |= GCWQ_MANAGE_WORKERS; | 1502 | gcwq->flags |= GCWQ_MANAGE_WORKERS; |
| @@ -1504,7 +1517,7 @@ static bool send_mayday(struct work_struct *work) | |||
| 1504 | return false; | 1517 | return false; |
| 1505 | 1518 | ||
| 1506 | /* mayday mayday mayday */ | 1519 | /* mayday mayday mayday */ |
| 1507 | cpu = cwq->gcwq->cpu; | 1520 | cpu = cwq->pool->gcwq->cpu; |
| 1508 | /* WORK_CPU_UNBOUND can't be set in cpumask, use cpu 0 instead */ | 1521 | /* WORK_CPU_UNBOUND can't be set in cpumask, use cpu 0 instead */ |
| 1509 | if (cpu == WORK_CPU_UNBOUND) | 1522 | if (cpu == WORK_CPU_UNBOUND) |
| 1510 | cpu = 0; | 1523 | cpu = 0; |
| @@ -1527,13 +1540,13 @@ static void gcwq_mayday_timeout(unsigned long __gcwq) | |||
| 1527 | * allocation deadlock. Send distress signals to | 1540 | * allocation deadlock. Send distress signals to |
| 1528 | * rescuers. | 1541 | * rescuers. |
| 1529 | */ | 1542 | */ |
| 1530 | list_for_each_entry(work, &gcwq->worklist, entry) | 1543 | list_for_each_entry(work, &gcwq->pool.worklist, entry) |
| 1531 | send_mayday(work); | 1544 | send_mayday(work); |
| 1532 | } | 1545 | } |
| 1533 | 1546 | ||
| 1534 | spin_unlock_irq(&gcwq->lock); | 1547 | spin_unlock_irq(&gcwq->lock); |
| 1535 | 1548 | ||
| 1536 | mod_timer(&gcwq->mayday_timer, jiffies + MAYDAY_INTERVAL); | 1549 | mod_timer(&gcwq->pool.mayday_timer, jiffies + MAYDAY_INTERVAL); |
| 1537 | } | 1550 | } |
| 1538 | 1551 | ||
| 1539 | /** | 1552 | /** |
| @@ -1568,14 +1581,14 @@ restart: | |||
| 1568 | spin_unlock_irq(&gcwq->lock); | 1581 | spin_unlock_irq(&gcwq->lock); |
| 1569 | 1582 | ||
| 1570 | /* if we don't make progress in MAYDAY_INITIAL_TIMEOUT, call for help */ | 1583 | /* if we don't make progress in MAYDAY_INITIAL_TIMEOUT, call for help */ |
| 1571 | mod_timer(&gcwq->mayday_timer, jiffies + MAYDAY_INITIAL_TIMEOUT); | 1584 | mod_timer(&gcwq->pool.mayday_timer, jiffies + MAYDAY_INITIAL_TIMEOUT); |
| 1572 | 1585 | ||
| 1573 | while (true) { | 1586 | while (true) { |
| 1574 | struct worker *worker; | 1587 | struct worker *worker; |
| 1575 | 1588 | ||
| 1576 | worker = create_worker(gcwq, true); | 1589 | worker = create_worker(gcwq, true); |
| 1577 | if (worker) { | 1590 | if (worker) { |
| 1578 | del_timer_sync(&gcwq->mayday_timer); | 1591 | del_timer_sync(&gcwq->pool.mayday_timer); |
| 1579 | spin_lock_irq(&gcwq->lock); | 1592 | spin_lock_irq(&gcwq->lock); |
| 1580 | start_worker(worker); | 1593 | start_worker(worker); |
| 1581 | BUG_ON(need_to_create_worker(gcwq)); | 1594 | BUG_ON(need_to_create_worker(gcwq)); |
| @@ -1592,7 +1605,7 @@ restart: | |||
| 1592 | break; | 1605 | break; |
| 1593 | } | 1606 | } |
| 1594 | 1607 | ||
| 1595 | del_timer_sync(&gcwq->mayday_timer); | 1608 | del_timer_sync(&gcwq->pool.mayday_timer); |
| 1596 | spin_lock_irq(&gcwq->lock); | 1609 | spin_lock_irq(&gcwq->lock); |
| 1597 | if (need_to_create_worker(gcwq)) | 1610 | if (need_to_create_worker(gcwq)) |
| 1598 | goto restart; | 1611 | goto restart; |
| @@ -1622,11 +1635,12 @@ static bool maybe_destroy_workers(struct global_cwq *gcwq) | |||
| 1622 | struct worker *worker; | 1635 | struct worker *worker; |
| 1623 | unsigned long expires; | 1636 | unsigned long expires; |
| 1624 | 1637 | ||
| 1625 | worker = list_entry(gcwq->idle_list.prev, struct worker, entry); | 1638 | worker = list_entry(gcwq->pool.idle_list.prev, struct worker, |
| 1639 | entry); | ||
| 1626 | expires = worker->last_active + IDLE_WORKER_TIMEOUT; | 1640 | expires = worker->last_active + IDLE_WORKER_TIMEOUT; |
| 1627 | 1641 | ||
| 1628 | if (time_before(jiffies, expires)) { | 1642 | if (time_before(jiffies, expires)) { |
| 1629 | mod_timer(&gcwq->idle_timer, expires); | 1643 | mod_timer(&gcwq->pool.idle_timer, expires); |
| 1630 | break; | 1644 | break; |
| 1631 | } | 1645 | } |
| 1632 | 1646 | ||
| @@ -1659,7 +1673,7 @@ static bool maybe_destroy_workers(struct global_cwq *gcwq) | |||
| 1659 | */ | 1673 | */ |
| 1660 | static bool manage_workers(struct worker *worker) | 1674 | static bool manage_workers(struct worker *worker) |
| 1661 | { | 1675 | { |
| 1662 | struct global_cwq *gcwq = worker->gcwq; | 1676 | struct global_cwq *gcwq = worker->pool->gcwq; |
| 1663 | bool ret = false; | 1677 | bool ret = false; |
| 1664 | 1678 | ||
| 1665 | if (gcwq->flags & GCWQ_MANAGING_WORKERS) | 1679 | if (gcwq->flags & GCWQ_MANAGING_WORKERS) |
| @@ -1732,7 +1746,7 @@ static void cwq_activate_first_delayed(struct cpu_workqueue_struct *cwq) | |||
| 1732 | { | 1746 | { |
| 1733 | struct work_struct *work = list_first_entry(&cwq->delayed_works, | 1747 | struct work_struct *work = list_first_entry(&cwq->delayed_works, |
| 1734 | struct work_struct, entry); | 1748 | struct work_struct, entry); |
| 1735 | struct list_head *pos = gcwq_determine_ins_pos(cwq->gcwq, cwq); | 1749 | struct list_head *pos = gcwq_determine_ins_pos(cwq->pool->gcwq, cwq); |
| 1736 | 1750 | ||
| 1737 | trace_workqueue_activate_work(work); | 1751 | trace_workqueue_activate_work(work); |
| 1738 | move_linked_works(work, pos, NULL); | 1752 | move_linked_works(work, pos, NULL); |
| @@ -1808,7 +1822,8 @@ __releases(&gcwq->lock) | |||
| 1808 | __acquires(&gcwq->lock) | 1822 | __acquires(&gcwq->lock) |
| 1809 | { | 1823 | { |
| 1810 | struct cpu_workqueue_struct *cwq = get_work_cwq(work); | 1824 | struct cpu_workqueue_struct *cwq = get_work_cwq(work); |
| 1811 | struct global_cwq *gcwq = cwq->gcwq; | 1825 | struct worker_pool *pool = worker->pool; |
| 1826 | struct global_cwq *gcwq = pool->gcwq; | ||
| 1812 | struct hlist_head *bwh = busy_worker_head(gcwq, work); | 1827 | struct hlist_head *bwh = busy_worker_head(gcwq, work); |
| 1813 | bool cpu_intensive = cwq->wq->flags & WQ_CPU_INTENSIVE; | 1828 | bool cpu_intensive = cwq->wq->flags & WQ_CPU_INTENSIVE; |
| 1814 | work_func_t f = work->func; | 1829 | work_func_t f = work->func; |
| @@ -1854,10 +1869,10 @@ __acquires(&gcwq->lock) | |||
| 1854 | * wake up another worker; otherwise, clear HIGHPRI_PENDING. | 1869 | * wake up another worker; otherwise, clear HIGHPRI_PENDING. |
| 1855 | */ | 1870 | */ |
| 1856 | if (unlikely(gcwq->flags & GCWQ_HIGHPRI_PENDING)) { | 1871 | if (unlikely(gcwq->flags & GCWQ_HIGHPRI_PENDING)) { |
| 1857 | struct work_struct *nwork = list_first_entry(&gcwq->worklist, | 1872 | struct work_struct *nwork = list_first_entry(&pool->worklist, |
| 1858 | struct work_struct, entry); | 1873 | struct work_struct, entry); |
| 1859 | 1874 | ||
| 1860 | if (!list_empty(&gcwq->worklist) && | 1875 | if (!list_empty(&pool->worklist) && |
| 1861 | get_work_cwq(nwork)->wq->flags & WQ_HIGHPRI) | 1876 | get_work_cwq(nwork)->wq->flags & WQ_HIGHPRI) |
| 1862 | wake_up_worker(gcwq); | 1877 | wake_up_worker(gcwq); |
| 1863 | else | 1878 | else |
| @@ -1950,7 +1965,8 @@ static void process_scheduled_works(struct worker *worker) | |||
| 1950 | static int worker_thread(void *__worker) | 1965 | static int worker_thread(void *__worker) |
| 1951 | { | 1966 | { |
| 1952 | struct worker *worker = __worker; | 1967 | struct worker *worker = __worker; |
| 1953 | struct global_cwq *gcwq = worker->gcwq; | 1968 | struct worker_pool *pool = worker->pool; |
| 1969 | struct global_cwq *gcwq = pool->gcwq; | ||
| 1954 | 1970 | ||
| 1955 | /* tell the scheduler that this is a workqueue worker */ | 1971 | /* tell the scheduler that this is a workqueue worker */ |
| 1956 | worker->task->flags |= PF_WQ_WORKER; | 1972 | worker->task->flags |= PF_WQ_WORKER; |
| @@ -1990,7 +2006,7 @@ recheck: | |||
| 1990 | 2006 | ||
| 1991 | do { | 2007 | do { |
| 1992 | struct work_struct *work = | 2008 | struct work_struct *work = |
| 1993 | list_first_entry(&gcwq->worklist, | 2009 | list_first_entry(&pool->worklist, |
| 1994 | struct work_struct, entry); | 2010 | struct work_struct, entry); |
| 1995 | 2011 | ||
| 1996 | if (likely(!(*work_data_bits(work) & WORK_STRUCT_LINKED))) { | 2012 | if (likely(!(*work_data_bits(work) & WORK_STRUCT_LINKED))) { |
| @@ -2064,14 +2080,15 @@ repeat: | |||
| 2064 | for_each_mayday_cpu(cpu, wq->mayday_mask) { | 2080 | for_each_mayday_cpu(cpu, wq->mayday_mask) { |
| 2065 | unsigned int tcpu = is_unbound ? WORK_CPU_UNBOUND : cpu; | 2081 | unsigned int tcpu = is_unbound ? WORK_CPU_UNBOUND : cpu; |
| 2066 | struct cpu_workqueue_struct *cwq = get_cwq(tcpu, wq); | 2082 | struct cpu_workqueue_struct *cwq = get_cwq(tcpu, wq); |
| 2067 | struct global_cwq *gcwq = cwq->gcwq; | 2083 | struct worker_pool *pool = cwq->pool; |
| 2084 | struct global_cwq *gcwq = pool->gcwq; | ||
| 2068 | struct work_struct *work, *n; | 2085 | struct work_struct *work, *n; |
| 2069 | 2086 | ||
| 2070 | __set_current_state(TASK_RUNNING); | 2087 | __set_current_state(TASK_RUNNING); |
| 2071 | mayday_clear_cpu(cpu, wq->mayday_mask); | 2088 | mayday_clear_cpu(cpu, wq->mayday_mask); |
| 2072 | 2089 | ||
| 2073 | /* migrate to the target cpu if possible */ | 2090 | /* migrate to the target cpu if possible */ |
| 2074 | rescuer->gcwq = gcwq; | 2091 | rescuer->pool = pool; |
| 2075 | worker_maybe_bind_and_lock(rescuer); | 2092 | worker_maybe_bind_and_lock(rescuer); |
| 2076 | 2093 | ||
| 2077 | /* | 2094 | /* |
| @@ -2079,7 +2096,7 @@ repeat: | |||
| 2079 | * process'em. | 2096 | * process'em. |
| 2080 | */ | 2097 | */ |
| 2081 | BUG_ON(!list_empty(&rescuer->scheduled)); | 2098 | BUG_ON(!list_empty(&rescuer->scheduled)); |
| 2082 | list_for_each_entry_safe(work, n, &gcwq->worklist, entry) | 2099 | list_for_each_entry_safe(work, n, &pool->worklist, entry) |
| 2083 | if (get_work_cwq(work) == cwq) | 2100 | if (get_work_cwq(work) == cwq) |
| 2084 | move_linked_works(work, scheduled, &n); | 2101 | move_linked_works(work, scheduled, &n); |
| 2085 | 2102 | ||
| @@ -2216,7 +2233,7 @@ static bool flush_workqueue_prep_cwqs(struct workqueue_struct *wq, | |||
| 2216 | 2233 | ||
| 2217 | for_each_cwq_cpu(cpu, wq) { | 2234 | for_each_cwq_cpu(cpu, wq) { |
| 2218 | struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq); | 2235 | struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq); |
| 2219 | struct global_cwq *gcwq = cwq->gcwq; | 2236 | struct global_cwq *gcwq = cwq->pool->gcwq; |
| 2220 | 2237 | ||
| 2221 | spin_lock_irq(&gcwq->lock); | 2238 | spin_lock_irq(&gcwq->lock); |
| 2222 | 2239 | ||
| @@ -2432,9 +2449,9 @@ reflush: | |||
| 2432 | struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq); | 2449 | struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq); |
| 2433 | bool drained; | 2450 | bool drained; |
| 2434 | 2451 | ||
| 2435 | spin_lock_irq(&cwq->gcwq->lock); | 2452 | spin_lock_irq(&cwq->pool->gcwq->lock); |
| 2436 | drained = !cwq->nr_active && list_empty(&cwq->delayed_works); | 2453 | drained = !cwq->nr_active && list_empty(&cwq->delayed_works); |
| 2437 | spin_unlock_irq(&cwq->gcwq->lock); | 2454 | spin_unlock_irq(&cwq->pool->gcwq->lock); |
| 2438 | 2455 | ||
| 2439 | if (drained) | 2456 | if (drained) |
| 2440 | continue; | 2457 | continue; |
| @@ -2474,7 +2491,7 @@ static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr, | |||
| 2474 | */ | 2491 | */ |
| 2475 | smp_rmb(); | 2492 | smp_rmb(); |
| 2476 | cwq = get_work_cwq(work); | 2493 | cwq = get_work_cwq(work); |
| 2477 | if (unlikely(!cwq || gcwq != cwq->gcwq)) | 2494 | if (unlikely(!cwq || gcwq != cwq->pool->gcwq)) |
| 2478 | goto already_gone; | 2495 | goto already_gone; |
| 2479 | } else if (wait_executing) { | 2496 | } else if (wait_executing) { |
| 2480 | worker = find_worker_executing_work(gcwq, work); | 2497 | worker = find_worker_executing_work(gcwq, work); |
| @@ -3017,7 +3034,7 @@ struct workqueue_struct *__alloc_workqueue_key(const char *fmt, | |||
| 3017 | struct global_cwq *gcwq = get_gcwq(cpu); | 3034 | struct global_cwq *gcwq = get_gcwq(cpu); |
| 3018 | 3035 | ||
| 3019 | BUG_ON((unsigned long)cwq & WORK_STRUCT_FLAG_MASK); | 3036 | BUG_ON((unsigned long)cwq & WORK_STRUCT_FLAG_MASK); |
| 3020 | cwq->gcwq = gcwq; | 3037 | cwq->pool = &gcwq->pool; |
| 3021 | cwq->wq = wq; | 3038 | cwq->wq = wq; |
| 3022 | cwq->flush_color = -1; | 3039 | cwq->flush_color = -1; |
| 3023 | cwq->max_active = max_active; | 3040 | cwq->max_active = max_active; |
| @@ -3344,7 +3361,7 @@ static int __cpuinit trustee_thread(void *__gcwq) | |||
| 3344 | 3361 | ||
| 3345 | gcwq->flags |= GCWQ_MANAGING_WORKERS; | 3362 | gcwq->flags |= GCWQ_MANAGING_WORKERS; |
| 3346 | 3363 | ||
| 3347 | list_for_each_entry(worker, &gcwq->idle_list, entry) | 3364 | list_for_each_entry(worker, &gcwq->pool.idle_list, entry) |
| 3348 | worker->flags |= WORKER_ROGUE; | 3365 | worker->flags |= WORKER_ROGUE; |
| 3349 | 3366 | ||
| 3350 | for_each_busy_worker(worker, i, pos, gcwq) | 3367 | for_each_busy_worker(worker, i, pos, gcwq) |
| @@ -3369,7 +3386,7 @@ static int __cpuinit trustee_thread(void *__gcwq) | |||
| 3369 | atomic_set(get_gcwq_nr_running(gcwq->cpu), 0); | 3386 | atomic_set(get_gcwq_nr_running(gcwq->cpu), 0); |
| 3370 | 3387 | ||
| 3371 | spin_unlock_irq(&gcwq->lock); | 3388 | spin_unlock_irq(&gcwq->lock); |
| 3372 | del_timer_sync(&gcwq->idle_timer); | 3389 | del_timer_sync(&gcwq->pool.idle_timer); |
| 3373 | spin_lock_irq(&gcwq->lock); | 3390 | spin_lock_irq(&gcwq->lock); |
| 3374 | 3391 | ||
| 3375 | /* | 3392 | /* |
| @@ -3391,17 +3408,17 @@ static int __cpuinit trustee_thread(void *__gcwq) | |||
| 3391 | * may be frozen works in freezable cwqs. Don't declare | 3408 | * may be frozen works in freezable cwqs. Don't declare |
| 3392 | * completion while frozen. | 3409 | * completion while frozen. |
| 3393 | */ | 3410 | */ |
| 3394 | while (gcwq->nr_workers != gcwq->nr_idle || | 3411 | while (gcwq->pool.nr_workers != gcwq->pool.nr_idle || |
| 3395 | gcwq->flags & GCWQ_FREEZING || | 3412 | gcwq->flags & GCWQ_FREEZING || |
| 3396 | gcwq->trustee_state == TRUSTEE_IN_CHARGE) { | 3413 | gcwq->trustee_state == TRUSTEE_IN_CHARGE) { |
| 3397 | int nr_works = 0; | 3414 | int nr_works = 0; |
| 3398 | 3415 | ||
| 3399 | list_for_each_entry(work, &gcwq->worklist, entry) { | 3416 | list_for_each_entry(work, &gcwq->pool.worklist, entry) { |
| 3400 | send_mayday(work); | 3417 | send_mayday(work); |
| 3401 | nr_works++; | 3418 | nr_works++; |
| 3402 | } | 3419 | } |
| 3403 | 3420 | ||
| 3404 | list_for_each_entry(worker, &gcwq->idle_list, entry) { | 3421 | list_for_each_entry(worker, &gcwq->pool.idle_list, entry) { |
| 3405 | if (!nr_works--) | 3422 | if (!nr_works--) |
| 3406 | break; | 3423 | break; |
| 3407 | wake_up_process(worker->task); | 3424 | wake_up_process(worker->task); |
| @@ -3428,11 +3445,11 @@ static int __cpuinit trustee_thread(void *__gcwq) | |||
| 3428 | * all workers till we're canceled. | 3445 | * all workers till we're canceled. |
| 3429 | */ | 3446 | */ |
| 3430 | do { | 3447 | do { |
| 3431 | rc = trustee_wait_event(!list_empty(&gcwq->idle_list)); | 3448 | rc = trustee_wait_event(!list_empty(&gcwq->pool.idle_list)); |
| 3432 | while (!list_empty(&gcwq->idle_list)) | 3449 | while (!list_empty(&gcwq->pool.idle_list)) |
| 3433 | destroy_worker(list_first_entry(&gcwq->idle_list, | 3450 | destroy_worker(list_first_entry(&gcwq->pool.idle_list, |
| 3434 | struct worker, entry)); | 3451 | struct worker, entry)); |
| 3435 | } while (gcwq->nr_workers && rc >= 0); | 3452 | } while (gcwq->pool.nr_workers && rc >= 0); |
| 3436 | 3453 | ||
| 3437 | /* | 3454 | /* |
| 3438 | * At this point, either draining has completed and no worker | 3455 | * At this point, either draining has completed and no worker |
| @@ -3441,7 +3458,7 @@ static int __cpuinit trustee_thread(void *__gcwq) | |||
| 3441 | * Tell the remaining busy ones to rebind once it finishes the | 3458 | * Tell the remaining busy ones to rebind once it finishes the |
| 3442 | * currently scheduled works by scheduling the rebind_work. | 3459 | * currently scheduled works by scheduling the rebind_work. |
| 3443 | */ | 3460 | */ |
| 3444 | WARN_ON(!list_empty(&gcwq->idle_list)); | 3461 | WARN_ON(!list_empty(&gcwq->pool.idle_list)); |
| 3445 | 3462 | ||
| 3446 | for_each_busy_worker(worker, i, pos, gcwq) { | 3463 | for_each_busy_worker(worker, i, pos, gcwq) { |
| 3447 | struct work_struct *rebind_work = &worker->rebind_work; | 3464 | struct work_struct *rebind_work = &worker->rebind_work; |
| @@ -3522,7 +3539,7 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb, | |||
| 3522 | kthread_bind(new_trustee, cpu); | 3539 | kthread_bind(new_trustee, cpu); |
| 3523 | /* fall through */ | 3540 | /* fall through */ |
| 3524 | case CPU_UP_PREPARE: | 3541 | case CPU_UP_PREPARE: |
| 3525 | BUG_ON(gcwq->first_idle); | 3542 | BUG_ON(gcwq->pool.first_idle); |
| 3526 | new_worker = create_worker(gcwq, false); | 3543 | new_worker = create_worker(gcwq, false); |
| 3527 | if (!new_worker) { | 3544 | if (!new_worker) { |
| 3528 | if (new_trustee) | 3545 | if (new_trustee) |
| @@ -3544,8 +3561,8 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb, | |||
| 3544 | wait_trustee_state(gcwq, TRUSTEE_IN_CHARGE); | 3561 | wait_trustee_state(gcwq, TRUSTEE_IN_CHARGE); |
| 3545 | /* fall through */ | 3562 | /* fall through */ |
| 3546 | case CPU_UP_PREPARE: | 3563 | case CPU_UP_PREPARE: |
| 3547 | BUG_ON(gcwq->first_idle); | 3564 | BUG_ON(gcwq->pool.first_idle); |
| 3548 | gcwq->first_idle = new_worker; | 3565 | gcwq->pool.first_idle = new_worker; |
| 3549 | break; | 3566 | break; |
| 3550 | 3567 | ||
| 3551 | case CPU_DYING: | 3568 | case CPU_DYING: |
| @@ -3562,8 +3579,8 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb, | |||
| 3562 | gcwq->trustee_state = TRUSTEE_BUTCHER; | 3579 | gcwq->trustee_state = TRUSTEE_BUTCHER; |
| 3563 | /* fall through */ | 3580 | /* fall through */ |
| 3564 | case CPU_UP_CANCELED: | 3581 | case CPU_UP_CANCELED: |
| 3565 | destroy_worker(gcwq->first_idle); | 3582 | destroy_worker(gcwq->pool.first_idle); |
| 3566 | gcwq->first_idle = NULL; | 3583 | gcwq->pool.first_idle = NULL; |
| 3567 | break; | 3584 | break; |
| 3568 | 3585 | ||
| 3569 | case CPU_DOWN_FAILED: | 3586 | case CPU_DOWN_FAILED: |
| @@ -3581,11 +3598,11 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb, | |||
| 3581 | * take a look. | 3598 | * take a look. |
| 3582 | */ | 3599 | */ |
| 3583 | spin_unlock_irq(&gcwq->lock); | 3600 | spin_unlock_irq(&gcwq->lock); |
| 3584 | kthread_bind(gcwq->first_idle->task, cpu); | 3601 | kthread_bind(gcwq->pool.first_idle->task, cpu); |
| 3585 | spin_lock_irq(&gcwq->lock); | 3602 | spin_lock_irq(&gcwq->lock); |
| 3586 | gcwq->flags |= GCWQ_MANAGE_WORKERS; | 3603 | gcwq->flags |= GCWQ_MANAGE_WORKERS; |
| 3587 | start_worker(gcwq->first_idle); | 3604 | start_worker(gcwq->pool.first_idle); |
| 3588 | gcwq->first_idle = NULL; | 3605 | gcwq->pool.first_idle = NULL; |
| 3589 | break; | 3606 | break; |
| 3590 | } | 3607 | } |
| 3591 | 3608 | ||
| @@ -3794,22 +3811,23 @@ static int __init init_workqueues(void) | |||
| 3794 | struct global_cwq *gcwq = get_gcwq(cpu); | 3811 | struct global_cwq *gcwq = get_gcwq(cpu); |
| 3795 | 3812 | ||
| 3796 | spin_lock_init(&gcwq->lock); | 3813 | spin_lock_init(&gcwq->lock); |
| 3797 | INIT_LIST_HEAD(&gcwq->worklist); | 3814 | gcwq->pool.gcwq = gcwq; |
| 3815 | INIT_LIST_HEAD(&gcwq->pool.worklist); | ||
| 3798 | gcwq->cpu = cpu; | 3816 | gcwq->cpu = cpu; |
| 3799 | gcwq->flags |= GCWQ_DISASSOCIATED; | 3817 | gcwq->flags |= GCWQ_DISASSOCIATED; |
| 3800 | 3818 | ||
| 3801 | INIT_LIST_HEAD(&gcwq->idle_list); | 3819 | INIT_LIST_HEAD(&gcwq->pool.idle_list); |
| 3802 | for (i = 0; i < BUSY_WORKER_HASH_SIZE; i++) | 3820 | for (i = 0; i < BUSY_WORKER_HASH_SIZE; i++) |
| 3803 | INIT_HLIST_HEAD(&gcwq->busy_hash[i]); | 3821 | INIT_HLIST_HEAD(&gcwq->busy_hash[i]); |
| 3804 | 3822 | ||
| 3805 | init_timer_deferrable(&gcwq->idle_timer); | 3823 | init_timer_deferrable(&gcwq->pool.idle_timer); |
| 3806 | gcwq->idle_timer.function = idle_worker_timeout; | 3824 | gcwq->pool.idle_timer.function = idle_worker_timeout; |
| 3807 | gcwq->idle_timer.data = (unsigned long)gcwq; | 3825 | gcwq->pool.idle_timer.data = (unsigned long)gcwq; |
| 3808 | 3826 | ||
| 3809 | setup_timer(&gcwq->mayday_timer, gcwq_mayday_timeout, | 3827 | setup_timer(&gcwq->pool.mayday_timer, gcwq_mayday_timeout, |
| 3810 | (unsigned long)gcwq); | 3828 | (unsigned long)gcwq); |
| 3811 | 3829 | ||
| 3812 | ida_init(&gcwq->worker_ida); | 3830 | ida_init(&gcwq->pool.worker_ida); |
| 3813 | 3831 | ||
| 3814 | gcwq->trustee_state = TRUSTEE_DONE; | 3832 | gcwq->trustee_state = TRUSTEE_DONE; |
| 3815 | init_waitqueue_head(&gcwq->trustee_wait); | 3833 | init_waitqueue_head(&gcwq->trustee_wait); |
