Pull smp hotplug updates from Thomas Gleixner: "This is the next part of the hotplug rework. - Convert all notifiers with a priority assigned - Convert all CPU_STARTING/DYING notifiers The final removal of the STARTING/DYING infrastructure will happen when the merge window closes. Another 700 hundred line of unpenetrable maze gone :)" * 'smp-hotplug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (70 commits) timers/core: Correct callback order during CPU hot plug leds/trigger/cpu: Move from CPU_STARTING to ONLINE level powerpc/numa: Convert to hotplug state machine arm/perf: Fix hotplug state machine conversion irqchip/armada: Avoid unused function warnings ARC/time: Convert to hotplug state machine clocksource/atlas7: Convert to hotplug state machine clocksource/armada-370-xp: Convert to hotplug state machine clocksource/exynos_mct: Convert to hotplug state machine clocksource/arm_global_timer: Convert to hotplug state machine rcu: Convert rcutree to hotplug state machine KVM/arm/arm64/vgic-new: Convert to hotplug state machine smp/cfd: Convert core to hotplug state machine x86/x2apic: Convert to CPU hotplug state machine profile: Convert to hotplug state machine timers/core: Convert to hotplug state machine hrtimer: Convert to hotplug state machine x86/tboot: Convert to hotplug state machine arm64/armv8 deprecated: Convert to hotplug state machine hwtracing/coresight-etm4x: Convert to hotplug state machine ...
Showing the changes to kernel/workqueue.c (1 of 75 files). Show all
Unified · Split
| @@ -4607,84 +4607,65 @@ static void restore_unbound_workers_cpumask(struct worker_pool *pool, int cpu) · 4606 unmodified lines | ||
| 4607 | 4607 | WARN_ON_ONCE(set_cpus_allowed_ptr(worker->task, &cpumask) < 0); |
| 4608 | 4608 | } |
| 4609 | 4609 | |
| 4610 | −/* | |
| 4611 | − * Workqueues should be brought up before normal priority CPU notifiers. | |
| 4612 | − * This will be registered high priority CPU notifier. | |
| 4613 | − */ | |
| 4614 | −static int workqueue_cpu_up_callback(struct notifier_block *nfb, | |
| 4615 | − unsigned long action, | |
| 4616 | − void *hcpu) | |
| 4610 | +int workqueue_prepare_cpu(unsigned int cpu) | |
| 4611 | +{ | |
| 4612 | + struct worker_pool *pool; | |
| 4613 | + | |
| 4614 | + for_each_cpu_worker_pool(pool, cpu) { | |
| 4615 | + if (pool->nr_workers) | |
| 4616 | + continue; | |
| 4617 | + if (!create_worker(pool)) | |
| 4618 | + return -ENOMEM; | |
| 4619 | + } | |
| 4620 | + return 0; | |
| 4621 | +} | |
| 4622 | + | |
| 4623 | +int workqueue_online_cpu(unsigned int cpu) | |
| 4617 | 4624 | { |
| 4618 | − int cpu = (unsigned long)hcpu; | |
| 4619 | 4625 | struct worker_pool *pool; |
| 4620 | 4626 | struct workqueue_struct *wq; |
| 4621 | 4627 | int pi; |
| 4622 | 4628 | |
| 4623 | − switch (action & ~CPU_TASKS_FROZEN) { | |
| 4624 | − case CPU_UP_PREPARE: | |
| 4625 | − for_each_cpu_worker_pool(pool, cpu) { | |
| 4626 | − if (pool->nr_workers) | |
| 4627 | − continue; | |
| 4628 | − if (!create_worker(pool)) | |
| 4629 | − return NOTIFY_BAD; | |
| 4630 | − } | |
| 4631 | − break; | |
| 4632 | − | |
| 4633 | − case CPU_DOWN_FAILED: | |
| 4634 | − case CPU_ONLINE: | |
| 4635 | − mutex_lock(&wq_pool_mutex); | |
| 4629 | + mutex_lock(&wq_pool_mutex); | |
| 4636 | 4630 | |
| 4637 | − for_each_pool(pool, pi) { | |
| 4638 | − mutex_lock(&pool->attach_mutex); | |
| 4631 | + for_each_pool(pool, pi) { | |
| 4632 | + mutex_lock(&pool->attach_mutex); | |
| 4639 | 4633 | |
| 4640 | − if (pool->cpu == cpu) | |
| 4641 | − rebind_workers(pool); | |
| 4642 | − else if (pool->cpu < 0) | |
| 4643 | − restore_unbound_workers_cpumask(pool, cpu); | |
| 4634 | + if (pool->cpu == cpu) | |
| 4635 | + rebind_workers(pool); | |
| 4636 | + else if (pool->cpu < 0) | |
| 4637 | + restore_unbound_workers_cpumask(pool, cpu); | |
| 4644 | 4638 | |
| 4645 | − mutex_unlock(&pool->attach_mutex); | |
| 4646 | − } | |
| 4639 | + mutex_unlock(&pool->attach_mutex); | |
| 4640 | + } | |
| 4647 | 4641 | |
| 4648 | − /* update NUMA affinity of unbound workqueues */ | |
| 4649 | − list_for_each_entry(wq, &workqueues, list) | |
| 4650 | − wq_update_unbound_numa(wq, cpu, true); | |
| 4642 | + /* update NUMA affinity of unbound workqueues */ | |
| 4643 | + list_for_each_entry(wq, &workqueues, list) | |
| 4644 | + wq_update_unbound_numa(wq, cpu, true); | |
| 4651 | 4645 | |
| 4652 | − mutex_unlock(&wq_pool_mutex); | |
| 4653 | − break; | |
| 4654 | − } | |
| 4655 | − return NOTIFY_OK; | |
| 4646 | + mutex_unlock(&wq_pool_mutex); | |
| 4647 | + return 0; | |
| 4656 | 4648 | } |
| 4657 | 4649 | |
| 4658 | −/* | |
| 4659 | − * Workqueues should be brought down after normal priority CPU notifiers. | |
| 4660 | − * This will be registered as low priority CPU notifier. | |
| 4661 | − */ | |
| 4662 | −static int workqueue_cpu_down_callback(struct notifier_block *nfb, | |
| 4663 | − unsigned long action, | |
| 4664 | − void *hcpu) | |
| 4650 | +int workqueue_offline_cpu(unsigned int cpu) | |
| 4665 | 4651 | { |
| 4666 | − int cpu = (unsigned long)hcpu; | |
| 4667 | 4652 | struct work_struct unbind_work; |
| 4668 | 4653 | struct workqueue_struct *wq; |
| 4669 | 4654 | |
| 4670 | − switch (action & ~CPU_TASKS_FROZEN) { | |
| 4671 | − case CPU_DOWN_PREPARE: | |
| 4672 | − /* unbinding per-cpu workers should happen on the local CPU */ | |
| 4673 | − INIT_WORK_ONSTACK(&unbind_work, wq_unbind_fn); | |
| 4674 | − queue_work_on(cpu, system_highpri_wq, &unbind_work); | |
| 4675 | − | |
| 4676 | − /* update NUMA affinity of unbound workqueues */ | |
| 4677 | − mutex_lock(&wq_pool_mutex); | |
| 4678 | − list_for_each_entry(wq, &workqueues, list) | |
| 4679 | − wq_update_unbound_numa(wq, cpu, false); | |
| 4680 | − mutex_unlock(&wq_pool_mutex); | |
| 4681 | − | |
| 4682 | − /* wait for per-cpu unbinding to finish */ | |
| 4683 | − flush_work(&unbind_work); | |
| 4684 | − destroy_work_on_stack(&unbind_work); | |
| 4685 | − break; | |
| 4686 | − } | |
| 4687 | − return NOTIFY_OK; | |
| 4655 | + /* unbinding per-cpu workers should happen on the local CPU */ | |
| 4656 | + INIT_WORK_ONSTACK(&unbind_work, wq_unbind_fn); | |
| 4657 | + queue_work_on(cpu, system_highpri_wq, &unbind_work); | |
| 4658 | + | |
| 4659 | + /* update NUMA affinity of unbound workqueues */ | |
| 4660 | + mutex_lock(&wq_pool_mutex); | |
| 4661 | + list_for_each_entry(wq, &workqueues, list) | |
| 4662 | + wq_update_unbound_numa(wq, cpu, false); | |
| 4663 | + mutex_unlock(&wq_pool_mutex); | |
| 4664 | + | |
| 4665 | + /* wait for per-cpu unbinding to finish */ | |
| 4666 | + flush_work(&unbind_work); | |
| 4667 | + destroy_work_on_stack(&unbind_work); | |
| 4668 | + return 0; | |
| 4688 | 4669 | } |
| 4689 | 4670 | |
| 4690 | 4671 | #ifdef CONFIG_SMP |
| @@ -5486,9 +5467,6 @@ static int __init init_workqueues(void) · 795 unmodified lines | ||
| 5486 | 5467 | |
| 5487 | 5468 | pwq_cache = KMEM_CACHE(pool_workqueue, SLAB_PANIC); |
| 5488 | 5469 | |
| 5489 | − cpu_notifier(workqueue_cpu_up_callback, CPU_PRI_WORKQUEUE_UP); | |
| 5490 | − hotcpu_notifier(workqueue_cpu_down_callback, CPU_PRI_WORKQUEUE_DOWN); | |
| 5491 | − | |
| 5492 | 5470 | wq_numa_init(); |
| 5493 | 5471 | |
| 5494 | 5472 | /* initialize CPU pools */ |