| @@ -21,6 +21,7 @@ · 20 unmodified lines |
| 21 | #include <linux/suspend.h> | 21 | #include <linux/suspend.h> |
| 22 | #include <linux/lockdep.h> | 22 | #include <linux/lockdep.h> |
| 23 | #include <linux/tick.h> | 23 | #include <linux/tick.h> |
| | 24 | #include <linux/irq.h> |
| 24 | #include <trace/events/power.h> | 25 | #include <trace/events/power.h> |
| 25 | | 26 | |
| 26 | #include "smpboot.h" | 27 | #include "smpboot.h" |
| @@ -392,13 +393,19 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) · 365 unmodified lines |
| 392 | smpboot_park_threads(cpu); | 393 | smpboot_park_threads(cpu); |
| 393 | | 394 | |
| 394 | /* | 395 | /* |
| 395 | * So now all preempt/rcu users must observe !cpu_active(). | 396 | * Prevent irq alloc/free while the dying cpu reorganizes the |
| | 397 | * interrupt affinities. |
| 396 | */ | 398 | */ |
| | 399 | irq_lock_sparse(); |
| 397 | | 400 | |
| | 401 | /* |
| | 402 | * So now all preempt/rcu users must observe !cpu_active(). |
| | 403 | */ |
| 398 | err = __stop_machine(take_cpu_down, &tcd_param, cpumask_of(cpu)); | 404 | err = __stop_machine(take_cpu_down, &tcd_param, cpumask_of(cpu)); |
| 399 | if (err) { | 405 | if (err) { |
| 400 | /* CPU didn't die: tell everyone. Can't complain. */ | 406 | /* CPU didn't die: tell everyone. Can't complain. */ |
| 401 | cpu_notify_nofail(CPU_DOWN_FAILED | mod, hcpu); | 407 | cpu_notify_nofail(CPU_DOWN_FAILED | mod, hcpu); |
| | 408 | irq_unlock_sparse(); |
| 402 | goto out_release; | 409 | goto out_release; |
| 403 | } | 410 | } |
| 404 | BUG_ON(cpu_online(cpu)); | 411 | BUG_ON(cpu_online(cpu)); |
| @@ -415,6 +422,9 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) · 10 unmodified lines |
| 415 | smp_mb(); /* Read from cpu_dead_idle before __cpu_die(). */ | 422 | smp_mb(); /* Read from cpu_dead_idle before __cpu_die(). */ |
| 416 | per_cpu(cpu_dead_idle, cpu) = false; | 423 | per_cpu(cpu_dead_idle, cpu) = false; |
| 417 | | 424 | |
| | 425 | /* Interrupts are moved away from the dying cpu, reenable alloc/free */ |
| | 426 | irq_unlock_sparse(); |
| | 427 | |
| 418 | hotplug_cpu__broadcast_tick_pull(cpu); | 428 | hotplug_cpu__broadcast_tick_pull(cpu); |
| 419 | /* This actually kills the CPU. */ | 429 | /* This actually kills the CPU. */ |
| 420 | __cpu_die(cpu); | 430 | __cpu_die(cpu); |
| @@ -517,8 +527,18 @@ static int _cpu_up(unsigned int cpu, int tasks_frozen) · 96 unmodified lines |
| 517 | goto out_notify; | 527 | goto out_notify; |
| 518 | } | 528 | } |
| 519 | | 529 | |
| | 530 | /* |
| | 531 | * Some architectures have to walk the irq descriptors to |
| | 532 | * setup the vector space for the cpu which comes online. |
| | 533 | * Prevent irq alloc/free across the bringup. |
| | 534 | */ |
| | 535 | irq_lock_sparse(); |
| | 536 | |
| 520 | /* Arch-specific enabling code. */ | 537 | /* Arch-specific enabling code. */ |
| 521 | ret = __cpu_up(cpu, idle); | 538 | ret = __cpu_up(cpu, idle); |
| | 539 | |
| | 540 | irq_unlock_sparse(); |
| | 541 | |
| 522 | if (ret != 0) | 542 | if (ret != 0) |
| 523 | goto out_notify; | 543 | goto out_notify; |
| 524 | BUG_ON(!cpu_online(cpu)); | 544 | BUG_ON(!cpu_online(cpu)); |