aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/workqueue.c149
1 files changed, 62 insertions, 87 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index c93651208760..fd400f8c9514 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -1670,10 +1670,10 @@ static void busy_worker_rebind_fn(struct work_struct *work)
1670} 1670}
1671 1671
1672/** 1672/**
1673 * rebind_workers - rebind all workers of a gcwq to the associated CPU 1673 * rebind_workers - rebind all workers of a pool to the associated CPU
1674 * @gcwq: gcwq of interest 1674 * @pool: pool of interest
1675 * 1675 *
1676 * @gcwq->cpu is coming online. Rebind all workers to the CPU. Rebinding 1676 * @pool->cpu is coming online. Rebind all workers to the CPU. Rebinding
1677 * is different for idle and busy ones. 1677 * is different for idle and busy ones.
1678 * 1678 *
1679 * Idle ones will be removed from the idle_list and woken up. They will 1679 * Idle ones will be removed from the idle_list and woken up. They will
@@ -1691,60 +1691,53 @@ static void busy_worker_rebind_fn(struct work_struct *work)
1691 * including the manager will not appear on @idle_list until rebind is 1691 * including the manager will not appear on @idle_list until rebind is
1692 * complete, making local wake-ups safe. 1692 * complete, making local wake-ups safe.
1693 */ 1693 */
1694static void rebind_workers(struct global_cwq *gcwq) 1694static void rebind_workers(struct worker_pool *pool)
1695{ 1695{
1696 struct worker_pool *pool;
1697 struct worker *worker, *n; 1696 struct worker *worker, *n;
1698 struct hlist_node *pos; 1697 struct hlist_node *pos;
1699 int i; 1698 int i;
1700 1699
1701 for_each_worker_pool(pool, gcwq) { 1700 lockdep_assert_held(&pool->assoc_mutex);
1702 lockdep_assert_held(&pool->assoc_mutex); 1701 lockdep_assert_held(&pool->lock);
1703 lockdep_assert_held(&pool->lock);
1704 }
1705 1702
1706 /* dequeue and kick idle ones */ 1703 /* dequeue and kick idle ones */
1707 for_each_worker_pool(pool, gcwq) { 1704 list_for_each_entry_safe(worker, n, &pool->idle_list, entry) {
1708 list_for_each_entry_safe(worker, n, &pool->idle_list, entry) { 1705 /*
1709 /* 1706 * idle workers should be off @pool->idle_list until rebind
1710 * idle workers should be off @pool->idle_list 1707 * is complete to avoid receiving premature local wake-ups.
1711 * until rebind is complete to avoid receiving 1708 */
1712 * premature local wake-ups. 1709 list_del_init(&worker->entry);
1713 */
1714 list_del_init(&worker->entry);
1715 1710
1716 /* 1711 /*
1717 * worker_thread() will see the above dequeuing 1712 * worker_thread() will see the above dequeuing and call
1718 * and call idle_worker_rebind(). 1713 * idle_worker_rebind().
1719 */ 1714 */
1720 wake_up_process(worker->task); 1715 wake_up_process(worker->task);
1721 } 1716 }
1722 1717
1723 /* rebind busy workers */ 1718 /* rebind busy workers */
1724 for_each_busy_worker(worker, i, pos, pool) { 1719 for_each_busy_worker(worker, i, pos, pool) {
1725 struct work_struct *rebind_work = &worker->rebind_work; 1720 struct work_struct *rebind_work = &worker->rebind_work;
1726 struct workqueue_struct *wq; 1721 struct workqueue_struct *wq;
1727 1722
1728 if (test_and_set_bit(WORK_STRUCT_PENDING_BIT, 1723 if (test_and_set_bit(WORK_STRUCT_PENDING_BIT,
1729 work_data_bits(rebind_work))) 1724 work_data_bits(rebind_work)))
1730 continue; 1725 continue;
1731 1726
1732 debug_work_activate(rebind_work); 1727 debug_work_activate(rebind_work);
1733 1728
1734 /* 1729 /*
1735 * wq doesn't really matter but let's keep 1730 * wq doesn't really matter but let's keep @worker->pool
1736 * @worker->pool and @cwq->pool consistent for 1731 * and @cwq->pool consistent for sanity.
1737 * sanity. 1732 */
1738 */ 1733 if (std_worker_pool_pri(worker->pool))
1739 if (std_worker_pool_pri(worker->pool)) 1734 wq = system_highpri_wq;
1740 wq = system_highpri_wq; 1735 else
1741 else 1736 wq = system_wq;
1742 wq = system_wq; 1737
1743 1738 insert_work(get_cwq(pool->cpu, wq), rebind_work,
1744 insert_work(get_cwq(pool->cpu, wq), rebind_work, 1739 worker->scheduled.next,
1745 worker->scheduled.next, 1740 work_color_to_flags(WORK_NO_COLOR));
1746 work_color_to_flags(WORK_NO_COLOR));
1747 }
1748 } 1741 }
1749} 1742}
1750 1743
@@ -3497,7 +3490,7 @@ EXPORT_SYMBOL_GPL(work_busy);
3497 * are a lot of assumptions on strong associations among work, cwq and 3490 * are a lot of assumptions on strong associations among work, cwq and
3498 * gcwq which make migrating pending and scheduled works very 3491 * gcwq which make migrating pending and scheduled works very
3499 * difficult to implement without impacting hot paths. Secondly, 3492 * difficult to implement without impacting hot paths. Secondly,
3500 * gcwqs serve mix of short, long and very long running works making 3493 * worker pools serve mix of short, long and very long running works making
3501 * blocked draining impractical. 3494 * blocked draining impractical.
3502 * 3495 *
3503 * This is solved by allowing the pools to be disassociated from the CPU 3496 * This is solved by allowing the pools to be disassociated from the CPU
@@ -3505,32 +3498,6 @@ EXPORT_SYMBOL_GPL(work_busy);
3505 * cpu comes back online. 3498 * cpu comes back online.
3506 */ 3499 */
3507 3500
3508/* claim manager positions of all pools */
3509static void gcwq_claim_assoc_and_lock(struct global_cwq *gcwq)
3510{
3511 struct worker_pool *pool;
3512
3513 for_each_worker_pool(pool, gcwq)
3514 mutex_lock_nested(&pool->assoc_mutex, pool - gcwq->pools);
3515
3516 local_irq_disable();
3517 for_each_worker_pool(pool, gcwq)
3518 spin_lock_nested(&pool->lock, pool - gcwq->pools);
3519}
3520
3521/* release manager positions */
3522static void gcwq_release_assoc_and_unlock(struct global_cwq *gcwq)
3523{
3524 struct worker_pool *pool;
3525
3526 for_each_worker_pool(pool, gcwq)
3527 spin_unlock(&pool->lock);
3528 local_irq_enable();
3529
3530 for_each_worker_pool(pool, gcwq)
3531 mutex_unlock(&pool->assoc_mutex);
3532}
3533
3534static void gcwq_unbind_fn(struct work_struct *work) 3501static void gcwq_unbind_fn(struct work_struct *work)
3535{ 3502{
3536 struct global_cwq *gcwq = get_gcwq(smp_processor_id()); 3503 struct global_cwq *gcwq = get_gcwq(smp_processor_id());
@@ -3539,17 +3506,19 @@ static void gcwq_unbind_fn(struct work_struct *work)
3539 struct hlist_node *pos; 3506 struct hlist_node *pos;
3540 int i; 3507 int i;
3541 3508
3542 BUG_ON(gcwq->pools[0].cpu != smp_processor_id()); 3509 for_each_worker_pool(pool, gcwq) {
3510 BUG_ON(pool->cpu != smp_processor_id());
3543 3511
3544 gcwq_claim_assoc_and_lock(gcwq); 3512 mutex_lock(&pool->assoc_mutex);
3513 spin_lock_irq(&pool->lock);
3545 3514
3546 /* 3515 /*
3547 * We've claimed all manager positions. Make all workers unbound 3516 * We've claimed all manager positions. Make all workers
3548 * and set DISASSOCIATED. Before this, all workers except for the 3517 * unbound and set DISASSOCIATED. Before this, all workers
3549 * ones which are still executing works from before the last CPU 3518 * except for the ones which are still executing works from
3550 * down must be on the cpu. After this, they may become diasporas. 3519 * before the last CPU down must be on the cpu. After
3551 */ 3520 * this, they may become diasporas.
3552 for_each_worker_pool(pool, gcwq) { 3521 */
3553 list_for_each_entry(worker, &pool->idle_list, entry) 3522 list_for_each_entry(worker, &pool->idle_list, entry)
3554 worker->flags |= WORKER_UNBOUND; 3523 worker->flags |= WORKER_UNBOUND;
3555 3524
@@ -3557,9 +3526,10 @@ static void gcwq_unbind_fn(struct work_struct *work)
3557 worker->flags |= WORKER_UNBOUND; 3526 worker->flags |= WORKER_UNBOUND;
3558 3527
3559 pool->flags |= POOL_DISASSOCIATED; 3528 pool->flags |= POOL_DISASSOCIATED;
3560 }
3561 3529
3562 gcwq_release_assoc_and_unlock(gcwq); 3530 spin_unlock_irq(&pool->lock);
3531 mutex_unlock(&pool->assoc_mutex);
3532 }
3563 3533
3564 /* 3534 /*
3565 * Call schedule() so that we cross rq->lock and thus can guarantee 3535 * Call schedule() so that we cross rq->lock and thus can guarantee
@@ -3615,11 +3585,16 @@ static int __cpuinit workqueue_cpu_up_callback(struct notifier_block *nfb,
3615 3585
3616 case CPU_DOWN_FAILED: 3586 case CPU_DOWN_FAILED:
3617 case CPU_ONLINE: 3587 case CPU_ONLINE:
3618 gcwq_claim_assoc_and_lock(gcwq); 3588 for_each_worker_pool(pool, gcwq) {
3619 for_each_worker_pool(pool, gcwq) 3589 mutex_lock(&pool->assoc_mutex);
3590 spin_lock_irq(&pool->lock);
3591
3620 pool->flags &= ~POOL_DISASSOCIATED; 3592 pool->flags &= ~POOL_DISASSOCIATED;
3621 rebind_workers(gcwq); 3593 rebind_workers(pool);
3622 gcwq_release_assoc_and_unlock(gcwq); 3594
3595 spin_unlock_irq(&pool->lock);
3596 mutex_unlock(&pool->assoc_mutex);
3597 }
3623 break; 3598 break;
3624 } 3599 }
3625 return NOTIFY_OK; 3600 return NOTIFY_OK;