Modify all functions which deal with per-pool properties to pass around @pool instead of @gcwq or @cpu. The changes in this patch are mechanical and don't caues any functional difference. This is to prepare for multiple pools per gcwq.
Showing the changes to kernel/workqueue.c (1 of 1 file). Show all
Unified · Split
| @@ -471,8 +471,10 @@ static struct global_cwq *get_gcwq(unsigned int cpu) · 470 unmodified lines | |||
| 471 | return &unbound_global_cwq; | 471 | return &unbound_global_cwq; |
| 472 | } | 472 | } |
| 473 | 473 | ||
| 474 | static atomic_t *get_gcwq_nr_running(unsigned int cpu) | 474 | static atomic_t *get_pool_nr_running(struct worker_pool *pool) |
| 475 | { | 475 | { |
| 476 | int cpu = pool->gcwq->cpu; | ||
| 477 | |||
| 476 | if (cpu != WORK_CPU_UNBOUND) | 478 | if (cpu != WORK_CPU_UNBOUND) |
| 477 | return &per_cpu(gcwq_nr_running, cpu); | 479 | return &per_cpu(gcwq_nr_running, cpu); |
| 478 | else | 480 | else |
| @@ -578,10 +580,10 @@ static struct global_cwq *get_work_gcwq(struct work_struct *work) · 99 unmodified lines | |||
| 578 | * assume that they're being called with gcwq->lock held. | 580 | * assume that they're being called with gcwq->lock held. |
| 579 | */ | 581 | */ |
| 580 | 582 | ||
| 581 | static bool __need_more_worker(struct global_cwq *gcwq) | 583 | static bool __need_more_worker(struct worker_pool *pool) |
| 582 | { | 584 | { |
| 583 | return !atomic_read(get_gcwq_nr_running(gcwq->cpu)) || | 585 | return !atomic_read(get_pool_nr_running(pool)) || |
| 584 | gcwq->flags & GCWQ_HIGHPRI_PENDING; | 586 | pool->gcwq->flags & GCWQ_HIGHPRI_PENDING; |
| 585 | } | 587 | } |
| 586 | 588 | ||
| 587 | /* | 589 | /* |
| @@ -592,45 +594,46 @@ static bool __need_more_worker(struct global_cwq *gcwq) · 4 unmodified lines | |||
| 592 | * function will always return %true for unbound gcwq as long as the | 594 | * function will always return %true for unbound gcwq as long as the |
| 593 | * worklist isn't empty. | 595 | * worklist isn't empty. |
| 594 | */ | 596 | */ |
| 595 | static bool need_more_worker(struct global_cwq *gcwq) | 597 | static bool need_more_worker(struct worker_pool *pool) |
| 596 | { | 598 | { |
| 597 | return !list_empty(&gcwq->pool.worklist) && __need_more_worker(gcwq); | 599 | return !list_empty(&pool->worklist) && __need_more_worker(pool); |
| 598 | } | 600 | } |
| 599 | 601 | ||
| 600 | /* Can I start working? Called from busy but !running workers. */ | 602 | /* Can I start working? Called from busy but !running workers. */ |
| 601 | static bool may_start_working(struct global_cwq *gcwq) | 603 | static bool may_start_working(struct worker_pool *pool) |
| 602 | { | 604 | { |
| 603 | return gcwq->pool.nr_idle; | 605 | return pool->nr_idle; |
| 604 | } | 606 | } |
| 605 | 607 | ||
| 606 | /* Do I need to keep working? Called from currently running workers. */ | 608 | /* Do I need to keep working? Called from currently running workers. */ |
| 607 | static bool keep_working(struct global_cwq *gcwq) | 609 | static bool keep_working(struct worker_pool *pool) |
| 608 | { | 610 | { |
| 609 | atomic_t *nr_running = get_gcwq_nr_running(gcwq->cpu); | 611 | atomic_t *nr_running = get_pool_nr_running(pool); |
| 610 | 612 | ||
| 611 | return !list_empty(&gcwq->pool.worklist) && | 613 | return !list_empty(&pool->worklist) && |
| 612 | (atomic_read(nr_running) <= 1 || | 614 | (atomic_read(nr_running) <= 1 || |
| 613 | gcwq->flags & GCWQ_HIGHPRI_PENDING); | 615 | pool->gcwq->flags & GCWQ_HIGHPRI_PENDING); |
| 614 | } | 616 | } |
| 615 | 617 | ||
| 616 | /* Do we need a new worker? Called from manager. */ | 618 | /* Do we need a new worker? Called from manager. */ |
| 617 | static bool need_to_create_worker(struct global_cwq *gcwq) | 619 | static bool need_to_create_worker(struct worker_pool *pool) |
| 618 | { | 620 | { |
| 619 | return need_more_worker(gcwq) && !may_start_working(gcwq); | 621 | return need_more_worker(pool) && !may_start_working(pool); |
| 620 | } | 622 | } |
| 621 | 623 | ||
| 622 | /* Do I need to be the manager? */ | 624 | /* Do I need to be the manager? */ |
| 623 | static bool need_to_manage_workers(struct global_cwq *gcwq) | 625 | static bool need_to_manage_workers(struct worker_pool *pool) |
| 624 | { | 626 | { |
| 625 | return need_to_create_worker(gcwq) || gcwq->flags & GCWQ_MANAGE_WORKERS; | 627 | return need_to_create_worker(pool) || |
| 628 | pool->gcwq->flags & GCWQ_MANAGE_WORKERS; | ||
| 626 | } | 629 | } |
| 627 | 630 | ||
| 628 | /* Do we have too many workers and should some go away? */ | 631 | /* Do we have too many workers and should some go away? */ |
| 629 | static bool too_many_workers(struct global_cwq *gcwq) | 632 | static bool too_many_workers(struct worker_pool *pool) |
| 630 | { | 633 | { |
| 631 | bool managing = gcwq->flags & GCWQ_MANAGING_WORKERS; | 634 | bool managing = pool->gcwq->flags & GCWQ_MANAGING_WORKERS; |
| 632 | int nr_idle = gcwq->pool.nr_idle + managing; /* manager is considered idle */ | 635 | int nr_idle = pool->nr_idle + managing; /* manager is considered idle */ |
| 633 | int nr_busy = gcwq->pool.nr_workers - nr_idle; | 636 | int nr_busy = pool->nr_workers - nr_idle; |
| 634 | 637 | ||
| 635 | return nr_idle > 2 && (nr_idle - 2) * MAX_IDLE_WORKERS_RATIO >= nr_busy; | 638 | return nr_idle > 2 && (nr_idle - 2) * MAX_IDLE_WORKERS_RATIO >= nr_busy; |
| 636 | } | 639 | } |
| @@ -640,26 +643,26 @@ static bool too_many_workers(struct global_cwq *gcwq) · 3 unmodified lines | |||
| 640 | */ | 643 | */ |
| 641 | 644 | ||
| 642 | /* Return the first worker. Safe with preemption disabled */ | 645 | /* Return the first worker. Safe with preemption disabled */ |
| 643 | static struct worker *first_worker(struct global_cwq *gcwq) | 646 | static struct worker *first_worker(struct worker_pool *pool) |
| 644 | { | 647 | { |
| 645 | if (unlikely(list_empty(&gcwq->pool.idle_list))) | 648 | if (unlikely(list_empty(&pool->idle_list))) |
| 646 | return NULL; | 649 | return NULL; |
| 647 | 650 | ||
| 648 | return list_first_entry(&gcwq->pool.idle_list, struct worker, entry); | 651 | return list_first_entry(&pool->idle_list, struct worker, entry); |
| 649 | } | 652 | } |
| 650 | 653 | ||
| 651 | /** | 654 | /** |
| 652 | * wake_up_worker - wake up an idle worker | 655 | * wake_up_worker - wake up an idle worker |
| 653 | * @gcwq: gcwq to wake worker for | 656 | * @pool: worker pool to wake worker from |
| 654 | * | 657 | * |
| 655 | * Wake up the first idle worker of @gcwq. | 658 | * Wake up the first idle worker of @pool. |
| 656 | * | 659 | * |
| 657 | * CONTEXT: | 660 | * CONTEXT: |
| 658 | * spin_lock_irq(gcwq->lock). | 661 | * spin_lock_irq(gcwq->lock). |
| 659 | */ | 662 | */ |
| 660 | static void wake_up_worker(struct global_cwq *gcwq) | 663 | static void wake_up_worker(struct worker_pool *pool) |
| 661 | { | 664 | { |
| 662 | struct worker *worker = first_worker(gcwq); | 665 | struct worker *worker = first_worker(pool); |
| 663 | 666 | ||
| 664 | if (likely(worker)) | 667 | if (likely(worker)) |
| 665 | wake_up_process(worker->task); | 668 | wake_up_process(worker->task); |
| @@ -681,7 +684,7 @@ void wq_worker_waking_up(struct task_struct *task, unsigned int cpu) · 15 unmodified lines | |||
| 681 | struct worker *worker = kthread_data(task); | 684 | struct worker *worker = kthread_data(task); |
| 682 | 685 | ||
| 683 | if (!(worker->flags & WORKER_NOT_RUNNING)) | 686 | if (!(worker->flags & WORKER_NOT_RUNNING)) |
| 684 | atomic_inc(get_gcwq_nr_running(cpu)); | 687 | atomic_inc(get_pool_nr_running(worker->pool)); |
| 685 | } | 688 | } |
| 686 | 689 | ||
| 687 | /** | 690 | /** |
| @@ -704,8 +707,7 @@ struct task_struct *wq_worker_sleeping(struct task_struct *task, · 16 unmodified lines | |||
| 704 | { | 707 | { |
| 705 | struct worker *worker = kthread_data(task), *to_wakeup = NULL; | 708 | struct worker *worker = kthread_data(task), *to_wakeup = NULL; |
| 706 | struct worker_pool *pool = worker->pool; | 709 | struct worker_pool *pool = worker->pool; |
| 707 | struct global_cwq *gcwq = pool->gcwq; | 710 | atomic_t *nr_running = get_pool_nr_running(pool); |
| 708 | atomic_t *nr_running = get_gcwq_nr_running(cpu); | ||
| 709 | 711 | ||
| 710 | if (worker->flags & WORKER_NOT_RUNNING) | 712 | if (worker->flags & WORKER_NOT_RUNNING) |
| 711 | return NULL; | 713 | return NULL; |
| @@ -725,7 +727,7 @@ struct task_struct *wq_worker_sleeping(struct task_struct *task, · 13 unmodified lines | |||
| 725 | * without gcwq lock is safe. | 727 | * without gcwq lock is safe. |
| 726 | */ | 728 | */ |
| 727 | if (atomic_dec_and_test(nr_running) && !list_empty(&pool->worklist)) | 729 | if (atomic_dec_and_test(nr_running) && !list_empty(&pool->worklist)) |
| 728 | to_wakeup = first_worker(gcwq); | 730 | to_wakeup = first_worker(pool); |
| 729 | return to_wakeup ? to_wakeup->task : NULL; | 731 | return to_wakeup ? to_wakeup->task : NULL; |
| 730 | } | 732 | } |
| 731 | 733 | ||
| @@ -746,7 +748,6 @@ static inline void worker_set_flags(struct worker *worker, unsigned int flags, · 14 unmodified lines | |||
| 746 | bool wakeup) | 748 | bool wakeup) |
| 747 | { | 749 | { |
| 748 | struct worker_pool *pool = worker->pool; | 750 | struct worker_pool *pool = worker->pool; |
| 749 | struct global_cwq *gcwq = pool->gcwq; | ||
| 750 | 751 | ||
| 751 | WARN_ON_ONCE(worker->task != current); | 752 | WARN_ON_ONCE(worker->task != current); |
| 752 | 753 | ||
| @@ -757,12 +758,12 @@ static inline void worker_set_flags(struct worker *worker, unsigned int flags, · 4 unmodified lines | |||
| 757 | */ | 758 | */ |
| 758 | if ((flags & WORKER_NOT_RUNNING) && | 759 | if ((flags & WORKER_NOT_RUNNING) && |
| 759 | !(worker->flags & WORKER_NOT_RUNNING)) { | 760 | !(worker->flags & WORKER_NOT_RUNNING)) { |
| 760 | atomic_t *nr_running = get_gcwq_nr_running(gcwq->cpu); | 761 | atomic_t *nr_running = get_pool_nr_running(pool); |
| 761 | 762 | ||
| 762 | if (wakeup) { | 763 | if (wakeup) { |
| 763 | if (atomic_dec_and_test(nr_running) && | 764 | if (atomic_dec_and_test(nr_running) && |
| 764 | !list_empty(&pool->worklist)) | 765 | !list_empty(&pool->worklist)) |
| 765 | wake_up_worker(gcwq); | 766 | wake_up_worker(pool); |
| 766 | } else | 767 | } else |
| 767 | atomic_dec(nr_running); | 768 | atomic_dec(nr_running); |
| 768 | } | 769 | } |
| @@ -782,7 +783,7 @@ static inline void worker_set_flags(struct worker *worker, unsigned int flags, · 13 unmodified lines | |||
| 782 | */ | 783 | */ |
| 783 | static inline void worker_clr_flags(struct worker *worker, unsigned int flags) | 784 | static inline void worker_clr_flags(struct worker *worker, unsigned int flags) |
| 784 | { | 785 | { |
| 785 | struct global_cwq *gcwq = worker->pool->gcwq; | 786 | struct worker_pool *pool = worker->pool; |
| 786 | unsigned int oflags = worker->flags; | 787 | unsigned int oflags = worker->flags; |
| 787 | 788 | ||
| 788 | WARN_ON_ONCE(worker->task != current); | 789 | WARN_ON_ONCE(worker->task != current); |
| @@ -796,7 +797,7 @@ static inline void worker_clr_flags(struct worker *worker, unsigned int flags) · 7 unmodified lines | |||
| 796 | */ | 797 | */ |
| 797 | if ((flags & WORKER_NOT_RUNNING) && (oflags & WORKER_NOT_RUNNING)) | 798 | if ((flags & WORKER_NOT_RUNNING) && (oflags & WORKER_NOT_RUNNING)) |
| 798 | if (!(worker->flags & WORKER_NOT_RUNNING)) | 799 | if (!(worker->flags & WORKER_NOT_RUNNING)) |
| 799 | atomic_inc(get_gcwq_nr_running(gcwq->cpu)); | 800 | atomic_inc(get_pool_nr_running(pool)); |
| 800 | } | 801 | } |
| 801 | 802 | ||
| 802 | /** | 803 | /** |
| @@ -880,15 +881,15 @@ static struct worker *find_worker_executing_work(struct global_cwq *gcwq, · 77 unmodified lines | |||
| 880 | } | 881 | } |
| 881 | 882 | ||
| 882 | /** | 883 | /** |
| 883 | * gcwq_determine_ins_pos - find insertion position | 884 | * pool_determine_ins_pos - find insertion position |
| 884 | * @gcwq: gcwq of interest | 885 | * @pool: pool of interest |
| 885 | * @cwq: cwq a work is being queued for | 886 | * @cwq: cwq a work is being queued for |
| 886 | * | 887 | * |
| 887 | * A work for @cwq is about to be queued on @gcwq, determine insertion | 888 | * A work for @cwq is about to be queued on @pool, determine insertion |
| 888 | * position for the work. If @cwq is for HIGHPRI wq, the work is | 889 | * position for the work. If @cwq is for HIGHPRI wq, the work is |
| 889 | * queued at the head of the queue but in FIFO order with respect to | 890 | * queued at the head of the queue but in FIFO order with respect to |
| 890 | * other HIGHPRI works; otherwise, at the end of the queue. This | 891 | * other HIGHPRI works; otherwise, at the end of the queue. This |
| 891 | * function also sets GCWQ_HIGHPRI_PENDING flag to hint @gcwq that | 892 | * function also sets GCWQ_HIGHPRI_PENDING flag to hint @pool that |
| 892 | * there are HIGHPRI works pending. | 893 | * there are HIGHPRI works pending. |
| 893 | * | 894 | * |
| 894 | * CONTEXT: | 895 | * CONTEXT: |
| @@ -897,22 +898,22 @@ static struct worker *find_worker_executing_work(struct global_cwq *gcwq, · 2 unmodified lines | |||
| 897 | * RETURNS: | 898 | * RETURNS: |
| 898 | * Pointer to inserstion position. | 899 | * Pointer to inserstion position. |
| 899 | */ | 900 | */ |
| 900 | static inline struct list_head *gcwq_determine_ins_pos(struct global_cwq *gcwq, | 901 | static inline struct list_head *pool_determine_ins_pos(struct worker_pool *pool, |
| 901 | struct cpu_workqueue_struct *cwq) | 902 | struct cpu_workqueue_struct *cwq) |
| 902 | { | 903 | { |
| 903 | struct work_struct *twork; | 904 | struct work_struct *twork; |
| 904 | 905 | ||
| 905 | if (likely(!(cwq->wq->flags & WQ_HIGHPRI))) | 906 | if (likely(!(cwq->wq->flags & WQ_HIGHPRI))) |
| 906 | return &gcwq->pool.worklist; | 907 | return &pool->worklist; |
| 907 | 908 | ||
| 908 | list_for_each_entry(twork, &gcwq->pool.worklist, entry) { | 909 | list_for_each_entry(twork, &pool->worklist, entry) { |
| 909 | struct cpu_workqueue_struct *tcwq = get_work_cwq(twork); | 910 | struct cpu_workqueue_struct *tcwq = get_work_cwq(twork); |
| 910 | 911 | ||
| 911 | if (!(tcwq->wq->flags & WQ_HIGHPRI)) | 912 | if (!(tcwq->wq->flags & WQ_HIGHPRI)) |
| 912 | break; | 913 | break; |
| 913 | } | 914 | } |
| 914 | 915 | ||
| 915 | gcwq->flags |= GCWQ_HIGHPRI_PENDING; | 916 | pool->gcwq->flags |= GCWQ_HIGHPRI_PENDING; |
| 916 | return &twork->entry; | 917 | return &twork->entry; |
| 917 | } | 918 | } |
| 918 | 919 | ||
| @@ -933,7 +934,7 @@ static void insert_work(struct cpu_workqueue_struct *cwq, · 14 unmodified lines | |||
| 933 | struct work_struct *work, struct list_head *head, | 934 | struct work_struct *work, struct list_head *head, |
| 934 | unsigned int extra_flags) | 935 | unsigned int extra_flags) |
| 935 | { | 936 | { |
| 936 | struct global_cwq *gcwq = cwq->pool->gcwq; | 937 | struct worker_pool *pool = cwq->pool; |
| 937 | 938 | ||
| 938 | /* we own @work, set data and link */ | 939 | /* we own @work, set data and link */ |
| 939 | set_work_cwq(work, cwq, extra_flags); | 940 | set_work_cwq(work, cwq, extra_flags); |
| @@ -953,8 +954,8 @@ static void insert_work(struct cpu_workqueue_struct *cwq, · 13 unmodified lines | |||
| 953 | */ | 954 | */ |
| 954 | smp_mb(); | 955 | smp_mb(); |
| 955 | 956 | ||
| 956 | if (__need_more_worker(gcwq)) | 957 | if (__need_more_worker(pool)) |
| 957 | wake_up_worker(gcwq); | 958 | wake_up_worker(pool); |
| 958 | } | 959 | } |
| 959 | 960 | ||
| 960 | /* | 961 | /* |
| @@ -1056,7 +1057,7 @@ static void __queue_work(unsigned int cpu, struct workqueue_struct *wq, · 95 unmodified lines | |||
| 1056 | if (likely(cwq->nr_active < cwq->max_active)) { | 1057 | if (likely(cwq->nr_active < cwq->max_active)) { |
| 1057 | trace_workqueue_activate_work(work); | 1058 | trace_workqueue_activate_work(work); |
| 1058 | cwq->nr_active++; | 1059 | cwq->nr_active++; |
| 1059 | worklist = gcwq_determine_ins_pos(gcwq, cwq); | 1060 | worklist = pool_determine_ins_pos(cwq->pool, cwq); |
| 1060 | } else { | 1061 | } else { |
| 1061 | work_flags |= WORK_STRUCT_DELAYED; | 1062 | work_flags |= WORK_STRUCT_DELAYED; |
| 1062 | worklist = &cwq->delayed_works; | 1063 | worklist = &cwq->delayed_works; |
| @@ -1221,7 +1222,7 @@ static void worker_enter_idle(struct worker *worker) · 158 unmodified lines | |||
| 1221 | list_add(&worker->entry, &pool->idle_list); | 1222 | list_add(&worker->entry, &pool->idle_list); |
| 1222 | 1223 | ||
| 1223 | if (likely(!(worker->flags & WORKER_ROGUE))) { | 1224 | if (likely(!(worker->flags & WORKER_ROGUE))) { |
| 1224 | if (too_many_workers(gcwq) && !timer_pending(&pool->idle_timer)) | 1225 | if (too_many_workers(pool) && !timer_pending(&pool->idle_timer)) |
| 1225 | mod_timer(&pool->idle_timer, | 1226 | mod_timer(&pool->idle_timer, |
| 1226 | jiffies + IDLE_WORKER_TIMEOUT); | 1227 | jiffies + IDLE_WORKER_TIMEOUT); |
| 1227 | } else | 1228 | } else |
| @@ -1234,7 +1235,7 @@ static void worker_enter_idle(struct worker *worker) · 6 unmodified lines | |||
| 1234 | */ | 1235 | */ |
| 1235 | WARN_ON_ONCE(gcwq->trustee_state == TRUSTEE_DONE && | 1236 | WARN_ON_ONCE(gcwq->trustee_state == TRUSTEE_DONE && |
| 1236 | pool->nr_workers == pool->nr_idle && | 1237 | pool->nr_workers == pool->nr_idle && |
| 1237 | atomic_read(get_gcwq_nr_running(gcwq->cpu))); | 1238 | atomic_read(get_pool_nr_running(pool))); |
| 1238 | } | 1239 | } |
| 1239 | 1240 | ||
| 1240 | /** | 1241 | /** |
| @@ -1356,10 +1357,10 @@ static struct worker *alloc_worker(void) · 115 unmodified lines | |||
| 1356 | 1357 | ||
| 1357 | /** | 1358 | /** |
| 1358 | * create_worker - create a new workqueue worker | 1359 | * create_worker - create a new workqueue worker |
| 1359 | * @gcwq: gcwq the new worker will belong to | 1360 | * @pool: pool the new worker will belong to |
| 1360 | * @bind: whether to set affinity to @cpu or not | 1361 | * @bind: whether to set affinity to @cpu or not |
| 1361 | * | 1362 | * |
| 1362 | * Create a new worker which is bound to @gcwq. The returned worker | 1363 | * Create a new worker which is bound to @pool. The returned worker |
| 1363 | * can be started by calling start_worker() or destroyed using | 1364 | * can be started by calling start_worker() or destroyed using |
| 1364 | * destroy_worker(). | 1365 | * destroy_worker(). |
| 1365 | * | 1366 | * |
| @@ -1369,10 +1370,10 @@ static struct worker *alloc_worker(void) · 3 unmodified lines | |||
| 1369 | * RETURNS: | 1370 | * RETURNS: |
| 1370 | * Pointer to the newly created worker. | 1371 | * Pointer to the newly created worker. |
| 1371 | */ | 1372 | */ |
| 1372 | static struct worker *create_worker(struct global_cwq *gcwq, bool bind) | 1373 | static struct worker *create_worker(struct worker_pool *pool, bool bind) |
| 1373 | { | 1374 | { |
| 1375 | struct global_cwq *gcwq = pool->gcwq; | ||
| 1374 | bool on_unbound_cpu = gcwq->cpu == WORK_CPU_UNBOUND; | 1376 | bool on_unbound_cpu = gcwq->cpu == WORK_CPU_UNBOUND; |
| 1375 | struct worker_pool *pool = &gcwq->pool; | ||
| 1376 | struct worker *worker = NULL; | 1377 | struct worker *worker = NULL; |
| 1377 | int id = -1; | 1378 | int id = -1; |
| 1378 | 1379 | ||
| @@ -1480,27 +1481,27 @@ static void destroy_worker(struct worker *worker) · 101 unmodified lines | |||
| 1480 | ida_remove(&pool->worker_ida, id); | 1481 | ida_remove(&pool->worker_ida, id); |
| 1481 | } | 1482 | } |
| 1482 | 1483 | ||
| 1483 | static void idle_worker_timeout(unsigned long __gcwq) | 1484 | static void idle_worker_timeout(unsigned long __pool) |
| 1484 | { | 1485 | { |
| 1485 | struct global_cwq *gcwq = (void *)__gcwq; | 1486 | struct worker_pool *pool = (void *)__pool; |
| 1487 | struct global_cwq *gcwq = pool->gcwq; | ||
| 1486 | 1488 | ||
| 1487 | spin_lock_irq(&gcwq->lock); | 1489 | spin_lock_irq(&gcwq->lock); |
| 1488 | 1490 | ||
| 1489 | if (too_many_workers(gcwq)) { | 1491 | if (too_many_workers(pool)) { |
| 1490 | struct worker *worker; | 1492 | struct worker *worker; |
| 1491 | unsigned long expires; | 1493 | unsigned long expires; |
| 1492 | 1494 | ||
| 1493 | /* idle_list is kept in LIFO order, check the last one */ | 1495 | /* idle_list is kept in LIFO order, check the last one */ |
| 1494 | worker = list_entry(gcwq->pool.idle_list.prev, struct worker, | 1496 | worker = list_entry(pool->idle_list.prev, struct worker, entry); |
| 1495 | entry); | ||
| 1496 | expires = worker->last_active + IDLE_WORKER_TIMEOUT; | 1497 | expires = worker->last_active + IDLE_WORKER_TIMEOUT; |
| 1497 | 1498 | ||
| 1498 | if (time_before(jiffies, expires)) | 1499 | if (time_before(jiffies, expires)) |
| 1499 | mod_timer(&gcwq->pool.idle_timer, expires); | 1500 | mod_timer(&pool->idle_timer, expires); |
| 1500 | else { | 1501 | else { |
| 1501 | /* it's been idle for too long, wake up manager */ | 1502 | /* it's been idle for too long, wake up manager */ |
| 1502 | gcwq->flags |= GCWQ_MANAGE_WORKERS; | 1503 | gcwq->flags |= GCWQ_MANAGE_WORKERS; |
| 1503 | wake_up_worker(gcwq); | 1504 | wake_up_worker(pool); |
| 1504 | } | 1505 | } |
| 1505 | } | 1506 | } |
| 1506 | 1507 | ||
| @@ -1526,37 +1527,38 @@ static bool send_mayday(struct work_struct *work) · 19 unmodified lines | |||
| 1526 | return true; | 1527 | return true; |
| 1527 | } | 1528 | } |
| 1528 | 1529 | ||
| 1529 | static void gcwq_mayday_timeout(unsigned long __gcwq) | 1530 | static void gcwq_mayday_timeout(unsigned long __pool) |
| 1530 | { | 1531 | { |
| 1531 | struct global_cwq *gcwq = (void *)__gcwq; | 1532 | struct worker_pool *pool = (void *)__pool; |
| 1533 | struct global_cwq *gcwq = pool->gcwq; | ||
| 1532 | struct work_struct *work; | 1534 | struct work_struct *work; |
| 1533 | 1535 | ||
| 1534 | spin_lock_irq(&gcwq->lock); | 1536 | spin_lock_irq(&gcwq->lock); |
| 1535 | 1537 | ||
| 1536 | if (need_to_create_worker(gcwq)) { | 1538 | if (need_to_create_worker(pool)) { |
| 1537 | /* | 1539 | /* |
| 1538 | * We've been trying to create a new worker but | 1540 | * We've been trying to create a new worker but |
| 1539 | * haven't been successful. We might be hitting an | 1541 | * haven't been successful. We might be hitting an |
| 1540 | * allocation deadlock. Send distress signals to | 1542 | * allocation deadlock. Send distress signals to |
| 1541 | * rescuers. | 1543 | * rescuers. |
| 1542 | */ | 1544 | */ |
| 1543 | list_for_each_entry(work, &gcwq->pool.worklist, entry) | 1545 | list_for_each_entry(work, &pool->worklist, entry) |
| 1544 | send_mayday(work); | 1546 | send_mayday(work); |
| 1545 | } | 1547 | } |
| 1546 | 1548 | ||
| 1547 | spin_unlock_irq(&gcwq->lock); | 1549 | spin_unlock_irq(&gcwq->lock); |
| 1548 | 1550 | ||
| 1549 | mod_timer(&gcwq->pool.mayday_timer, jiffies + MAYDAY_INTERVAL); | 1551 | mod_timer(&pool->mayday_timer, jiffies + MAYDAY_INTERVAL); |
| 1550 | } | 1552 | } |
| 1551 | 1553 | ||
| 1552 | /** | 1554 | /** |
| 1553 | * maybe_create_worker - create a new worker if necessary | 1555 | * maybe_create_worker - create a new worker if necessary |
| 1554 | * @gcwq: gcwq to create a new worker for | 1556 | * @pool: pool to create a new worker for |
| 1555 | * | 1557 | * |
| 1556 | * Create a new worker for @gcwq if necessary. @gcwq is guaranteed to | 1558 | * Create a new worker for @pool if necessary. @pool is guaranteed to |
| 1557 | * have at least one idle worker on return from this function. If | 1559 | * have at least one idle worker on return from this function. If |
| 1558 | * creating a new worker takes longer than MAYDAY_INTERVAL, mayday is | 1560 | * creating a new worker takes longer than MAYDAY_INTERVAL, mayday is |
| 1559 | * sent to all rescuers with works scheduled on @gcwq to resolve | 1561 | * sent to all rescuers with works scheduled on @pool to resolve |
| 1560 | * possible allocation deadlock. | 1562 | * possible allocation deadlock. |
| 1561 | * | 1563 | * |
| 1562 | * On return, need_to_create_worker() is guaranteed to be false and | 1564 | * On return, need_to_create_worker() is guaranteed to be false and |
| @@ -1571,52 +1573,54 @@ static void gcwq_mayday_timeout(unsigned long __gcwq) · 8 unmodified lines | |||
| 1571 | * false if no action was taken and gcwq->lock stayed locked, true | 1573 | * false if no action was taken and gcwq->lock stayed locked, true |
| 1572 | * otherwise. | 1574 | * otherwise. |
| 1573 | */ | 1575 | */ |
| 1574 | static bool maybe_create_worker(struct global_cwq *gcwq) | 1576 | static bool maybe_create_worker(struct worker_pool *pool) |
| 1575 | __releases(&gcwq->lock) | 1577 | __releases(&gcwq->lock) |
| 1576 | __acquires(&gcwq->lock) | 1578 | __acquires(&gcwq->lock) |
| 1577 | { | 1579 | { |
| 1578 | if (!need_to_create_worker(gcwq)) | 1580 | struct global_cwq *gcwq = pool->gcwq; |
| 1581 | |||
| 1582 | if (!need_to_create_worker(pool)) | ||
| 1579 | return false; | 1583 | return false; |
| 1580 | restart: | 1584 | restart: |
| 1581 | spin_unlock_irq(&gcwq->lock); | 1585 | spin_unlock_irq(&gcwq->lock); |
| 1582 | 1586 | ||
| 1583 | /* if we don't make progress in MAYDAY_INITIAL_TIMEOUT, call for help */ | 1587 | /* if we don't make progress in MAYDAY_INITIAL_TIMEOUT, call for help */ |
| 1584 | mod_timer(&gcwq->pool.mayday_timer, jiffies + MAYDAY_INITIAL_TIMEOUT); | 1588 | mod_timer(&pool->mayday_timer, jiffies + MAYDAY_INITIAL_TIMEOUT); |
| 1585 | 1589 | ||
| 1586 | while (true) { | 1590 | while (true) { |
| 1587 | struct worker *worker; | 1591 | struct worker *worker; |
| 1588 | 1592 | ||
| 1589 | worker = create_worker(gcwq, true); | 1593 | worker = create_worker(pool, true); |
| 1590 | if (worker) { | 1594 | if (worker) { |
| 1591 | del_timer_sync(&gcwq->pool.mayday_timer); | 1595 | del_timer_sync(&pool->mayday_timer); |
| 1592 | spin_lock_irq(&gcwq->lock); | 1596 | spin_lock_irq(&gcwq->lock); |
| 1593 | start_worker(worker); | 1597 | start_worker(worker); |
| 1594 | BUG_ON(need_to_create_worker(gcwq)); | 1598 | BUG_ON(need_to_create_worker(pool)); |
| 1595 | return true; | 1599 | return true; |
| 1596 | } | 1600 | } |
| 1597 | 1601 | ||
| 1598 | if (!need_to_create_worker(gcwq)) | 1602 | if (!need_to_create_worker(pool)) |
| 1599 | break; | 1603 | break; |
| 1600 | 1604 | ||
| 1601 | __set_current_state(TASK_INTERRUPTIBLE); | 1605 | __set_current_state(TASK_INTERRUPTIBLE); |
| 1602 | schedule_timeout(CREATE_COOLDOWN); | 1606 | schedule_timeout(CREATE_COOLDOWN); |
| 1603 | 1607 | ||
| 1604 | if (!need_to_create_worker(gcwq)) | 1608 | if (!need_to_create_worker(pool)) |
| 1605 | break; | 1609 | break; |
| 1606 | } | 1610 | } |
| 1607 | 1611 | ||
| 1608 | del_timer_sync(&gcwq->pool.mayday_timer); | 1612 | del_timer_sync(&pool->mayday_timer); |
| 1609 | spin_lock_irq(&gcwq->lock); | 1613 | spin_lock_irq(&gcwq->lock); |
| 1610 | if (need_to_create_worker(gcwq)) | 1614 | if (need_to_create_worker(pool)) |
| 1611 | goto restart; | 1615 | goto restart; |
| 1612 | return true; | 1616 | return true; |
| 1613 | } | 1617 | } |
| 1614 | 1618 | ||
| 1615 | /** | 1619 | /** |
| 1616 | * maybe_destroy_worker - destroy workers which have been idle for a while | 1620 | * maybe_destroy_worker - destroy workers which have been idle for a while |
| 1617 | * @gcwq: gcwq to destroy workers for | 1621 | * @pool: pool to destroy workers for |
| 1618 | * | 1622 | * |
| 1619 | * Destroy @gcwq workers which have been idle for longer than | 1623 | * Destroy @pool workers which have been idle for longer than |
| 1620 | * IDLE_WORKER_TIMEOUT. | 1624 | * IDLE_WORKER_TIMEOUT. |
| 1621 | * | 1625 | * |
| 1622 | * LOCKING: | 1626 | * LOCKING: |
| @@ -1627,20 +1631,19 @@ restart: · 4 unmodified lines | |||
| 1627 | * false if no action was taken and gcwq->lock stayed locked, true | 1631 | * false if no action was taken and gcwq->lock stayed locked, true |
| 1628 | * otherwise. | 1632 | * otherwise. |
| 1629 | */ | 1633 | */ |
| 1630 | static bool maybe_destroy_workers(struct global_cwq *gcwq) | 1634 | static bool maybe_destroy_workers(struct worker_pool *pool) |
| 1631 | { | 1635 | { |
| 1632 | bool ret = false; | 1636 | bool ret = false; |
| 1633 | 1637 | ||
| 1634 | while (too_many_workers(gcwq)) { | 1638 | while (too_many_workers(pool)) { |
| 1635 | struct worker *worker; | 1639 | struct worker *worker; |
| 1636 | unsigned long expires; | 1640 | unsigned long expires; |
| 1637 | 1641 | ||
| 1638 | worker = list_entry(gcwq->pool.idle_list.prev, struct worker, | 1642 | worker = list_entry(pool->idle_list.prev, struct worker, entry); |
| 1639 | entry); | ||
| 1640 | expires = worker->last_active + IDLE_WORKER_TIMEOUT; | 1643 | expires = worker->last_active + IDLE_WORKER_TIMEOUT; |
| 1641 | 1644 | ||
| 1642 | if (time_before(jiffies, expires)) { | 1645 | if (time_before(jiffies, expires)) { |
| 1643 | mod_timer(&gcwq->pool.idle_timer, expires); | 1646 | mod_timer(&pool->idle_timer, expires); |
| 1644 | break; | 1647 | break; |
| 1645 | } | 1648 | } |
| 1646 | 1649 | ||
| @@ -1673,7 +1676,8 @@ static bool maybe_destroy_workers(struct global_cwq *gcwq) · 26 unmodified lines | |||
| 1673 | */ | 1676 | */ |
| 1674 | static bool manage_workers(struct worker *worker) | 1677 | static bool manage_workers(struct worker *worker) |
| 1675 | { | 1678 | { |
| 1676 | struct global_cwq *gcwq = worker->pool->gcwq; | 1679 | struct worker_pool *pool = worker->pool; |
| 1680 | struct global_cwq *gcwq = pool->gcwq; | ||
| 1677 | bool ret = false; | 1681 | bool ret = false; |
| 1678 | 1682 | ||
| 1679 | if (gcwq->flags & GCWQ_MANAGING_WORKERS) | 1683 | if (gcwq->flags & GCWQ_MANAGING_WORKERS) |
| @@ -1686,8 +1690,8 @@ static bool manage_workers(struct worker *worker) · 6 unmodified lines | |||
| 1686 | * Destroy and then create so that may_start_working() is true | 1690 | * Destroy and then create so that may_start_working() is true |
| 1687 | * on return. | 1691 | * on return. |
| 1688 | */ | 1692 | */ |
| 1689 | ret |= maybe_destroy_workers(gcwq); | 1693 | ret |= maybe_destroy_workers(pool); |
| 1690 | ret |= maybe_create_worker(gcwq); | 1694 | ret |= maybe_create_worker(pool); |
| 1691 | 1695 | ||
| 1692 | gcwq->flags &= ~GCWQ_MANAGING_WORKERS; | 1696 | gcwq->flags &= ~GCWQ_MANAGING_WORKERS; |
| 1693 | 1697 | ||
| @@ -1746,7 +1750,7 @@ static void cwq_activate_first_delayed(struct cpu_workqueue_struct *cwq) · 52 unmodified lines | |||
| 1746 | { | 1750 | { |
| 1747 | struct work_struct *work = list_first_entry(&cwq->delayed_works, | 1751 | struct work_struct *work = list_first_entry(&cwq->delayed_works, |
| 1748 | struct work_struct, entry); | 1752 | struct work_struct, entry); |
| 1749 | struct list_head *pos = gcwq_determine_ins_pos(cwq->pool->gcwq, cwq); | 1753 | struct list_head *pos = pool_determine_ins_pos(cwq->pool, cwq); |
| 1750 | 1754 | ||
| 1751 | trace_workqueue_activate_work(work); | 1755 | trace_workqueue_activate_work(work); |
| 1752 | move_linked_works(work, pos, NULL); | 1756 | move_linked_works(work, pos, NULL); |
| @@ -1874,7 +1878,7 @@ __acquires(&gcwq->lock) · 121 unmodified lines | |||
| 1874 | 1878 | ||
| 1875 | if (!list_empty(&pool->worklist) && | 1879 | if (!list_empty(&pool->worklist) && |
| 1876 | get_work_cwq(nwork)->wq->flags & WQ_HIGHPRI) | 1880 | get_work_cwq(nwork)->wq->flags & WQ_HIGHPRI) |
| 1877 | wake_up_worker(gcwq); | 1881 | wake_up_worker(pool); |
| 1878 | else | 1882 | else |
| 1879 | gcwq->flags &= ~GCWQ_HIGHPRI_PENDING; | 1883 | gcwq->flags &= ~GCWQ_HIGHPRI_PENDING; |
| 1880 | } | 1884 | } |
| @@ -1890,8 +1894,8 @@ __acquires(&gcwq->lock) · 9 unmodified lines | |||
| 1890 | * Unbound gcwq isn't concurrency managed and work items should be | 1894 | * Unbound gcwq isn't concurrency managed and work items should be |
| 1891 | * executed ASAP. Wake up another worker if necessary. | 1895 | * executed ASAP. Wake up another worker if necessary. |
| 1892 | */ | 1896 | */ |
| 1893 | if ((worker->flags & WORKER_UNBOUND) && need_more_worker(gcwq)) | 1897 | if ((worker->flags & WORKER_UNBOUND) && need_more_worker(pool)) |
| 1894 | wake_up_worker(gcwq); | 1898 | wake_up_worker(pool); |
| 1895 | 1899 | ||
| 1896 | spin_unlock_irq(&gcwq->lock); | 1900 | spin_unlock_irq(&gcwq->lock); |
| 1897 | 1901 | ||
| @@ -1983,11 +1987,11 @@ woke_up: · 85 unmodified lines | |||
| 1983 | worker_leave_idle(worker); | 1987 | worker_leave_idle(worker); |
| 1984 | recheck: | 1988 | recheck: |
| 1985 | /* no more worker necessary? */ | 1989 | /* no more worker necessary? */ |
| 1986 | if (!need_more_worker(gcwq)) | 1990 | if (!need_more_worker(pool)) |
| 1987 | goto sleep; | 1991 | goto sleep; |
| 1988 | 1992 | ||
| 1989 | /* do we need to manage? */ | 1993 | /* do we need to manage? */ |
| 1990 | if (unlikely(!may_start_working(gcwq)) && manage_workers(worker)) | 1994 | if (unlikely(!may_start_working(pool)) && manage_workers(worker)) |
| 1991 | goto recheck; | 1995 | goto recheck; |
| 1992 | 1996 | ||
| 1993 | /* | 1997 | /* |
| @@ -2018,11 +2022,11 @@ recheck: · 24 unmodified lines | |||
| 2018 | move_linked_works(work, &worker->scheduled, NULL); | 2022 | move_linked_works(work, &worker->scheduled, NULL); |
| 2019 | process_scheduled_works(worker); | 2023 | process_scheduled_works(worker); |
| 2020 | } | 2024 | } |
| 2021 | } while (keep_working(gcwq)); | 2025 | } while (keep_working(pool)); |
| 2022 | 2026 | ||
| 2023 | worker_set_flags(worker, WORKER_PREP, false); | 2027 | worker_set_flags(worker, WORKER_PREP, false); |
| 2024 | sleep: | 2028 | sleep: |
| 2025 | if (unlikely(need_to_manage_workers(gcwq)) && manage_workers(worker)) | 2029 | if (unlikely(need_to_manage_workers(pool)) && manage_workers(worker)) |
| 2026 | goto recheck; | 2030 | goto recheck; |
| 2027 | 2031 | ||
| 2028 | /* | 2032 | /* |
| @@ -2107,8 +2111,8 @@ repeat: · 78 unmodified lines | |||
| 2107 | * regular worker; otherwise, we end up with 0 concurrency | 2111 | * regular worker; otherwise, we end up with 0 concurrency |
| 2108 | * and stalling the execution. | 2112 | * and stalling the execution. |
| 2109 | */ | 2113 | */ |
| 2110 | if (keep_working(gcwq)) | 2114 | if (keep_working(pool)) |
| 2111 | wake_up_worker(gcwq); | 2115 | wake_up_worker(pool); |
| 2112 | 2116 | ||
| 2113 | spin_unlock_irq(&gcwq->lock); | 2117 | spin_unlock_irq(&gcwq->lock); |
| 2114 | } | 2118 | } |
| @@ -3383,7 +3387,7 @@ static int __cpuinit trustee_thread(void *__gcwq) · 1268 unmodified lines | |||
| 3383 | * keep_working() are always true as long as the worklist is | 3387 | * keep_working() are always true as long as the worklist is |
| 3384 | * not empty. | 3388 | * not empty. |
| 3385 | */ | 3389 | */ |
| 3386 | atomic_set(get_gcwq_nr_running(gcwq->cpu), 0); | 3390 | atomic_set(get_pool_nr_running(&gcwq->pool), 0); |
| 3387 | 3391 | ||
| 3388 | spin_unlock_irq(&gcwq->lock); | 3392 | spin_unlock_irq(&gcwq->lock); |
| 3389 | del_timer_sync(&gcwq->pool.idle_timer); | 3393 | del_timer_sync(&gcwq->pool.idle_timer); |
| @@ -3424,9 +3428,9 @@ static int __cpuinit trustee_thread(void *__gcwq) · 34 unmodified lines | |||
| 3424 | wake_up_process(worker->task); | 3428 | wake_up_process(worker->task); |
| 3425 | } | 3429 | } |
| 3426 | 3430 | ||
| 3427 | if (need_to_create_worker(gcwq)) { | 3431 | if (need_to_create_worker(&gcwq->pool)) { |
| 3428 | spin_unlock_irq(&gcwq->lock); | 3432 | spin_unlock_irq(&gcwq->lock); |
| 3429 | worker = create_worker(gcwq, false); | 3433 | worker = create_worker(&gcwq->pool, false); |
| 3430 | spin_lock_irq(&gcwq->lock); | 3434 | spin_lock_irq(&gcwq->lock); |
| 3431 | if (worker) { | 3435 | if (worker) { |
| 3432 | worker->flags |= WORKER_ROGUE; | 3436 | worker->flags |= WORKER_ROGUE; |
| @@ -3540,7 +3544,7 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb, · 107 unmodified lines | |||
| 3540 | /* fall through */ | 3544 | /* fall through */ |
| 3541 | case CPU_UP_PREPARE: | 3545 | case CPU_UP_PREPARE: |
| 3542 | BUG_ON(gcwq->pool.first_idle); | 3546 | BUG_ON(gcwq->pool.first_idle); |
| 3543 | new_worker = create_worker(gcwq, false); | 3547 | new_worker = create_worker(&gcwq->pool, false); |
| 3544 | if (!new_worker) { | 3548 | if (!new_worker) { |
| 3545 | if (new_trustee) | 3549 | if (new_trustee) |
| 3546 | kthread_stop(new_trustee); | 3550 | kthread_stop(new_trustee); |
| @@ -3788,7 +3792,7 @@ void thaw_workqueues(void) · 241 unmodified lines | |||
| 3788 | cwq_activate_first_delayed(cwq); | 3792 | cwq_activate_first_delayed(cwq); |
| 3789 | } | 3793 | } |
| 3790 | 3794 | ||
| 3791 | wake_up_worker(gcwq); | 3795 | wake_up_worker(&gcwq->pool); |
| 3792 | 3796 | ||
| 3793 | spin_unlock_irq(&gcwq->lock); | 3797 | spin_unlock_irq(&gcwq->lock); |
| 3794 | } | 3798 | } |
| @@ -3822,10 +3826,10 @@ static int __init init_workqueues(void) · 27 unmodified lines | |||
| 3822 | 3826 | ||
| 3823 | init_timer_deferrable(&gcwq->pool.idle_timer); | 3827 | init_timer_deferrable(&gcwq->pool.idle_timer); |
| 3824 | gcwq->pool.idle_timer.function = idle_worker_timeout; | 3828 | gcwq->pool.idle_timer.function = idle_worker_timeout; |
| 3825 | gcwq->pool.idle_timer.data = (unsigned long)gcwq; | 3829 | gcwq->pool.idle_timer.data = (unsigned long)&gcwq->pool; |
| 3826 | 3830 | ||
| 3827 | setup_timer(&gcwq->pool.mayday_timer, gcwq_mayday_timeout, | 3831 | setup_timer(&gcwq->pool.mayday_timer, gcwq_mayday_timeout, |
| 3828 | (unsigned long)gcwq); | 3832 | (unsigned long)&gcwq->pool); |
| 3829 | 3833 | ||
| 3830 | ida_init(&gcwq->pool.worker_ida); | 3834 | ida_init(&gcwq->pool.worker_ida); |
| 3831 | 3835 | ||
| @@ -3840,7 +3844,7 @@ static int __init init_workqueues(void) · 8 unmodified lines | |||
| 3840 | 3844 | ||
| 3841 | if (cpu != WORK_CPU_UNBOUND) | 3845 | if (cpu != WORK_CPU_UNBOUND) |
| 3842 | gcwq->flags &= ~GCWQ_DISASSOCIATED; | 3846 | gcwq->flags &= ~GCWQ_DISASSOCIATED; |
| 3843 | worker = create_worker(gcwq, true); | 3847 | worker = create_worker(&gcwq->pool, true); |
| 3844 | BUG_ON(!worker); | 3848 | BUG_ON(!worker); |
| 3845 | spin_lock_irq(&gcwq->lock); | 3849 | spin_lock_irq(&gcwq->lock); |
| 3846 | start_worker(worker); | 3850 | start_worker(worker); |