diff options
| author | Mark Brown <broonie@kernel.org> | 2015-08-27 20:30:46 +0100 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2015-08-27 20:30:46 +0100 |
| commit | 2002e90412df17ef7f714be62ed96a3c80b2f907 (patch) | |
| tree | 3dd03684f7436320ec64f9c702b5d057a25dca17 /kernel/cpu.c | |
| parent | 02a9547e9b3f10d73fde66f52fc8b2a375a300cd (diff) | |
| parent | 3b7ce99748f0d006f9d1aa85709872e7b46787f7 (diff) | |
| download | lwn-2002e90412df17ef7f714be62ed96a3c80b2f907.tar.gz lwn-2002e90412df17ef7f714be62ed96a3c80b2f907.zip | |
Merge branch 'topic/ics43432' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into asoc-gtm601
Diffstat (limited to 'kernel/cpu.c')
| -rw-r--r-- | kernel/cpu.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c index 9c9c9fab16cc..6a374544d495 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -21,6 +21,7 @@ #include <linux/suspend.h> #include <linux/lockdep.h> #include <linux/tick.h> +#include <linux/irq.h> #include <trace/events/power.h> #include "smpboot.h" @@ -392,13 +393,19 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) smpboot_park_threads(cpu); /* - * So now all preempt/rcu users must observe !cpu_active(). + * Prevent irq alloc/free while the dying cpu reorganizes the + * interrupt affinities. */ + irq_lock_sparse(); + /* + * So now all preempt/rcu users must observe !cpu_active(). + */ err = __stop_machine(take_cpu_down, &tcd_param, cpumask_of(cpu)); if (err) { /* CPU didn't die: tell everyone. Can't complain. */ cpu_notify_nofail(CPU_DOWN_FAILED | mod, hcpu); + irq_unlock_sparse(); goto out_release; } BUG_ON(cpu_online(cpu)); @@ -415,6 +422,9 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) smp_mb(); /* Read from cpu_dead_idle before __cpu_die(). */ per_cpu(cpu_dead_idle, cpu) = false; + /* Interrupts are moved away from the dying cpu, reenable alloc/free */ + irq_unlock_sparse(); + hotplug_cpu__broadcast_tick_pull(cpu); /* This actually kills the CPU. */ __cpu_die(cpu); @@ -517,8 +527,18 @@ static int _cpu_up(unsigned int cpu, int tasks_frozen) goto out_notify; } + /* + * Some architectures have to walk the irq descriptors to + * setup the vector space for the cpu which comes online. + * Prevent irq alloc/free across the bringup. + */ + irq_lock_sparse(); + /* Arch-specific enabling code. */ ret = __cpu_up(cpu, idle); + + irq_unlock_sparse(); + if (ret != 0) goto out_notify; BUG_ON(!cpu_online(cpu)); |
