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.
Unified · Split
| @@ -471,8 +471,10 @@ static struct global_cwq *get_gcwq(unsigned int cpu) · 470 unmodified lines | ||
| 471 | 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 | 478 | if (cpu != WORK_CPU_UNBOUND) |
| 477 | 479 | return &per_cpu(gcwq_nr_running, cpu); |
| 478 | 480 | else |
| @@ -578,10 +580,10 @@ static struct global_cwq *get_work_gcwq(struct work_struct *work) · 99 unmodified lines | ||
| 578 | 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)) || | |
| 584 | − gcwq->flags & GCWQ_HIGHPRI_PENDING; | |
| 585 | + return !atomic_read(get_pool_nr_running(pool)) || | |
| 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 | 594 | * function will always return %true for unbound gcwq as long as the |
| 593 | 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 | 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 | 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 | 614 | (atomic_read(nr_running) <= 1 || |
| 613 | − gcwq->flags & GCWQ_HIGHPRI_PENDING); | |
| 615 | + pool->gcwq->flags & GCWQ_HIGHPRI_PENDING); | |
| 614 | 616 | } |
| 615 | 617 | |
| 616 | 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 | 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 | 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; | |
| 632 | − int nr_idle = gcwq->pool.nr_idle + managing; /* manager is considered idle */ | |
| 633 | − int nr_busy = gcwq->pool.nr_workers - nr_idle; | |
| 634 | + bool managing = pool->gcwq->flags & GCWQ_MANAGING_WORKERS; | |
| 635 | + int nr_idle = pool->nr_idle + managing; /* manager is considered idle */ | |
| 636 | + int nr_busy = pool->nr_workers - nr_idle; | |
| 634 | 637 | |
| 635 | 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 | 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 | 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 | 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 | 660 | * CONTEXT: |
| 658 | 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 | 667 | if (likely(worker)) |
| 665 | 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 | 684 | struct worker *worker = kthread_data(task); |
| 682 | 685 | |
| 683 | 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 | 708 | struct worker *worker = kthread_data(task), *to_wakeup = NULL; |
| 706 | 709 | struct worker_pool *pool = worker->pool; |
| 707 | − struct global_cwq *gcwq = pool->gcwq; | |
| 708 | − atomic_t *nr_running = get_gcwq_nr_running(cpu); | |
| 710 | + atomic_t *nr_running = get_pool_nr_running(pool); | |
| 709 | 711 | |
| 710 | 712 | if (worker->flags & WORKER_NOT_RUNNING) |
| 711 | 713 | return NULL; |
| @@ -725,7 +727,7 @@ struct task_struct *wq_worker_sleeping(struct task_struct *task, · 13 unmodified lines | ||
| 725 | 727 | * without gcwq lock is safe. |
| 726 | 728 | */ |
| 727 | 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 | 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 | 748 | bool wakeup) |
| 747 | 749 | { |
| 748 | 750 | struct worker_pool *pool = worker->pool; |
| 749 | − struct global_cwq *gcwq = pool->gcwq; | |
| 750 | 751 | |
| 751 | 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 | 759 | if ((flags & WORKER_NOT_RUNNING) && |
| 759 | 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 | 763 | if (wakeup) { |
| 763 | 764 | if (atomic_dec_and_test(nr_running) && |
| 764 | 765 | !list_empty(&pool->worklist)) |
| 765 | − wake_up_worker(gcwq); | |
| 766 | + wake_up_worker(pool); | |
| 766 | 767 | } else |
| 767 | 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 | 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 | 787 | unsigned int oflags = worker->flags; |
| 787 | 788 | |
| 788 | 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 | 798 | if ((flags & WORKER_NOT_RUNNING) && (oflags & WORKER_NOT_RUNNING)) |
| 798 | 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 | − * @gcwq: gcwq of interest | |
| 884 | + * pool_determine_ins_pos - find insertion position | |
| 885 | + * @pool: pool of interest | |
| 885 | 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 | 889 | * position for the work. If @cwq is for HIGHPRI wq, the work is |
| 889 | 890 | * queued at the head of the queue but in FIFO order with respect to |
| 890 | 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 | 893 | * there are HIGHPRI works pending. |
| 893 | 894 | * |
| 894 | 895 | * CONTEXT: |
| @@ -897,22 +898,22 @@ static struct worker *find_worker_executing_work(struct global_cwq *gcwq, · 2 unmodified lines | ||
| 897 | 898 | * RETURNS: |
| 898 | 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 | 902 | struct cpu_workqueue_struct *cwq) |
| 902 | 903 | { |
| 903 | 904 | struct work_struct *twork; |
| 904 | 905 | |
| 905 | 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 | 910 | struct cpu_workqueue_struct *tcwq = get_work_cwq(twork); |
| 910 | 911 | |
| 911 | 912 | if (!(tcwq->wq->flags & WQ_HIGHPRI)) |
| 912 | 913 | break; |
| 913 | 914 | } |
| 914 | 915 | |
| 915 | − gcwq->flags |= GCWQ_HIGHPRI_PENDING; | |
| 916 | + pool->gcwq->flags |= GCWQ_HIGHPRI_PENDING; | |
| 916 | 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 | 934 | struct work_struct *work, struct list_head *head, |
| 934 | 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 | 939 | /* we own @work, set data and link */ |
| 939 | 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 | 955 | smp_mb(); |
| 955 | 956 | |
| 956 | − if (__need_more_worker(gcwq)) | |
| 957 | − wake_up_worker(gcwq); | |
| 957 | + if (__need_more_worker(pool)) | |
| 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 | 1057 | if (likely(cwq->nr_active < cwq->max_active)) { |
| 1057 | 1058 | trace_workqueue_activate_work(work); |
| 1058 | 1059 | cwq->nr_active++; |
| 1059 | − worklist = gcwq_determine_ins_pos(gcwq, cwq); | |
| 1060 | + worklist = pool_determine_ins_pos(cwq->pool, cwq); | |
| 1060 | 1061 | } else { |
| 1061 | 1062 | work_flags |= WORK_STRUCT_DELAYED; |
| 1062 | 1063 | worklist = &cwq->delayed_works; |
| @@ -1221,7 +1222,7 @@ static void worker_enter_idle(struct worker *worker) · 158 unmodified lines | ||
| 1221 | 1222 | list_add(&worker->entry, &pool->idle_list); |
| 1222 | 1223 | |
| 1223 | 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 | 1226 | mod_timer(&pool->idle_timer, |
| 1226 | 1227 | jiffies + IDLE_WORKER_TIMEOUT); |
| 1227 | 1228 | } else |
| @@ -1234,7 +1235,7 @@ static void worker_enter_idle(struct worker *worker) · 6 unmodified lines | ||
| 1234 | 1235 | */ |
| 1235 | 1236 | WARN_ON_ONCE(gcwq->trustee_state == TRUSTEE_DONE && |
| 1236 | 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 | 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 | 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 | 1364 | * can be started by calling start_worker() or destroyed using |
| 1364 | 1365 | * destroy_worker(). |
| 1365 | 1366 | * |
| @@ -1369,10 +1370,10 @@ static struct worker *alloc_worker(void) · 3 unmodified lines | ||
| 1369 | 1370 | * RETURNS: |
| 1370 | 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 | 1376 | bool on_unbound_cpu = gcwq->cpu == WORK_CPU_UNBOUND; |
| 1375 | − struct worker_pool *pool = &gcwq->pool; | |
| 1376 | 1377 | struct worker *worker = NULL; |
| 1377 | 1378 | int id = -1; |
| 1378 | 1379 | |
| @@ -1480,27 +1481,27 @@ static void destroy_worker(struct worker *worker) · 101 unmodified lines | ||
| 1480 | 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 | 1489 | spin_lock_irq(&gcwq->lock); |
| 1488 | 1490 | |
| 1489 | − if (too_many_workers(gcwq)) { | |
| 1491 | + if (too_many_workers(pool)) { | |
| 1490 | 1492 | struct worker *worker; |
| 1491 | 1493 | unsigned long expires; |
| 1492 | 1494 | |
| 1493 | 1495 | /* idle_list is kept in LIFO order, check the last one */ |
| 1494 | − worker = list_entry(gcwq->pool.idle_list.prev, struct worker, | |
| 1495 | − entry); | |
| 1496 | + worker = list_entry(pool->idle_list.prev, struct worker, entry); | |
| 1496 | 1497 | expires = worker->last_active + IDLE_WORKER_TIMEOUT; |
| 1497 | 1498 | |
| 1498 | 1499 | if (time_before(jiffies, expires)) |
| 1499 | − mod_timer(&gcwq->pool.idle_timer, expires); | |
| 1500 | + mod_timer(&pool->idle_timer, expires); | |
| 1500 | 1501 | else { |
| 1501 | 1502 | /* it's been idle for too long, wake up manager */ |
| 1502 | 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 | 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 | 1534 | struct work_struct *work; |
| 1533 | 1535 | |
| 1534 | 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 | 1540 | * We've been trying to create a new worker but |
| 1539 | 1541 | * haven't been successful. We might be hitting an |
| 1540 | 1542 | * allocation deadlock. Send distress signals to |
| 1541 | 1543 | * rescuers. |
| 1542 | 1544 | */ |
| 1543 | − list_for_each_entry(work, &gcwq->pool.worklist, entry) | |
| 1545 | + list_for_each_entry(work, &pool->worklist, entry) | |
| 1544 | 1546 | send_mayday(work); |
| 1545 | 1547 | } |
| 1546 | 1548 | |
| 1547 | 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 | 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 | 1559 | * have at least one idle worker on return from this function. If |
| 1558 | 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 | 1562 | * possible allocation deadlock. |
| 1561 | 1563 | * |
| 1562 | 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 | 1573 | * false if no action was taken and gcwq->lock stayed locked, true |
| 1572 | 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 | 1577 | __releases(&gcwq->lock) |
| 1576 | 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 | 1583 | return false; |
| 1580 | 1584 | restart: |
| 1581 | 1585 | spin_unlock_irq(&gcwq->lock); |
| 1582 | 1586 | |
| 1583 | 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 | 1590 | while (true) { |
| 1587 | 1591 | struct worker *worker; |
| 1588 | 1592 | |
| 1589 | − worker = create_worker(gcwq, true); | |
| 1593 | + worker = create_worker(pool, true); | |
| 1590 | 1594 | if (worker) { |
| 1591 | − del_timer_sync(&gcwq->pool.mayday_timer); | |
| 1595 | + del_timer_sync(&pool->mayday_timer); | |
| 1592 | 1596 | spin_lock_irq(&gcwq->lock); |
| 1593 | 1597 | start_worker(worker); |
| 1594 | − BUG_ON(need_to_create_worker(gcwq)); | |
| 1598 | + BUG_ON(need_to_create_worker(pool)); | |
| 1595 | 1599 | return true; |
| 1596 | 1600 | } |
| 1597 | 1601 | |
| 1598 | − if (!need_to_create_worker(gcwq)) | |
| 1602 | + if (!need_to_create_worker(pool)) | |
| 1599 | 1603 | break; |
| 1600 | 1604 | |
| 1601 | 1605 | __set_current_state(TASK_INTERRUPTIBLE); |
| 1602 | 1606 | schedule_timeout(CREATE_COOLDOWN); |
| 1603 | 1607 | |
| 1604 | − if (!need_to_create_worker(gcwq)) | |
| 1608 | + if (!need_to_create_worker(pool)) | |
| 1605 | 1609 | break; |
| 1606 | 1610 | } |
| 1607 | 1611 | |
| 1608 | − del_timer_sync(&gcwq->pool.mayday_timer); | |
| 1612 | + del_timer_sync(&pool->mayday_timer); | |
| 1609 | 1613 | spin_lock_irq(&gcwq->lock); |
| 1610 | − if (need_to_create_worker(gcwq)) | |
| 1614 | + if (need_to_create_worker(pool)) | |
| 1611 | 1615 | goto restart; |
| 1612 | 1616 | return true; |
| 1613 | 1617 | } |
| 1614 | 1618 | |
| 1615 | 1619 | /** |
| 1616 | 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 | 1624 | * IDLE_WORKER_TIMEOUT. |
| 1621 | 1625 | * |
| 1622 | 1626 | * LOCKING: |
| @@ -1627,20 +1631,19 @@ restart: · 4 unmodified lines | ||
| 1627 | 1631 | * false if no action was taken and gcwq->lock stayed locked, true |
| 1628 | 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 | 1636 | bool ret = false; |
| 1633 | 1637 | |
| 1634 | − while (too_many_workers(gcwq)) { | |
| 1638 | + while (too_many_workers(pool)) { | |
| 1635 | 1639 | struct worker *worker; |
| 1636 | 1640 | unsigned long expires; |
| 1637 | 1641 | |
| 1638 | − worker = list_entry(gcwq->pool.idle_list.prev, struct worker, | |
| 1639 | − entry); | |
| 1642 | + worker = list_entry(pool->idle_list.prev, struct worker, entry); | |
| 1640 | 1643 | expires = worker->last_active + IDLE_WORKER_TIMEOUT; |
| 1641 | 1644 | |
| 1642 | 1645 | if (time_before(jiffies, expires)) { |
| 1643 | − mod_timer(&gcwq->pool.idle_timer, expires); | |
| 1646 | + mod_timer(&pool->idle_timer, expires); | |
| 1644 | 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 | 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 | 1681 | bool ret = false; |
| 1678 | 1682 | |
| 1679 | 1683 | if (gcwq->flags & GCWQ_MANAGING_WORKERS) |
| @@ -1686,8 +1690,8 @@ static bool manage_workers(struct worker *worker) · 6 unmodified lines | ||
| 1686 | 1690 | * Destroy and then create so that may_start_working() is true |
| 1687 | 1691 | * on return. |
| 1688 | 1692 | */ |
| 1689 | − ret |= maybe_destroy_workers(gcwq); | |
| 1690 | − ret |= maybe_create_worker(gcwq); | |
| 1693 | + ret |= maybe_destroy_workers(pool); | |
| 1694 | + ret |= maybe_create_worker(pool); | |
| 1691 | 1695 | |
| 1692 | 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 | 1751 | struct work_struct *work = list_first_entry(&cwq->delayed_works, |
| 1748 | 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 | 1755 | trace_workqueue_activate_work(work); |
| 1752 | 1756 | move_linked_works(work, pos, NULL); |
| @@ -1874,7 +1878,7 @@ __acquires(&gcwq->lock) · 121 unmodified lines | ||
| 1874 | 1878 | |
| 1875 | 1879 | if (!list_empty(&pool->worklist) && |
| 1876 | 1880 | get_work_cwq(nwork)->wq->flags & WQ_HIGHPRI) |
| 1877 | − wake_up_worker(gcwq); | |
| 1881 | + wake_up_worker(pool); | |
| 1878 | 1882 | else |
| 1879 | 1883 | gcwq->flags &= ~GCWQ_HIGHPRI_PENDING; |
| 1880 | 1884 | } |
| @@ -1890,8 +1894,8 @@ __acquires(&gcwq->lock) · 9 unmodified lines | ||
| 1890 | 1894 | * Unbound gcwq isn't concurrency managed and work items should be |
| 1891 | 1895 | * executed ASAP. Wake up another worker if necessary. |
| 1892 | 1896 | */ |
| 1893 | − if ((worker->flags & WORKER_UNBOUND) && need_more_worker(gcwq)) | |
| 1894 | − wake_up_worker(gcwq); | |
| 1897 | + if ((worker->flags & WORKER_UNBOUND) && need_more_worker(pool)) | |
| 1898 | + wake_up_worker(pool); | |
| 1895 | 1899 | |
| 1896 | 1900 | spin_unlock_irq(&gcwq->lock); |
| 1897 | 1901 | |
| @@ -1983,11 +1987,11 @@ woke_up: · 85 unmodified lines | ||
| 1983 | 1987 | worker_leave_idle(worker); |
| 1984 | 1988 | recheck: |
| 1985 | 1989 | /* no more worker necessary? */ |
| 1986 | − if (!need_more_worker(gcwq)) | |
| 1990 | + if (!need_more_worker(pool)) | |
| 1987 | 1991 | goto sleep; |
| 1988 | 1992 | |
| 1989 | 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 | 1995 | goto recheck; |
| 1992 | 1996 | |
| 1993 | 1997 | /* |
| @@ -2018,11 +2022,11 @@ recheck: · 24 unmodified lines | ||
| 2018 | 2022 | move_linked_works(work, &worker->scheduled, NULL); |
| 2019 | 2023 | process_scheduled_works(worker); |
| 2020 | 2024 | } |
| 2021 | − } while (keep_working(gcwq)); | |
| 2025 | + } while (keep_working(pool)); | |
| 2022 | 2026 | |
| 2023 | 2027 | worker_set_flags(worker, WORKER_PREP, false); |
| 2024 | 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 | 2030 | goto recheck; |
| 2027 | 2031 | |
| 2028 | 2032 | /* |
| @@ -2107,8 +2111,8 @@ repeat: · 78 unmodified lines | ||
| 2107 | 2111 | * regular worker; otherwise, we end up with 0 concurrency |
| 2108 | 2112 | * and stalling the execution. |
| 2109 | 2113 | */ |
| 2110 | − if (keep_working(gcwq)) | |
| 2111 | − wake_up_worker(gcwq); | |
| 2114 | + if (keep_working(pool)) | |
| 2115 | + wake_up_worker(pool); | |
| 2112 | 2116 | |
| 2113 | 2117 | spin_unlock_irq(&gcwq->lock); |
| 2114 | 2118 | } |
| @@ -3383,7 +3387,7 @@ static int __cpuinit trustee_thread(void *__gcwq) · 1268 unmodified lines | ||
| 3383 | 3387 | * keep_working() are always true as long as the worklist is |
| 3384 | 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 | 3392 | spin_unlock_irq(&gcwq->lock); |
| 3389 | 3393 | del_timer_sync(&gcwq->pool.idle_timer); |
| @@ -3424,9 +3428,9 @@ static int __cpuinit trustee_thread(void *__gcwq) · 34 unmodified lines | ||
| 3424 | 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 | 3432 | spin_unlock_irq(&gcwq->lock); |
| 3429 | − worker = create_worker(gcwq, false); | |
| 3433 | + worker = create_worker(&gcwq->pool, false); | |
| 3430 | 3434 | spin_lock_irq(&gcwq->lock); |
| 3431 | 3435 | if (worker) { |
| 3432 | 3436 | worker->flags |= WORKER_ROGUE; |
| @@ -3540,7 +3544,7 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb, · 107 unmodified lines | ||
| 3540 | 3544 | /* fall through */ |
| 3541 | 3545 | case CPU_UP_PREPARE: |
| 3542 | 3546 | BUG_ON(gcwq->pool.first_idle); |
| 3543 | − new_worker = create_worker(gcwq, false); | |
| 3547 | + new_worker = create_worker(&gcwq->pool, false); | |
| 3544 | 3548 | if (!new_worker) { |
| 3545 | 3549 | if (new_trustee) |
| 3546 | 3550 | kthread_stop(new_trustee); |
| @@ -3788,7 +3792,7 @@ void thaw_workqueues(void) · 241 unmodified lines | ||
| 3788 | 3792 | cwq_activate_first_delayed(cwq); |
| 3789 | 3793 | } |
| 3790 | 3794 | |
| 3791 | − wake_up_worker(gcwq); | |
| 3795 | + wake_up_worker(&gcwq->pool); | |
| 3792 | 3796 | |
| 3793 | 3797 | spin_unlock_irq(&gcwq->lock); |
| 3794 | 3798 | } |
| @@ -3822,10 +3826,10 @@ static int __init init_workqueues(void) · 27 unmodified lines | ||
| 3822 | 3826 | |
| 3823 | 3827 | init_timer_deferrable(&gcwq->pool.idle_timer); |
| 3824 | 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 | 3831 | setup_timer(&gcwq->pool.mayday_timer, gcwq_mayday_timeout, |
| 3828 | − (unsigned long)gcwq); | |
| 3832 | + (unsigned long)&gcwq->pool); | |
| 3829 | 3833 | |
| 3830 | 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 | 3845 | if (cpu != WORK_CPU_UNBOUND) |
| 3842 | 3846 | gcwq->flags &= ~GCWQ_DISASSOCIATED; |
| 3843 | − worker = create_worker(gcwq, true); | |
| 3847 | + worker = create_worker(&gcwq->pool, true); | |
| 3844 | 3848 | BUG_ON(!worker); |
| 3845 | 3849 | spin_lock_irq(&gcwq->lock); |
| 3846 | 3850 | start_worker(worker); |