diff options
47 files changed, 152 insertions, 27 deletions
diff --git a/Documentation/cpu-hotplug.txt b/Documentation/cpu-hotplug.txt index cc60d29b954c..b6d24c22274b 100644 --- a/Documentation/cpu-hotplug.txt +++ b/Documentation/cpu-hotplug.txt | |||
@@ -217,14 +217,17 @@ Q: What happens when a CPU is being logically offlined? | |||
217 | A: The following happen, listed in no particular order :-) | 217 | A: The following happen, listed in no particular order :-) |
218 | 218 | ||
219 | - A notification is sent to in-kernel registered modules by sending an event | 219 | - A notification is sent to in-kernel registered modules by sending an event |
220 | CPU_DOWN_PREPARE | 220 | CPU_DOWN_PREPARE or CPU_DOWN_PREPARE_FROZEN, depending on whether or not the |
221 | CPU is being offlined while tasks are frozen due to a suspend operation in | ||
222 | progress | ||
221 | - All process is migrated away from this outgoing CPU to a new CPU | 223 | - All process is migrated away from this outgoing CPU to a new CPU |
222 | - All interrupts targeted to this CPU is migrated to a new CPU | 224 | - All interrupts targeted to this CPU is migrated to a new CPU |
223 | - timers/bottom half/task lets are also migrated to a new CPU | 225 | - timers/bottom half/task lets are also migrated to a new CPU |
224 | - Once all services are migrated, kernel calls an arch specific routine | 226 | - Once all services are migrated, kernel calls an arch specific routine |
225 | __cpu_disable() to perform arch specific cleanup. | 227 | __cpu_disable() to perform arch specific cleanup. |
226 | - Once this is successful, an event for successful cleanup is sent by an event | 228 | - Once this is successful, an event for successful cleanup is sent by an event |
227 | CPU_DEAD. | 229 | CPU_DEAD (or CPU_DEAD_FROZEN if tasks are frozen due to a suspend while the |
230 | CPU is being offlined). | ||
228 | 231 | ||
229 | "It is expected that each service cleans up when the CPU_DOWN_PREPARE | 232 | "It is expected that each service cleans up when the CPU_DOWN_PREPARE |
230 | notifier is called, when CPU_DEAD is called its expected there is nothing | 233 | notifier is called, when CPU_DEAD is called its expected there is nothing |
@@ -242,9 +245,11 @@ A: This is what you would need in your kernel code to receive notifications. | |||
242 | 245 | ||
243 | switch (action) { | 246 | switch (action) { |
244 | case CPU_ONLINE: | 247 | case CPU_ONLINE: |
248 | case CPU_ONLINE_FROZEN: | ||
245 | foobar_online_action(cpu); | 249 | foobar_online_action(cpu); |
246 | break; | 250 | break; |
247 | case CPU_DEAD: | 251 | case CPU_DEAD: |
252 | case CPU_DEAD_FROZEN: | ||
248 | foobar_dead_action(cpu); | 253 | foobar_dead_action(cpu); |
249 | break; | 254 | break; |
250 | } | 255 | } |
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c index 80b4c5d421b1..e5be819492ef 100644 --- a/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/arch/i386/kernel/cpu/intel_cacheinfo.c | |||
@@ -733,9 +733,11 @@ static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb, | |||
733 | sys_dev = get_cpu_sysdev(cpu); | 733 | sys_dev = get_cpu_sysdev(cpu); |
734 | switch (action) { | 734 | switch (action) { |
735 | case CPU_ONLINE: | 735 | case CPU_ONLINE: |
736 | case CPU_ONLINE_FROZEN: | ||
736 | cache_add_dev(sys_dev); | 737 | cache_add_dev(sys_dev); |
737 | break; | 738 | break; |
738 | case CPU_DEAD: | 739 | case CPU_DEAD: |
740 | case CPU_DEAD_FROZEN: | ||
739 | cache_remove_dev(sys_dev); | 741 | cache_remove_dev(sys_dev); |
740 | break; | 742 | break; |
741 | } | 743 | } |
diff --git a/arch/i386/kernel/cpu/mcheck/therm_throt.c b/arch/i386/kernel/cpu/mcheck/therm_throt.c index 065005c3f168..5b0a040213c2 100644 --- a/arch/i386/kernel/cpu/mcheck/therm_throt.c +++ b/arch/i386/kernel/cpu/mcheck/therm_throt.c | |||
@@ -137,10 +137,12 @@ static __cpuinit int thermal_throttle_cpu_callback(struct notifier_block *nfb, | |||
137 | mutex_lock(&therm_cpu_lock); | 137 | mutex_lock(&therm_cpu_lock); |
138 | switch (action) { | 138 | switch (action) { |
139 | case CPU_ONLINE: | 139 | case CPU_ONLINE: |
140 | case CPU_ONLINE_FROZEN: | ||
140 | err = thermal_throttle_add_dev(sys_dev); | 141 | err = thermal_throttle_add_dev(sys_dev); |
141 | WARN_ON(err); | 142 | WARN_ON(err); |
142 | break; | 143 | break; |
143 | case CPU_DEAD: | 144 | case CPU_DEAD: |
145 | case CPU_DEAD_FROZEN: | ||
144 | thermal_throttle_remove_dev(sys_dev); | 146 | thermal_throttle_remove_dev(sys_dev); |
145 | break; | 147 | break; |
146 | } | 148 | } |
diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c index eeae0d992337..5c2faa10e9fa 100644 --- a/arch/i386/kernel/cpuid.c +++ b/arch/i386/kernel/cpuid.c | |||
@@ -169,9 +169,11 @@ static int cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long ac | |||
169 | 169 | ||
170 | switch (action) { | 170 | switch (action) { |
171 | case CPU_ONLINE: | 171 | case CPU_ONLINE: |
172 | case CPU_ONLINE_FROZEN: | ||
172 | cpuid_device_create(cpu); | 173 | cpuid_device_create(cpu); |
173 | break; | 174 | break; |
174 | case CPU_DEAD: | 175 | case CPU_DEAD: |
176 | case CPU_DEAD_FROZEN: | ||
175 | device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu)); | 177 | device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu)); |
176 | break; | 178 | break; |
177 | } | 179 | } |
diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c index cbe7ec8dbb9f..7d934e493e74 100644 --- a/arch/i386/kernel/microcode.c +++ b/arch/i386/kernel/microcode.c | |||
@@ -775,10 +775,13 @@ mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) | |||
775 | sys_dev = get_cpu_sysdev(cpu); | 775 | sys_dev = get_cpu_sysdev(cpu); |
776 | switch (action) { | 776 | switch (action) { |
777 | case CPU_ONLINE: | 777 | case CPU_ONLINE: |
778 | case CPU_ONLINE_FROZEN: | ||
778 | case CPU_DOWN_FAILED: | 779 | case CPU_DOWN_FAILED: |
780 | case CPU_DOWN_FAILED_FROZEN: | ||
779 | mc_sysdev_add(sys_dev); | 781 | mc_sysdev_add(sys_dev); |
780 | break; | 782 | break; |
781 | case CPU_DOWN_PREPARE: | 783 | case CPU_DOWN_PREPARE: |
784 | case CPU_DOWN_PREPARE_FROZEN: | ||
782 | mc_sysdev_remove(sys_dev); | 785 | mc_sysdev_remove(sys_dev); |
783 | break; | 786 | break; |
784 | } | 787 | } |
diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c index 8cd0a91ce107..0c1069b8d638 100644 --- a/arch/i386/kernel/msr.c +++ b/arch/i386/kernel/msr.c | |||
@@ -153,9 +153,11 @@ static int msr_class_cpu_callback(struct notifier_block *nfb, | |||
153 | 153 | ||
154 | switch (action) { | 154 | switch (action) { |
155 | case CPU_ONLINE: | 155 | case CPU_ONLINE: |
156 | case CPU_ONLINE_FROZEN: | ||
156 | msr_device_create(cpu); | 157 | msr_device_create(cpu); |
157 | break; | 158 | break; |
158 | case CPU_DEAD: | 159 | case CPU_DEAD: |
160 | case CPU_DEAD_FROZEN: | ||
159 | device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); | 161 | device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); |
160 | break; | 162 | break; |
161 | } | 163 | } |
diff --git a/arch/ia64/kernel/err_inject.c b/arch/ia64/kernel/err_inject.c index d3e9f33e8bdd..6a49600cf337 100644 --- a/arch/ia64/kernel/err_inject.c +++ b/arch/ia64/kernel/err_inject.c | |||
@@ -236,9 +236,11 @@ static int __cpuinit err_inject_cpu_callback(struct notifier_block *nfb, | |||
236 | sys_dev = get_cpu_sysdev(cpu); | 236 | sys_dev = get_cpu_sysdev(cpu); |
237 | switch (action) { | 237 | switch (action) { |
238 | case CPU_ONLINE: | 238 | case CPU_ONLINE: |
239 | case CPU_ONLINE_FROZEN: | ||
239 | err_inject_add_dev(sys_dev); | 240 | err_inject_add_dev(sys_dev); |
240 | break; | 241 | break; |
241 | case CPU_DEAD: | 242 | case CPU_DEAD: |
243 | case CPU_DEAD_FROZEN: | ||
242 | err_inject_remove_dev(sys_dev); | 244 | err_inject_remove_dev(sys_dev); |
243 | break; | 245 | break; |
244 | } | 246 | } |
diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c index a71df9ae0397..85829e27785c 100644 --- a/arch/ia64/kernel/palinfo.c +++ b/arch/ia64/kernel/palinfo.c | |||
@@ -975,9 +975,11 @@ static int palinfo_cpu_callback(struct notifier_block *nfb, | |||
975 | 975 | ||
976 | switch (action) { | 976 | switch (action) { |
977 | case CPU_ONLINE: | 977 | case CPU_ONLINE: |
978 | case CPU_ONLINE_FROZEN: | ||
978 | create_palinfo_proc_entries(hotcpu); | 979 | create_palinfo_proc_entries(hotcpu); |
979 | break; | 980 | break; |
980 | case CPU_DEAD: | 981 | case CPU_DEAD: |
982 | case CPU_DEAD_FROZEN: | ||
981 | remove_palinfo_proc_entries(hotcpu); | 983 | remove_palinfo_proc_entries(hotcpu); |
982 | break; | 984 | break; |
983 | } | 985 | } |
diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c index a51f1d0bfb70..89f6b138a62c 100644 --- a/arch/ia64/kernel/salinfo.c +++ b/arch/ia64/kernel/salinfo.c | |||
@@ -582,6 +582,7 @@ salinfo_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu | |||
582 | struct salinfo_data *data; | 582 | struct salinfo_data *data; |
583 | switch (action) { | 583 | switch (action) { |
584 | case CPU_ONLINE: | 584 | case CPU_ONLINE: |
585 | case CPU_ONLINE_FROZEN: | ||
585 | spin_lock_irqsave(&data_saved_lock, flags); | 586 | spin_lock_irqsave(&data_saved_lock, flags); |
586 | for (i = 0, data = salinfo_data; | 587 | for (i = 0, data = salinfo_data; |
587 | i < ARRAY_SIZE(salinfo_data); | 588 | i < ARRAY_SIZE(salinfo_data); |
@@ -592,6 +593,7 @@ salinfo_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu | |||
592 | spin_unlock_irqrestore(&data_saved_lock, flags); | 593 | spin_unlock_irqrestore(&data_saved_lock, flags); |
593 | break; | 594 | break; |
594 | case CPU_DEAD: | 595 | case CPU_DEAD: |
596 | case CPU_DEAD_FROZEN: | ||
595 | spin_lock_irqsave(&data_saved_lock, flags); | 597 | spin_lock_irqsave(&data_saved_lock, flags); |
596 | for (i = 0, data = salinfo_data; | 598 | for (i = 0, data = salinfo_data; |
597 | i < ARRAY_SIZE(salinfo_data); | 599 | i < ARRAY_SIZE(salinfo_data); |
diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c index 687500ddb4b8..94ae3c87d828 100644 --- a/arch/ia64/kernel/topology.c +++ b/arch/ia64/kernel/topology.c | |||
@@ -412,9 +412,11 @@ static int __cpuinit cache_cpu_callback(struct notifier_block *nfb, | |||
412 | sys_dev = get_cpu_sysdev(cpu); | 412 | sys_dev = get_cpu_sysdev(cpu); |
413 | switch (action) { | 413 | switch (action) { |
414 | case CPU_ONLINE: | 414 | case CPU_ONLINE: |
415 | case CPU_ONLINE_FROZEN: | ||
415 | cache_add_dev(sys_dev); | 416 | cache_add_dev(sys_dev); |
416 | break; | 417 | break; |
417 | case CPU_DEAD: | 418 | case CPU_DEAD: |
419 | case CPU_DEAD_FROZEN: | ||
418 | cache_remove_dev(sys_dev); | 420 | cache_remove_dev(sys_dev); |
419 | break; | 421 | break; |
420 | } | 422 | } |
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index cae39d9dfe48..68991c2d4a1b 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c | |||
@@ -342,10 +342,12 @@ static int __cpuinit sysfs_cpu_notify(struct notifier_block *self, | |||
342 | 342 | ||
343 | switch (action) { | 343 | switch (action) { |
344 | case CPU_ONLINE: | 344 | case CPU_ONLINE: |
345 | case CPU_ONLINE_FROZEN: | ||
345 | register_cpu_online(cpu); | 346 | register_cpu_online(cpu); |
346 | break; | 347 | break; |
347 | #ifdef CONFIG_HOTPLUG_CPU | 348 | #ifdef CONFIG_HOTPLUG_CPU |
348 | case CPU_DEAD: | 349 | case CPU_DEAD: |
350 | case CPU_DEAD_FROZEN: | ||
349 | unregister_cpu_online(cpu); | 351 | unregister_cpu_online(cpu); |
350 | break; | 352 | break; |
351 | #endif | 353 | #endif |
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index b3a592b25ab3..de45aa82d97b 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c | |||
@@ -252,12 +252,15 @@ static int __cpuinit cpu_numa_callback(struct notifier_block *nfb, | |||
252 | 252 | ||
253 | switch (action) { | 253 | switch (action) { |
254 | case CPU_UP_PREPARE: | 254 | case CPU_UP_PREPARE: |
255 | case CPU_UP_PREPARE_FROZEN: | ||
255 | numa_setup_cpu(lcpu); | 256 | numa_setup_cpu(lcpu); |
256 | ret = NOTIFY_OK; | 257 | ret = NOTIFY_OK; |
257 | break; | 258 | break; |
258 | #ifdef CONFIG_HOTPLUG_CPU | 259 | #ifdef CONFIG_HOTPLUG_CPU |
259 | case CPU_DEAD: | 260 | case CPU_DEAD: |
261 | case CPU_DEAD_FROZEN: | ||
260 | case CPU_UP_CANCELED: | 262 | case CPU_UP_CANCELED: |
263 | case CPU_UP_CANCELED_FROZEN: | ||
261 | unmap_cpu_from_node(lcpu); | 264 | unmap_cpu_from_node(lcpu); |
262 | break; | 265 | break; |
263 | ret = NOTIFY_OK; | 266 | ret = NOTIFY_OK; |
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index ee89b33145d5..81a2b92ab0c2 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c | |||
@@ -567,9 +567,11 @@ appldata_cpu_notify(struct notifier_block *self, | |||
567 | { | 567 | { |
568 | switch (action) { | 568 | switch (action) { |
569 | case CPU_ONLINE: | 569 | case CPU_ONLINE: |
570 | case CPU_ONLINE_FROZEN: | ||
570 | appldata_online_cpu((long) hcpu); | 571 | appldata_online_cpu((long) hcpu); |
571 | break; | 572 | break; |
572 | case CPU_DEAD: | 573 | case CPU_DEAD: |
574 | case CPU_DEAD_FROZEN: | ||
573 | appldata_offline_cpu((long) hcpu); | 575 | appldata_offline_cpu((long) hcpu); |
574 | break; | 576 | break; |
575 | default: | 577 | default: |
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index b7977027a28f..09f028a3266b 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -789,10 +789,12 @@ static int __cpuinit smp_cpu_notify(struct notifier_block *self, | |||
789 | 789 | ||
790 | switch (action) { | 790 | switch (action) { |
791 | case CPU_ONLINE: | 791 | case CPU_ONLINE: |
792 | case CPU_ONLINE_FROZEN: | ||
792 | if (sysdev_create_file(s, &attr_capability)) | 793 | if (sysdev_create_file(s, &attr_capability)) |
793 | return NOTIFY_BAD; | 794 | return NOTIFY_BAD; |
794 | break; | 795 | break; |
795 | case CPU_DEAD: | 796 | case CPU_DEAD: |
797 | case CPU_DEAD_FROZEN: | ||
796 | sysdev_remove_file(s, &attr_capability); | 798 | sysdev_remove_file(s, &attr_capability); |
797 | break; | 799 | break; |
798 | } | 800 | } |
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c index 442169640e45..a14375dd5425 100644 --- a/arch/x86_64/kernel/mce.c +++ b/arch/x86_64/kernel/mce.c | |||
@@ -720,9 +720,11 @@ mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | |||
720 | 720 | ||
721 | switch (action) { | 721 | switch (action) { |
722 | case CPU_ONLINE: | 722 | case CPU_ONLINE: |
723 | case CPU_ONLINE_FROZEN: | ||
723 | mce_create_device(cpu); | 724 | mce_create_device(cpu); |
724 | break; | 725 | break; |
725 | case CPU_DEAD: | 726 | case CPU_DEAD: |
727 | case CPU_DEAD_FROZEN: | ||
726 | mce_remove_device(cpu); | 728 | mce_remove_device(cpu); |
727 | break; | 729 | break; |
728 | } | 730 | } |
diff --git a/arch/x86_64/kernel/mce_amd.c b/arch/x86_64/kernel/mce_amd.c index d0bd5d66e103..03356e64f9c8 100644 --- a/arch/x86_64/kernel/mce_amd.c +++ b/arch/x86_64/kernel/mce_amd.c | |||
@@ -654,9 +654,11 @@ static int threshold_cpu_callback(struct notifier_block *nfb, | |||
654 | 654 | ||
655 | switch (action) { | 655 | switch (action) { |
656 | case CPU_ONLINE: | 656 | case CPU_ONLINE: |
657 | case CPU_ONLINE_FROZEN: | ||
657 | threshold_create_device(cpu); | 658 | threshold_create_device(cpu); |
658 | break; | 659 | break; |
659 | case CPU_DEAD: | 660 | case CPU_DEAD: |
661 | case CPU_DEAD_FROZEN: | ||
660 | threshold_remove_device(cpu); | 662 | threshold_remove_device(cpu); |
661 | break; | 663 | break; |
662 | default: | 664 | default: |
diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c index dc32cef96195..51d4c6fa88c8 100644 --- a/arch/x86_64/kernel/vsyscall.c +++ b/arch/x86_64/kernel/vsyscall.c | |||
@@ -327,7 +327,7 @@ static int __cpuinit | |||
327 | cpu_vsyscall_notifier(struct notifier_block *n, unsigned long action, void *arg) | 327 | cpu_vsyscall_notifier(struct notifier_block *n, unsigned long action, void *arg) |
328 | { | 328 | { |
329 | long cpu = (long)arg; | 329 | long cpu = (long)arg; |
330 | if (action == CPU_ONLINE) | 330 | if (action == CPU_ONLINE || action == CPU_ONLINE_FROZEN) |
331 | smp_call_function_single(cpu, cpu_vsyscall_init, NULL, 0, 1); | 331 | smp_call_function_single(cpu, cpu_vsyscall_init, NULL, 0, 1); |
332 | return NOTIFY_DONE; | 332 | return NOTIFY_DONE; |
333 | } | 333 | } |
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index df506571ed60..cd54672da99f 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c | |||
@@ -3507,7 +3507,7 @@ static int blk_cpu_notify(struct notifier_block *self, unsigned long action, | |||
3507 | * If a CPU goes away, splice its entries to the current CPU | 3507 | * If a CPU goes away, splice its entries to the current CPU |
3508 | * and trigger a run of the softirq | 3508 | * and trigger a run of the softirq |
3509 | */ | 3509 | */ |
3510 | if (action == CPU_DEAD) { | 3510 | if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) { |
3511 | int cpu = (unsigned long) hcpu; | 3511 | int cpu = (unsigned long) hcpu; |
3512 | 3512 | ||
3513 | local_irq_disable(); | 3513 | local_irq_disable(); |
diff --git a/drivers/base/topology.c b/drivers/base/topology.c index 067a9e8bc377..8d8cdfec6529 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c | |||
@@ -126,10 +126,13 @@ static int __cpuinit topology_cpu_callback(struct notifier_block *nfb, | |||
126 | 126 | ||
127 | switch (action) { | 127 | switch (action) { |
128 | case CPU_UP_PREPARE: | 128 | case CPU_UP_PREPARE: |
129 | case CPU_UP_PREPARE_FROZEN: | ||
129 | rc = topology_add_dev(cpu); | 130 | rc = topology_add_dev(cpu); |
130 | break; | 131 | break; |
131 | case CPU_UP_CANCELED: | 132 | case CPU_UP_CANCELED: |
133 | case CPU_UP_CANCELED_FROZEN: | ||
132 | case CPU_DEAD: | 134 | case CPU_DEAD: |
135 | case CPU_DEAD_FROZEN: | ||
133 | topology_remove_dev(cpu); | 136 | topology_remove_dev(cpu); |
134 | break; | 137 | break; |
135 | } | 138 | } |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 893dbaf386fb..eb37fba9b7ef 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -1685,9 +1685,11 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb, | |||
1685 | if (sys_dev) { | 1685 | if (sys_dev) { |
1686 | switch (action) { | 1686 | switch (action) { |
1687 | case CPU_ONLINE: | 1687 | case CPU_ONLINE: |
1688 | case CPU_ONLINE_FROZEN: | ||
1688 | cpufreq_add_dev(sys_dev); | 1689 | cpufreq_add_dev(sys_dev); |
1689 | break; | 1690 | break; |
1690 | case CPU_DOWN_PREPARE: | 1691 | case CPU_DOWN_PREPARE: |
1692 | case CPU_DOWN_PREPARE_FROZEN: | ||
1691 | if (unlikely(lock_policy_rwsem_write(cpu))) | 1693 | if (unlikely(lock_policy_rwsem_write(cpu))) |
1692 | BUG(); | 1694 | BUG(); |
1693 | 1695 | ||
@@ -1699,6 +1701,7 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb, | |||
1699 | __cpufreq_remove_dev(sys_dev); | 1701 | __cpufreq_remove_dev(sys_dev); |
1700 | break; | 1702 | break; |
1701 | case CPU_DOWN_FAILED: | 1703 | case CPU_DOWN_FAILED: |
1704 | case CPU_DOWN_FAILED_FROZEN: | ||
1702 | cpufreq_add_dev(sys_dev); | 1705 | cpufreq_add_dev(sys_dev); |
1703 | break; | 1706 | break; |
1704 | } | 1707 | } |
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index d1c7cac9316c..d2f0cbd8b8f3 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c | |||
@@ -313,9 +313,11 @@ static int cpufreq_stat_cpu_callback(struct notifier_block *nfb, | |||
313 | 313 | ||
314 | switch (action) { | 314 | switch (action) { |
315 | case CPU_ONLINE: | 315 | case CPU_ONLINE: |
316 | case CPU_ONLINE_FROZEN: | ||
316 | cpufreq_update_policy(cpu); | 317 | cpufreq_update_policy(cpu); |
317 | break; | 318 | break; |
318 | case CPU_DEAD: | 319 | case CPU_DEAD: |
320 | case CPU_DEAD_FROZEN: | ||
319 | cpufreq_stats_free_table(cpu); | 321 | cpufreq_stats_free_table(cpu); |
320 | break; | 322 | break; |
321 | } | 323 | } |
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 03b1f650d1c4..75e3911810a3 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
@@ -309,9 +309,11 @@ static int coretemp_cpu_callback(struct notifier_block *nfb, | |||
309 | 309 | ||
310 | switch (action) { | 310 | switch (action) { |
311 | case CPU_ONLINE: | 311 | case CPU_ONLINE: |
312 | case CPU_ONLINE_FROZEN: | ||
312 | coretemp_device_add(cpu); | 313 | coretemp_device_add(cpu); |
313 | break; | 314 | break; |
314 | case CPU_DEAD: | 315 | case CPU_DEAD: |
316 | case CPU_DEAD_FROZEN: | ||
315 | coretemp_device_remove(cpu); | 317 | coretemp_device_remove(cpu); |
316 | break; | 318 | break; |
317 | } | 319 | } |
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c index f284be1c9166..82dda2faf4d0 100644 --- a/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/drivers/infiniband/hw/ehca/ehca_irq.c | |||
@@ -745,6 +745,7 @@ static int comp_pool_callback(struct notifier_block *nfb, | |||
745 | 745 | ||
746 | switch (action) { | 746 | switch (action) { |
747 | case CPU_UP_PREPARE: | 747 | case CPU_UP_PREPARE: |
748 | case CPU_UP_PREPARE_FROZEN: | ||
748 | ehca_gen_dbg("CPU: %x (CPU_PREPARE)", cpu); | 749 | ehca_gen_dbg("CPU: %x (CPU_PREPARE)", cpu); |
749 | if(!create_comp_task(pool, cpu)) { | 750 | if(!create_comp_task(pool, cpu)) { |
750 | ehca_gen_err("Can't create comp_task for cpu: %x", cpu); | 751 | ehca_gen_err("Can't create comp_task for cpu: %x", cpu); |
@@ -752,24 +753,29 @@ static int comp_pool_callback(struct notifier_block *nfb, | |||
752 | } | 753 | } |
753 | break; | 754 | break; |
754 | case CPU_UP_CANCELED: | 755 | case CPU_UP_CANCELED: |
756 | case CPU_UP_CANCELED_FROZEN: | ||
755 | ehca_gen_dbg("CPU: %x (CPU_CANCELED)", cpu); | 757 | ehca_gen_dbg("CPU: %x (CPU_CANCELED)", cpu); |
756 | cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu); | 758 | cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu); |
757 | kthread_bind(cct->task, any_online_cpu(cpu_online_map)); | 759 | kthread_bind(cct->task, any_online_cpu(cpu_online_map)); |
758 | destroy_comp_task(pool, cpu); | 760 | destroy_comp_task(pool, cpu); |
759 | break; | 761 | break; |
760 | case CPU_ONLINE: | 762 | case CPU_ONLINE: |
763 | case CPU_ONLINE_FROZEN: | ||
761 | ehca_gen_dbg("CPU: %x (CPU_ONLINE)", cpu); | 764 | ehca_gen_dbg("CPU: %x (CPU_ONLINE)", cpu); |
762 | cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu); | 765 | cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu); |
763 | kthread_bind(cct->task, cpu); | 766 | kthread_bind(cct->task, cpu); |
764 | wake_up_process(cct->task); | 767 | wake_up_process(cct->task); |
765 | break; | 768 | break; |
766 | case CPU_DOWN_PREPARE: | 769 | case CPU_DOWN_PREPARE: |
770 | case CPU_DOWN_PREPARE_FROZEN: | ||
767 | ehca_gen_dbg("CPU: %x (CPU_DOWN_PREPARE)", cpu); | 771 | ehca_gen_dbg("CPU: %x (CPU_DOWN_PREPARE)", cpu); |
768 | break; | 772 | break; |
769 | case CPU_DOWN_FAILED: | 773 | case CPU_DOWN_FAILED: |
774 | case CPU_DOWN_FAILED_FROZEN: | ||
770 | ehca_gen_dbg("CPU: %x (CPU_DOWN_FAILED)", cpu); | 775 | ehca_gen_dbg("CPU: %x (CPU_DOWN_FAILED)", cpu); |
771 | break; | 776 | break; |
772 | case CPU_DEAD: | 777 | case CPU_DEAD: |
778 | case CPU_DEAD_FROZEN: | ||
773 | ehca_gen_dbg("CPU: %x (CPU_DEAD)", cpu); | 779 | ehca_gen_dbg("CPU: %x (CPU_DEAD)", cpu); |
774 | destroy_comp_task(pool, cpu); | 780 | destroy_comp_task(pool, cpu); |
775 | take_over_work(pool, cpu); | 781 | take_over_work(pool, cpu); |
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index c8b8cfa332bb..0d892600ff00 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c | |||
@@ -2889,7 +2889,9 @@ static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val, | |||
2889 | 2889 | ||
2890 | switch (val) { | 2890 | switch (val) { |
2891 | case CPU_DOWN_PREPARE: | 2891 | case CPU_DOWN_PREPARE: |
2892 | case CPU_DOWN_PREPARE_FROZEN: | ||
2892 | case CPU_UP_CANCELED: | 2893 | case CPU_UP_CANCELED: |
2894 | case CPU_UP_CANCELED_FROZEN: | ||
2893 | printk(KERN_INFO "kvm: disabling virtualization on CPU%d\n", | 2895 | printk(KERN_INFO "kvm: disabling virtualization on CPU%d\n", |
2894 | cpu); | 2896 | cpu); |
2895 | decache_vcpus_on_cpu(cpu); | 2897 | decache_vcpus_on_cpu(cpu); |
@@ -2897,6 +2899,7 @@ static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val, | |||
2897 | NULL, 0, 1); | 2899 | NULL, 0, 1); |
2898 | break; | 2900 | break; |
2899 | case CPU_ONLINE: | 2901 | case CPU_ONLINE: |
2902 | case CPU_ONLINE_FROZEN: | ||
2900 | printk(KERN_INFO "kvm: enabling virtualization on CPU%d\n", | 2903 | printk(KERN_INFO "kvm: enabling virtualization on CPU%d\n", |
2901 | cpu); | 2904 | cpu); |
2902 | smp_call_function_single(cpu, kvm_arch_ops->hardware_enable, | 2905 | smp_call_function_single(cpu, kvm_arch_ops->hardware_enable, |
diff --git a/fs/buffer.c b/fs/buffer.c index fc2d763a8d78..aecd057cd0e0 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -2946,7 +2946,7 @@ static void buffer_exit_cpu(int cpu) | |||
2946 | static int buffer_cpu_notify(struct notifier_block *self, | 2946 | static int buffer_cpu_notify(struct notifier_block *self, |
2947 | unsigned long action, void *hcpu) | 2947 | unsigned long action, void *hcpu) |
2948 | { | 2948 | { |
2949 | if (action == CPU_DEAD) | 2949 | if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) |
2950 | buffer_exit_cpu((unsigned long)hcpu); | 2950 | buffer_exit_cpu((unsigned long)hcpu); |
2951 | return NOTIFY_OK; | 2951 | return NOTIFY_OK; |
2952 | } | 2952 | } |
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index f5aa3ef855fb..a96bde6df96d 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -1734,11 +1734,13 @@ xfs_icsb_cpu_notify( | |||
1734 | per_cpu_ptr(mp->m_sb_cnts, (unsigned long)hcpu); | 1734 | per_cpu_ptr(mp->m_sb_cnts, (unsigned long)hcpu); |
1735 | switch (action) { | 1735 | switch (action) { |
1736 | case CPU_UP_PREPARE: | 1736 | case CPU_UP_PREPARE: |
1737 | case CPU_UP_PREPARE_FROZEN: | ||
1737 | /* Easy Case - initialize the area and locks, and | 1738 | /* Easy Case - initialize the area and locks, and |
1738 | * then rebalance when online does everything else for us. */ | 1739 | * then rebalance when online does everything else for us. */ |
1739 | memset(cntp, 0, sizeof(xfs_icsb_cnts_t)); | 1740 | memset(cntp, 0, sizeof(xfs_icsb_cnts_t)); |
1740 | break; | 1741 | break; |
1741 | case CPU_ONLINE: | 1742 | case CPU_ONLINE: |
1743 | case CPU_ONLINE_FROZEN: | ||
1742 | xfs_icsb_lock(mp); | 1744 | xfs_icsb_lock(mp); |
1743 | xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0, 0); | 1745 | xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0, 0); |
1744 | xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, 0, 0); | 1746 | xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, 0, 0); |
@@ -1746,6 +1748,7 @@ xfs_icsb_cpu_notify( | |||
1746 | xfs_icsb_unlock(mp); | 1748 | xfs_icsb_unlock(mp); |
1747 | break; | 1749 | break; |
1748 | case CPU_DEAD: | 1750 | case CPU_DEAD: |
1751 | case CPU_DEAD_FROZEN: | ||
1749 | /* Disable all the counters, then fold the dead cpu's | 1752 | /* Disable all the counters, then fold the dead cpu's |
1750 | * count into the total on the global superblock and | 1753 | * count into the total on the global superblock and |
1751 | * re-enable the counters. */ | 1754 | * re-enable the counters. */ |
diff --git a/include/linux/notifier.h b/include/linux/notifier.h index 1903e5490c04..9431101bf876 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h | |||
@@ -197,5 +197,17 @@ extern int __srcu_notifier_call_chain(struct srcu_notifier_head *nh, | |||
197 | #define CPU_LOCK_ACQUIRE 0x0008 /* Acquire all hotcpu locks */ | 197 | #define CPU_LOCK_ACQUIRE 0x0008 /* Acquire all hotcpu locks */ |
198 | #define CPU_LOCK_RELEASE 0x0009 /* Release all hotcpu locks */ | 198 | #define CPU_LOCK_RELEASE 0x0009 /* Release all hotcpu locks */ |
199 | 199 | ||
200 | /* Used for CPU hotplug events occuring while tasks are frozen due to a suspend | ||
201 | * operation in progress | ||
202 | */ | ||
203 | #define CPU_TASKS_FROZEN 0x0010 | ||
204 | |||
205 | #define CPU_ONLINE_FROZEN (CPU_ONLINE | CPU_TASKS_FROZEN) | ||
206 | #define CPU_UP_PREPARE_FROZEN (CPU_UP_PREPARE | CPU_TASKS_FROZEN) | ||
207 | #define CPU_UP_CANCELED_FROZEN (CPU_UP_CANCELED | CPU_TASKS_FROZEN) | ||
208 | #define CPU_DOWN_PREPARE_FROZEN (CPU_DOWN_PREPARE | CPU_TASKS_FROZEN) | ||
209 | #define CPU_DOWN_FAILED_FROZEN (CPU_DOWN_FAILED | CPU_TASKS_FROZEN) | ||
210 | #define CPU_DEAD_FROZEN (CPU_DEAD | CPU_TASKS_FROZEN) | ||
211 | |||
200 | #endif /* __KERNEL__ */ | 212 | #endif /* __KERNEL__ */ |
201 | #endif /* _LINUX_NOTIFIER_H */ | 213 | #endif /* _LINUX_NOTIFIER_H */ |
diff --git a/kernel/cpu.c b/kernel/cpu.c index 28cb6c71a47a..369d2892687d 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
@@ -120,12 +120,13 @@ static int take_cpu_down(void *unused) | |||
120 | } | 120 | } |
121 | 121 | ||
122 | /* Requires cpu_add_remove_lock to be held */ | 122 | /* Requires cpu_add_remove_lock to be held */ |
123 | static int _cpu_down(unsigned int cpu) | 123 | static int _cpu_down(unsigned int cpu, int tasks_frozen) |
124 | { | 124 | { |
125 | int err, nr_calls = 0; | 125 | int err, nr_calls = 0; |
126 | struct task_struct *p; | 126 | struct task_struct *p; |
127 | cpumask_t old_allowed, tmp; | 127 | cpumask_t old_allowed, tmp; |
128 | void *hcpu = (void *)(long)cpu; | 128 | void *hcpu = (void *)(long)cpu; |
129 | unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0; | ||
129 | 130 | ||
130 | if (num_online_cpus() == 1) | 131 | if (num_online_cpus() == 1) |
131 | return -EBUSY; | 132 | return -EBUSY; |
@@ -134,11 +135,11 @@ static int _cpu_down(unsigned int cpu) | |||
134 | return -EINVAL; | 135 | return -EINVAL; |
135 | 136 | ||
136 | raw_notifier_call_chain(&cpu_chain, CPU_LOCK_ACQUIRE, hcpu); | 137 | raw_notifier_call_chain(&cpu_chain, CPU_LOCK_ACQUIRE, hcpu); |
137 | err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE, | 138 | err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod, |
138 | hcpu, -1, &nr_calls); | 139 | hcpu, -1, &nr_calls); |
139 | if (err == NOTIFY_BAD) { | 140 | if (err == NOTIFY_BAD) { |
140 | __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED, hcpu, | 141 | __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod, |
141 | nr_calls, NULL); | 142 | hcpu, nr_calls, NULL); |
142 | printk("%s: attempt to take down CPU %u failed\n", | 143 | printk("%s: attempt to take down CPU %u failed\n", |
143 | __FUNCTION__, cpu); | 144 | __FUNCTION__, cpu); |
144 | err = -EINVAL; | 145 | err = -EINVAL; |
@@ -157,7 +158,7 @@ static int _cpu_down(unsigned int cpu) | |||
157 | 158 | ||
158 | if (IS_ERR(p) || cpu_online(cpu)) { | 159 | if (IS_ERR(p) || cpu_online(cpu)) { |
159 | /* CPU didn't die: tell everyone. Can't complain. */ | 160 | /* CPU didn't die: tell everyone. Can't complain. */ |
160 | if (raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED, | 161 | if (raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod, |
161 | hcpu) == NOTIFY_BAD) | 162 | hcpu) == NOTIFY_BAD) |
162 | BUG(); | 163 | BUG(); |
163 | 164 | ||
@@ -176,7 +177,8 @@ static int _cpu_down(unsigned int cpu) | |||
176 | __cpu_die(cpu); | 177 | __cpu_die(cpu); |
177 | 178 | ||
178 | /* CPU is completely dead: tell everyone. Too late to complain. */ | 179 | /* CPU is completely dead: tell everyone. Too late to complain. */ |
179 | if (raw_notifier_call_chain(&cpu_chain, CPU_DEAD, hcpu) == NOTIFY_BAD) | 180 | if (raw_notifier_call_chain(&cpu_chain, CPU_DEAD | mod, |
181 | hcpu) == NOTIFY_BAD) | ||
180 | BUG(); | 182 | BUG(); |
181 | 183 | ||
182 | check_for_tasks(cpu); | 184 | check_for_tasks(cpu); |
@@ -186,8 +188,7 @@ out_thread: | |||
186 | out_allowed: | 188 | out_allowed: |
187 | set_cpus_allowed(current, old_allowed); | 189 | set_cpus_allowed(current, old_allowed); |
188 | out_release: | 190 | out_release: |
189 | raw_notifier_call_chain(&cpu_chain, CPU_LOCK_RELEASE, | 191 | raw_notifier_call_chain(&cpu_chain, CPU_LOCK_RELEASE, hcpu); |
190 | (void *)(long)cpu); | ||
191 | return err; | 192 | return err; |
192 | } | 193 | } |
193 | 194 | ||
@@ -199,7 +200,7 @@ int cpu_down(unsigned int cpu) | |||
199 | if (cpu_hotplug_disabled) | 200 | if (cpu_hotplug_disabled) |
200 | err = -EBUSY; | 201 | err = -EBUSY; |
201 | else | 202 | else |
202 | err = _cpu_down(cpu); | 203 | err = _cpu_down(cpu, 0); |
203 | 204 | ||
204 | mutex_unlock(&cpu_add_remove_lock); | 205 | mutex_unlock(&cpu_add_remove_lock); |
205 | return err; | 206 | return err; |
@@ -207,16 +208,17 @@ int cpu_down(unsigned int cpu) | |||
207 | #endif /*CONFIG_HOTPLUG_CPU*/ | 208 | #endif /*CONFIG_HOTPLUG_CPU*/ |
208 | 209 | ||
209 | /* Requires cpu_add_remove_lock to be held */ | 210 | /* Requires cpu_add_remove_lock to be held */ |
210 | static int __cpuinit _cpu_up(unsigned int cpu) | 211 | static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen) |
211 | { | 212 | { |
212 | int ret, nr_calls = 0; | 213 | int ret, nr_calls = 0; |
213 | void *hcpu = (void *)(long)cpu; | 214 | void *hcpu = (void *)(long)cpu; |
215 | unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0; | ||
214 | 216 | ||
215 | if (cpu_online(cpu) || !cpu_present(cpu)) | 217 | if (cpu_online(cpu) || !cpu_present(cpu)) |
216 | return -EINVAL; | 218 | return -EINVAL; |
217 | 219 | ||
218 | raw_notifier_call_chain(&cpu_chain, CPU_LOCK_ACQUIRE, hcpu); | 220 | raw_notifier_call_chain(&cpu_chain, CPU_LOCK_ACQUIRE, hcpu); |
219 | ret = __raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu, | 221 | ret = __raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE | mod, hcpu, |
220 | -1, &nr_calls); | 222 | -1, &nr_calls); |
221 | if (ret == NOTIFY_BAD) { | 223 | if (ret == NOTIFY_BAD) { |
222 | printk("%s: attempt to bring up CPU %u failed\n", | 224 | printk("%s: attempt to bring up CPU %u failed\n", |
@@ -234,12 +236,12 @@ static int __cpuinit _cpu_up(unsigned int cpu) | |||
234 | BUG_ON(!cpu_online(cpu)); | 236 | BUG_ON(!cpu_online(cpu)); |
235 | 237 | ||
236 | /* Now call notifier in preparation. */ | 238 | /* Now call notifier in preparation. */ |
237 | raw_notifier_call_chain(&cpu_chain, CPU_ONLINE, hcpu); | 239 | raw_notifier_call_chain(&cpu_chain, CPU_ONLINE | mod, hcpu); |
238 | 240 | ||
239 | out_notify: | 241 | out_notify: |
240 | if (ret != 0) | 242 | if (ret != 0) |
241 | __raw_notifier_call_chain(&cpu_chain, | 243 | __raw_notifier_call_chain(&cpu_chain, |
242 | CPU_UP_CANCELED, hcpu, nr_calls, NULL); | 244 | CPU_UP_CANCELED | mod, hcpu, nr_calls, NULL); |
243 | raw_notifier_call_chain(&cpu_chain, CPU_LOCK_RELEASE, hcpu); | 245 | raw_notifier_call_chain(&cpu_chain, CPU_LOCK_RELEASE, hcpu); |
244 | 246 | ||
245 | return ret; | 247 | return ret; |
@@ -253,7 +255,7 @@ int __cpuinit cpu_up(unsigned int cpu) | |||
253 | if (cpu_hotplug_disabled) | 255 | if (cpu_hotplug_disabled) |
254 | err = -EBUSY; | 256 | err = -EBUSY; |
255 | else | 257 | else |
256 | err = _cpu_up(cpu); | 258 | err = _cpu_up(cpu, 0); |
257 | 259 | ||
258 | mutex_unlock(&cpu_add_remove_lock); | 260 | mutex_unlock(&cpu_add_remove_lock); |
259 | return err; | 261 | return err; |
@@ -283,7 +285,7 @@ int disable_nonboot_cpus(void) | |||
283 | for_each_online_cpu(cpu) { | 285 | for_each_online_cpu(cpu) { |
284 | if (cpu == first_cpu) | 286 | if (cpu == first_cpu) |
285 | continue; | 287 | continue; |
286 | error = _cpu_down(cpu); | 288 | error = _cpu_down(cpu, 1); |
287 | if (!error) { | 289 | if (!error) { |
288 | cpu_set(cpu, frozen_cpus); | 290 | cpu_set(cpu, frozen_cpus); |
289 | printk("CPU%d is down\n", cpu); | 291 | printk("CPU%d is down\n", cpu); |
@@ -318,7 +320,7 @@ void enable_nonboot_cpus(void) | |||
318 | suspend_cpu_hotplug = 1; | 320 | suspend_cpu_hotplug = 1; |
319 | printk("Enabling non-boot CPUs ...\n"); | 321 | printk("Enabling non-boot CPUs ...\n"); |
320 | for_each_cpu_mask(cpu, frozen_cpus) { | 322 | for_each_cpu_mask(cpu, frozen_cpus) { |
321 | error = _cpu_up(cpu); | 323 | error = _cpu_up(cpu, 1); |
322 | if (!error) { | 324 | if (!error) { |
323 | printk("CPU%d is up\n", cpu); | 325 | printk("CPU%d is up\n", cpu); |
324 | continue; | 326 | continue; |
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index c9f4f044a8a8..23c03f43e196 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -1411,11 +1411,13 @@ static int __cpuinit hrtimer_cpu_notify(struct notifier_block *self, | |||
1411 | switch (action) { | 1411 | switch (action) { |
1412 | 1412 | ||
1413 | case CPU_UP_PREPARE: | 1413 | case CPU_UP_PREPARE: |
1414 | case CPU_UP_PREPARE_FROZEN: | ||
1414 | init_hrtimers_cpu(cpu); | 1415 | init_hrtimers_cpu(cpu); |
1415 | break; | 1416 | break; |
1416 | 1417 | ||
1417 | #ifdef CONFIG_HOTPLUG_CPU | 1418 | #ifdef CONFIG_HOTPLUG_CPU |
1418 | case CPU_DEAD: | 1419 | case CPU_DEAD: |
1420 | case CPU_DEAD_FROZEN: | ||
1419 | clockevents_notify(CLOCK_EVT_NOTIFY_CPU_DEAD, &cpu); | 1421 | clockevents_notify(CLOCK_EVT_NOTIFY_CPU_DEAD, &cpu); |
1420 | migrate_hrtimers(cpu); | 1422 | migrate_hrtimers(cpu); |
1421 | break; | 1423 | break; |
diff --git a/kernel/profile.c b/kernel/profile.c index 9bfadb248dd8..cc91b9bf759d 100644 --- a/kernel/profile.c +++ b/kernel/profile.c | |||
@@ -340,6 +340,7 @@ static int __devinit profile_cpu_callback(struct notifier_block *info, | |||
340 | 340 | ||
341 | switch (action) { | 341 | switch (action) { |
342 | case CPU_UP_PREPARE: | 342 | case CPU_UP_PREPARE: |
343 | case CPU_UP_PREPARE_FROZEN: | ||
343 | node = cpu_to_node(cpu); | 344 | node = cpu_to_node(cpu); |
344 | per_cpu(cpu_profile_flip, cpu) = 0; | 345 | per_cpu(cpu_profile_flip, cpu) = 0; |
345 | if (!per_cpu(cpu_profile_hits, cpu)[1]) { | 346 | if (!per_cpu(cpu_profile_hits, cpu)[1]) { |
@@ -365,10 +366,13 @@ static int __devinit profile_cpu_callback(struct notifier_block *info, | |||
365 | __free_page(page); | 366 | __free_page(page); |
366 | return NOTIFY_BAD; | 367 | return NOTIFY_BAD; |
367 | case CPU_ONLINE: | 368 | case CPU_ONLINE: |
369 | case CPU_ONLINE_FROZEN: | ||
368 | cpu_set(cpu, prof_cpu_mask); | 370 | cpu_set(cpu, prof_cpu_mask); |
369 | break; | 371 | break; |
370 | case CPU_UP_CANCELED: | 372 | case CPU_UP_CANCELED: |
373 | case CPU_UP_CANCELED_FROZEN: | ||
371 | case CPU_DEAD: | 374 | case CPU_DEAD: |
375 | case CPU_DEAD_FROZEN: | ||
372 | cpu_clear(cpu, prof_cpu_mask); | 376 | cpu_clear(cpu, prof_cpu_mask); |
373 | if (per_cpu(cpu_profile_hits, cpu)[0]) { | 377 | if (per_cpu(cpu_profile_hits, cpu)[0]) { |
374 | page = virt_to_page(per_cpu(cpu_profile_hits, cpu)[0]); | 378 | page = virt_to_page(per_cpu(cpu_profile_hits, cpu)[0]); |
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index 3554b76da84c..2c2dd8410dc4 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c | |||
@@ -558,9 +558,11 @@ static int __cpuinit rcu_cpu_notify(struct notifier_block *self, | |||
558 | long cpu = (long)hcpu; | 558 | long cpu = (long)hcpu; |
559 | switch (action) { | 559 | switch (action) { |
560 | case CPU_UP_PREPARE: | 560 | case CPU_UP_PREPARE: |
561 | case CPU_UP_PREPARE_FROZEN: | ||
561 | rcu_online_cpu(cpu); | 562 | rcu_online_cpu(cpu); |
562 | break; | 563 | break; |
563 | case CPU_DEAD: | 564 | case CPU_DEAD: |
565 | case CPU_DEAD_FROZEN: | ||
564 | rcu_offline_cpu(cpu); | 566 | rcu_offline_cpu(cpu); |
565 | break; | 567 | break; |
566 | default: | 568 | default: |
diff --git a/kernel/relay.c b/kernel/relay.c index e804589c863c..61a504900eaa 100644 --- a/kernel/relay.c +++ b/kernel/relay.c | |||
@@ -484,6 +484,7 @@ static int __cpuinit relay_hotcpu_callback(struct notifier_block *nb, | |||
484 | 484 | ||
485 | switch(action) { | 485 | switch(action) { |
486 | case CPU_UP_PREPARE: | 486 | case CPU_UP_PREPARE: |
487 | case CPU_UP_PREPARE_FROZEN: | ||
487 | mutex_lock(&relay_channels_mutex); | 488 | mutex_lock(&relay_channels_mutex); |
488 | list_for_each_entry(chan, &relay_channels, list) { | 489 | list_for_each_entry(chan, &relay_channels, list) { |
489 | if (chan->buf[hotcpu]) | 490 | if (chan->buf[hotcpu]) |
@@ -500,6 +501,7 @@ static int __cpuinit relay_hotcpu_callback(struct notifier_block *nb, | |||
500 | mutex_unlock(&relay_channels_mutex); | 501 | mutex_unlock(&relay_channels_mutex); |
501 | break; | 502 | break; |
502 | case CPU_DEAD: | 503 | case CPU_DEAD: |
504 | case CPU_DEAD_FROZEN: | ||
503 | /* No need to flush the cpu : will be flushed upon | 505 | /* No need to flush the cpu : will be flushed upon |
504 | * final relay_flush() call. */ | 506 | * final relay_flush() call. */ |
505 | break; | 507 | break; |
diff --git a/kernel/sched.c b/kernel/sched.c index fe1a9c2b855a..799d23b4e35d 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -5394,6 +5394,7 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu) | |||
5394 | break; | 5394 | break; |
5395 | 5395 | ||
5396 | case CPU_UP_PREPARE: | 5396 | case CPU_UP_PREPARE: |
5397 | case CPU_UP_PREPARE_FROZEN: | ||
5397 | p = kthread_create(migration_thread, hcpu, "migration/%d",cpu); | 5398 | p = kthread_create(migration_thread, hcpu, "migration/%d",cpu); |
5398 | if (IS_ERR(p)) | 5399 | if (IS_ERR(p)) |
5399 | return NOTIFY_BAD; | 5400 | return NOTIFY_BAD; |
@@ -5407,12 +5408,14 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu) | |||
5407 | break; | 5408 | break; |
5408 | 5409 | ||
5409 | case CPU_ONLINE: | 5410 | case CPU_ONLINE: |
5411 | case CPU_ONLINE_FROZEN: | ||
5410 | /* Strictly unneccessary, as first user will wake it. */ | 5412 | /* Strictly unneccessary, as first user will wake it. */ |
5411 | wake_up_process(cpu_rq(cpu)->migration_thread); | 5413 | wake_up_process(cpu_rq(cpu)->migration_thread); |
5412 | break; | 5414 | break; |
5413 | 5415 | ||
5414 | #ifdef CONFIG_HOTPLUG_CPU | 5416 | #ifdef CONFIG_HOTPLUG_CPU |
5415 | case CPU_UP_CANCELED: | 5417 | case CPU_UP_CANCELED: |
5418 | case CPU_UP_CANCELED_FROZEN: | ||
5416 | if (!cpu_rq(cpu)->migration_thread) | 5419 | if (!cpu_rq(cpu)->migration_thread) |
5417 | break; | 5420 | break; |
5418 | /* Unbind it from offline cpu so it can run. Fall thru. */ | 5421 | /* Unbind it from offline cpu so it can run. Fall thru. */ |
@@ -5423,6 +5426,7 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu) | |||
5423 | break; | 5426 | break; |
5424 | 5427 | ||
5425 | case CPU_DEAD: | 5428 | case CPU_DEAD: |
5429 | case CPU_DEAD_FROZEN: | ||
5426 | migrate_live_tasks(cpu); | 5430 | migrate_live_tasks(cpu); |
5427 | rq = cpu_rq(cpu); | 5431 | rq = cpu_rq(cpu); |
5428 | kthread_stop(rq->migration_thread); | 5432 | kthread_stop(rq->migration_thread); |
@@ -6912,14 +6916,20 @@ static int update_sched_domains(struct notifier_block *nfb, | |||
6912 | { | 6916 | { |
6913 | switch (action) { | 6917 | switch (action) { |
6914 | case CPU_UP_PREPARE: | 6918 | case CPU_UP_PREPARE: |
6919 | case CPU_UP_PREPARE_FROZEN: | ||
6915 | case CPU_DOWN_PREPARE: | 6920 | case CPU_DOWN_PREPARE: |
6921 | case CPU_DOWN_PREPARE_FROZEN: | ||
6916 | detach_destroy_domains(&cpu_online_map); | 6922 | detach_destroy_domains(&cpu_online_map); |
6917 | return NOTIFY_OK; | 6923 | return NOTIFY_OK; |
6918 | 6924 | ||
6919 | case CPU_UP_CANCELED: | 6925 | case CPU_UP_CANCELED: |
6926 | case CPU_UP_CANCELED_FROZEN: | ||
6920 | case CPU_DOWN_FAILED: | 6927 | case CPU_DOWN_FAILED: |
6928 | case CPU_DOWN_FAILED_FROZEN: | ||
6921 | case CPU_ONLINE: | 6929 | case CPU_ONLINE: |
6930 | case CPU_ONLINE_FROZEN: | ||
6922 | case CPU_DEAD: | 6931 | case CPU_DEAD: |
6932 | case CPU_DEAD_FROZEN: | ||
6923 | /* | 6933 | /* |
6924 | * Fall through and re-initialise the domains. | 6934 | * Fall through and re-initialise the domains. |
6925 | */ | 6935 | */ |
diff --git a/kernel/softirq.c b/kernel/softirq.c index 8b75008e2bd8..0b9886a00e74 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c | |||
@@ -593,6 +593,7 @@ static int __cpuinit cpu_callback(struct notifier_block *nfb, | |||
593 | 593 | ||
594 | switch (action) { | 594 | switch (action) { |
595 | case CPU_UP_PREPARE: | 595 | case CPU_UP_PREPARE: |
596 | case CPU_UP_PREPARE_FROZEN: | ||
596 | p = kthread_create(ksoftirqd, hcpu, "ksoftirqd/%d", hotcpu); | 597 | p = kthread_create(ksoftirqd, hcpu, "ksoftirqd/%d", hotcpu); |
597 | if (IS_ERR(p)) { | 598 | if (IS_ERR(p)) { |
598 | printk("ksoftirqd for %i failed\n", hotcpu); | 599 | printk("ksoftirqd for %i failed\n", hotcpu); |
@@ -602,16 +603,19 @@ static int __cpuinit cpu_callback(struct notifier_block *nfb, | |||
602 | per_cpu(ksoftirqd, hotcpu) = p; | 603 | per_cpu(ksoftirqd, hotcpu) = p; |
603 | break; | 604 | break; |
604 | case CPU_ONLINE: | 605 | case CPU_ONLINE: |
606 | case CPU_ONLINE_FROZEN: | ||
605 | wake_up_process(per_cpu(ksoftirqd, hotcpu)); | 607 | wake_up_process(per_cpu(ksoftirqd, hotcpu)); |
606 | break; | 608 | break; |
607 | #ifdef CONFIG_HOTPLUG_CPU | 609 | #ifdef CONFIG_HOTPLUG_CPU |
608 | case CPU_UP_CANCELED: | 610 | case CPU_UP_CANCELED: |
611 | case CPU_UP_CANCELED_FROZEN: | ||
609 | if (!per_cpu(ksoftirqd, hotcpu)) | 612 | if (!per_cpu(ksoftirqd, hotcpu)) |
610 | break; | 613 | break; |
611 | /* Unbind so it can run. Fall thru. */ | 614 | /* Unbind so it can run. Fall thru. */ |
612 | kthread_bind(per_cpu(ksoftirqd, hotcpu), | 615 | kthread_bind(per_cpu(ksoftirqd, hotcpu), |
613 | any_online_cpu(cpu_online_map)); | 616 | any_online_cpu(cpu_online_map)); |
614 | case CPU_DEAD: | 617 | case CPU_DEAD: |
618 | case CPU_DEAD_FROZEN: | ||
615 | p = per_cpu(ksoftirqd, hotcpu); | 619 | p = per_cpu(ksoftirqd, hotcpu); |
616 | per_cpu(ksoftirqd, hotcpu) = NULL; | 620 | per_cpu(ksoftirqd, hotcpu) = NULL; |
617 | kthread_stop(p); | 621 | kthread_stop(p); |
diff --git a/kernel/softlockup.c b/kernel/softlockup.c index 8fa7040247ad..0131e296ffb4 100644 --- a/kernel/softlockup.c +++ b/kernel/softlockup.c | |||
@@ -146,6 +146,7 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | |||
146 | 146 | ||
147 | switch (action) { | 147 | switch (action) { |
148 | case CPU_UP_PREPARE: | 148 | case CPU_UP_PREPARE: |
149 | case CPU_UP_PREPARE_FROZEN: | ||
149 | BUG_ON(per_cpu(watchdog_task, hotcpu)); | 150 | BUG_ON(per_cpu(watchdog_task, hotcpu)); |
150 | p = kthread_create(watchdog, hcpu, "watchdog/%d", hotcpu); | 151 | p = kthread_create(watchdog, hcpu, "watchdog/%d", hotcpu); |
151 | if (IS_ERR(p)) { | 152 | if (IS_ERR(p)) { |
@@ -157,16 +158,19 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | |||
157 | kthread_bind(p, hotcpu); | 158 | kthread_bind(p, hotcpu); |
158 | break; | 159 | break; |
159 | case CPU_ONLINE: | 160 | case CPU_ONLINE: |
161 | case CPU_ONLINE_FROZEN: | ||
160 | wake_up_process(per_cpu(watchdog_task, hotcpu)); | 162 | wake_up_process(per_cpu(watchdog_task, hotcpu)); |
161 | break; | 163 | break; |
162 | #ifdef CONFIG_HOTPLUG_CPU | 164 | #ifdef CONFIG_HOTPLUG_CPU |
163 | case CPU_UP_CANCELED: | 165 | case CPU_UP_CANCELED: |
166 | case CPU_UP_CANCELED_FROZEN: | ||
164 | if (!per_cpu(watchdog_task, hotcpu)) | 167 | if (!per_cpu(watchdog_task, hotcpu)) |
165 | break; | 168 | break; |
166 | /* Unbind so it can run. Fall thru. */ | 169 | /* Unbind so it can run. Fall thru. */ |
167 | kthread_bind(per_cpu(watchdog_task, hotcpu), | 170 | kthread_bind(per_cpu(watchdog_task, hotcpu), |
168 | any_online_cpu(cpu_online_map)); | 171 | any_online_cpu(cpu_online_map)); |
169 | case CPU_DEAD: | 172 | case CPU_DEAD: |
173 | case CPU_DEAD_FROZEN: | ||
170 | p = per_cpu(watchdog_task, hotcpu); | 174 | p = per_cpu(watchdog_task, hotcpu); |
171 | per_cpu(watchdog_task, hotcpu) = NULL; | 175 | per_cpu(watchdog_task, hotcpu) = NULL; |
172 | kthread_stop(p); | 176 | kthread_stop(p); |
diff --git a/kernel/timer.c b/kernel/timer.c index 58f6dd07c80b..de85f8491c1d 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -1293,11 +1293,13 @@ static int __cpuinit timer_cpu_notify(struct notifier_block *self, | |||
1293 | long cpu = (long)hcpu; | 1293 | long cpu = (long)hcpu; |
1294 | switch(action) { | 1294 | switch(action) { |
1295 | case CPU_UP_PREPARE: | 1295 | case CPU_UP_PREPARE: |
1296 | case CPU_UP_PREPARE_FROZEN: | ||
1296 | if (init_timers_cpu(cpu) < 0) | 1297 | if (init_timers_cpu(cpu) < 0) |
1297 | return NOTIFY_BAD; | 1298 | return NOTIFY_BAD; |
1298 | break; | 1299 | break; |
1299 | #ifdef CONFIG_HOTPLUG_CPU | 1300 | #ifdef CONFIG_HOTPLUG_CPU |
1300 | case CPU_DEAD: | 1301 | case CPU_DEAD: |
1302 | case CPU_DEAD_FROZEN: | ||
1301 | migrate_timers(cpu); | 1303 | migrate_timers(cpu); |
1302 | break; | 1304 | break; |
1303 | #endif | 1305 | #endif |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index b976ed87dd37..fb56fedd5c02 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -799,6 +799,8 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb, | |||
799 | struct cpu_workqueue_struct *cwq; | 799 | struct cpu_workqueue_struct *cwq; |
800 | struct workqueue_struct *wq; | 800 | struct workqueue_struct *wq; |
801 | 801 | ||
802 | action &= ~CPU_TASKS_FROZEN; | ||
803 | |||
802 | switch (action) { | 804 | switch (action) { |
803 | case CPU_LOCK_ACQUIRE: | 805 | case CPU_LOCK_ACQUIRE: |
804 | mutex_lock(&workqueue_mutex); | 806 | mutex_lock(&workqueue_mutex); |
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index d69ddbe43865..402eb4eb6b23 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c | |||
@@ -1004,7 +1004,7 @@ static int radix_tree_callback(struct notifier_block *nfb, | |||
1004 | struct radix_tree_preload *rtp; | 1004 | struct radix_tree_preload *rtp; |
1005 | 1005 | ||
1006 | /* Free per-cpu pool of perloaded nodes */ | 1006 | /* Free per-cpu pool of perloaded nodes */ |
1007 | if (action == CPU_DEAD) { | 1007 | if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) { |
1008 | rtp = &per_cpu(radix_tree_preloads, cpu); | 1008 | rtp = &per_cpu(radix_tree_preloads, cpu); |
1009 | while (rtp->nr) { | 1009 | while (rtp->nr) { |
1010 | kmem_cache_free(radix_tree_node_cachep, | 1010 | kmem_cache_free(radix_tree_node_cachep, |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 6fd0b7455b0b..d53cbf8acb8e 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -2148,11 +2148,14 @@ static int __cpuinit pageset_cpuup_callback(struct notifier_block *nfb, | |||
2148 | 2148 | ||
2149 | switch (action) { | 2149 | switch (action) { |
2150 | case CPU_UP_PREPARE: | 2150 | case CPU_UP_PREPARE: |
2151 | case CPU_UP_PREPARE_FROZEN: | ||
2151 | if (process_zones(cpu)) | 2152 | if (process_zones(cpu)) |
2152 | ret = NOTIFY_BAD; | 2153 | ret = NOTIFY_BAD; |
2153 | break; | 2154 | break; |
2154 | case CPU_UP_CANCELED: | 2155 | case CPU_UP_CANCELED: |
2156 | case CPU_UP_CANCELED_FROZEN: | ||
2155 | case CPU_DEAD: | 2157 | case CPU_DEAD: |
2158 | case CPU_DEAD_FROZEN: | ||
2156 | free_zone_pagesets(cpu); | 2159 | free_zone_pagesets(cpu); |
2157 | break; | 2160 | break; |
2158 | default: | 2161 | default: |
@@ -3012,7 +3015,7 @@ static int page_alloc_cpu_notify(struct notifier_block *self, | |||
3012 | { | 3015 | { |
3013 | int cpu = (unsigned long)hcpu; | 3016 | int cpu = (unsigned long)hcpu; |
3014 | 3017 | ||
3015 | if (action == CPU_DEAD) { | 3018 | if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) { |
3016 | local_irq_disable(); | 3019 | local_irq_disable(); |
3017 | __drain_pages(cpu); | 3020 | __drain_pages(cpu); |
3018 | vm_events_fold_cpu(cpu); | 3021 | vm_events_fold_cpu(cpu); |
@@ -1190,6 +1190,7 @@ static int __cpuinit cpuup_callback(struct notifier_block *nfb, | |||
1190 | mutex_lock(&cache_chain_mutex); | 1190 | mutex_lock(&cache_chain_mutex); |
1191 | break; | 1191 | break; |
1192 | case CPU_UP_PREPARE: | 1192 | case CPU_UP_PREPARE: |
1193 | case CPU_UP_PREPARE_FROZEN: | ||
1193 | /* | 1194 | /* |
1194 | * We need to do this right in the beginning since | 1195 | * We need to do this right in the beginning since |
1195 | * alloc_arraycache's are going to use this list. | 1196 | * alloc_arraycache's are going to use this list. |
@@ -1276,10 +1277,12 @@ static int __cpuinit cpuup_callback(struct notifier_block *nfb, | |||
1276 | } | 1277 | } |
1277 | break; | 1278 | break; |
1278 | case CPU_ONLINE: | 1279 | case CPU_ONLINE: |
1280 | case CPU_ONLINE_FROZEN: | ||
1279 | start_cpu_timer(cpu); | 1281 | start_cpu_timer(cpu); |
1280 | break; | 1282 | break; |
1281 | #ifdef CONFIG_HOTPLUG_CPU | 1283 | #ifdef CONFIG_HOTPLUG_CPU |
1282 | case CPU_DOWN_PREPARE: | 1284 | case CPU_DOWN_PREPARE: |
1285 | case CPU_DOWN_PREPARE_FROZEN: | ||
1283 | /* | 1286 | /* |
1284 | * Shutdown cache reaper. Note that the cache_chain_mutex is | 1287 | * Shutdown cache reaper. Note that the cache_chain_mutex is |
1285 | * held so that if cache_reap() is invoked it cannot do | 1288 | * held so that if cache_reap() is invoked it cannot do |
@@ -1291,9 +1294,11 @@ static int __cpuinit cpuup_callback(struct notifier_block *nfb, | |||
1291 | per_cpu(reap_work, cpu).work.func = NULL; | 1294 | per_cpu(reap_work, cpu).work.func = NULL; |
1292 | break; | 1295 | break; |
1293 | case CPU_DOWN_FAILED: | 1296 | case CPU_DOWN_FAILED: |
1297 | case CPU_DOWN_FAILED_FROZEN: | ||
1294 | start_cpu_timer(cpu); | 1298 | start_cpu_timer(cpu); |
1295 | break; | 1299 | break; |
1296 | case CPU_DEAD: | 1300 | case CPU_DEAD: |
1301 | case CPU_DEAD_FROZEN: | ||
1297 | /* | 1302 | /* |
1298 | * Even if all the cpus of a node are down, we don't free the | 1303 | * Even if all the cpus of a node are down, we don't free the |
1299 | * kmem_list3 of any cache. This to avoid a race between | 1304 | * kmem_list3 of any cache. This to avoid a race between |
@@ -1305,6 +1310,7 @@ static int __cpuinit cpuup_callback(struct notifier_block *nfb, | |||
1305 | /* fall thru */ | 1310 | /* fall thru */ |
1306 | #endif | 1311 | #endif |
1307 | case CPU_UP_CANCELED: | 1312 | case CPU_UP_CANCELED: |
1313 | case CPU_UP_CANCELED_FROZEN: | ||
1308 | list_for_each_entry(cachep, &cache_chain, next) { | 1314 | list_for_each_entry(cachep, &cache_chain, next) { |
1309 | struct array_cache *nc; | 1315 | struct array_cache *nc; |
1310 | struct array_cache *shared; | 1316 | struct array_cache *shared; |
@@ -2514,7 +2514,9 @@ static int __cpuinit slab_cpuup_callback(struct notifier_block *nfb, | |||
2514 | 2514 | ||
2515 | switch (action) { | 2515 | switch (action) { |
2516 | case CPU_UP_CANCELED: | 2516 | case CPU_UP_CANCELED: |
2517 | case CPU_UP_CANCELED_FROZEN: | ||
2517 | case CPU_DEAD: | 2518 | case CPU_DEAD: |
2519 | case CPU_DEAD_FROZEN: | ||
2518 | for_all_slabs(__flush_cpu_slab, cpu); | 2520 | for_all_slabs(__flush_cpu_slab, cpu); |
2519 | break; | 2521 | break; |
2520 | default: | 2522 | default: |
@@ -488,7 +488,7 @@ static int cpu_swap_callback(struct notifier_block *nfb, | |||
488 | long *committed; | 488 | long *committed; |
489 | 489 | ||
490 | committed = &per_cpu(committed_space, (long)hcpu); | 490 | committed = &per_cpu(committed_space, (long)hcpu); |
491 | if (action == CPU_DEAD) { | 491 | if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) { |
492 | atomic_add(*committed, &vm_committed_space); | 492 | atomic_add(*committed, &vm_committed_space); |
493 | *committed = 0; | 493 | *committed = 0; |
494 | __lru_add_drain((long)hcpu); | 494 | __lru_add_drain((long)hcpu); |
diff --git a/mm/vmscan.c b/mm/vmscan.c index 1c8e75a1cfcd..1be5a6376ef0 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -1528,7 +1528,7 @@ static int __devinit cpu_callback(struct notifier_block *nfb, | |||
1528 | pg_data_t *pgdat; | 1528 | pg_data_t *pgdat; |
1529 | cpumask_t mask; | 1529 | cpumask_t mask; |
1530 | 1530 | ||
1531 | if (action == CPU_ONLINE) { | 1531 | if (action == CPU_ONLINE || action == CPU_ONLINE_FROZEN) { |
1532 | for_each_online_pgdat(pgdat) { | 1532 | for_each_online_pgdat(pgdat) { |
1533 | mask = node_to_cpumask(pgdat->node_id); | 1533 | mask = node_to_cpumask(pgdat->node_id); |
1534 | if (any_online_cpu(mask) != NR_CPUS) | 1534 | if (any_online_cpu(mask) != NR_CPUS) |
diff --git a/mm/vmstat.c b/mm/vmstat.c index 6c488d6ac425..9a66dc4aed43 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c | |||
@@ -650,8 +650,11 @@ static int __cpuinit vmstat_cpuup_callback(struct notifier_block *nfb, | |||
650 | { | 650 | { |
651 | switch (action) { | 651 | switch (action) { |
652 | case CPU_UP_PREPARE: | 652 | case CPU_UP_PREPARE: |
653 | case CPU_UP_PREPARE_FROZEN: | ||
653 | case CPU_UP_CANCELED: | 654 | case CPU_UP_CANCELED: |
655 | case CPU_UP_CANCELED_FROZEN: | ||
654 | case CPU_DEAD: | 656 | case CPU_DEAD: |
657 | case CPU_DEAD_FROZEN: | ||
655 | refresh_zone_stat_thresholds(); | 658 | refresh_zone_stat_thresholds(); |
656 | break; | 659 | break; |
657 | default: | 660 | default: |
diff --git a/net/core/dev.c b/net/core/dev.c index 4317c1be4d3f..8301e2ac747f 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -3450,7 +3450,7 @@ static int dev_cpu_callback(struct notifier_block *nfb, | |||
3450 | unsigned int cpu, oldcpu = (unsigned long)ocpu; | 3450 | unsigned int cpu, oldcpu = (unsigned long)ocpu; |
3451 | struct softnet_data *sd, *oldsd; | 3451 | struct softnet_data *sd, *oldsd; |
3452 | 3452 | ||
3453 | if (action != CPU_DEAD) | 3453 | if (action != CPU_DEAD && action != CPU_DEAD_FROZEN) |
3454 | return NOTIFY_OK; | 3454 | return NOTIFY_OK; |
3455 | 3455 | ||
3456 | local_irq_disable(); | 3456 | local_irq_disable(); |
diff --git a/net/core/flow.c b/net/core/flow.c index 5d25697920b1..051430545a05 100644 --- a/net/core/flow.c +++ b/net/core/flow.c | |||
@@ -338,7 +338,7 @@ static int flow_cache_cpu(struct notifier_block *nfb, | |||
338 | unsigned long action, | 338 | unsigned long action, |
339 | void *hcpu) | 339 | void *hcpu) |
340 | { | 340 | { |
341 | if (action == CPU_DEAD) | 341 | if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) |
342 | __flow_cache_shrink((unsigned long)hcpu, 0); | 342 | __flow_cache_shrink((unsigned long)hcpu, 0); |
343 | return NOTIFY_OK; | 343 | return NOTIFY_OK; |
344 | } | 344 | } |
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c index fb3faf72e850..b7333061016d 100644 --- a/net/iucv/iucv.c +++ b/net/iucv/iucv.c | |||
@@ -556,6 +556,7 @@ static int __cpuinit iucv_cpu_notify(struct notifier_block *self, | |||
556 | 556 | ||
557 | switch (action) { | 557 | switch (action) { |
558 | case CPU_UP_PREPARE: | 558 | case CPU_UP_PREPARE: |
559 | case CPU_UP_PREPARE_FROZEN: | ||
559 | if (!percpu_populate(iucv_irq_data, | 560 | if (!percpu_populate(iucv_irq_data, |
560 | sizeof(struct iucv_irq_data), | 561 | sizeof(struct iucv_irq_data), |
561 | GFP_KERNEL|GFP_DMA, cpu)) | 562 | GFP_KERNEL|GFP_DMA, cpu)) |
@@ -567,15 +568,20 @@ static int __cpuinit iucv_cpu_notify(struct notifier_block *self, | |||
567 | } | 568 | } |
568 | break; | 569 | break; |
569 | case CPU_UP_CANCELED: | 570 | case CPU_UP_CANCELED: |
571 | case CPU_UP_CANCELED_FROZEN: | ||
570 | case CPU_DEAD: | 572 | case CPU_DEAD: |
573 | case CPU_DEAD_FROZEN: | ||
571 | percpu_depopulate(iucv_param, cpu); | 574 | percpu_depopulate(iucv_param, cpu); |
572 | percpu_depopulate(iucv_irq_data, cpu); | 575 | percpu_depopulate(iucv_irq_data, cpu); |
573 | break; | 576 | break; |
574 | case CPU_ONLINE: | 577 | case CPU_ONLINE: |
578 | case CPU_ONLINE_FROZEN: | ||
575 | case CPU_DOWN_FAILED: | 579 | case CPU_DOWN_FAILED: |
580 | case CPU_DOWN_FAILED_FROZEN: | ||
576 | smp_call_function_on(iucv_declare_cpu, NULL, 0, 1, cpu); | 581 | smp_call_function_on(iucv_declare_cpu, NULL, 0, 1, cpu); |
577 | break; | 582 | break; |
578 | case CPU_DOWN_PREPARE: | 583 | case CPU_DOWN_PREPARE: |
584 | case CPU_DOWN_PREPARE_FROZEN: | ||
579 | cpumask = iucv_buffer_cpumask; | 585 | cpumask = iucv_buffer_cpumask; |
580 | cpu_clear(cpu, cpumask); | 586 | cpu_clear(cpu, cpumask); |
581 | if (cpus_empty(cpumask)) | 587 | if (cpus_empty(cpumask)) |