diff options
-rw-r--r-- | arch/alpha/kernel/smp.c | 3 | ||||
-rw-r--r-- | arch/arm/kernel/smp.c | 1 | ||||
-rw-r--r-- | arch/cris/arch-v32/kernel/smp.c | 1 | ||||
-rw-r--r-- | arch/ia64/kernel/smpboot.c | 1 | ||||
-rw-r--r-- | arch/m32r/kernel/smpboot.c | 2 | ||||
-rw-r--r-- | arch/mips/kernel/smp.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/smp.c | 1 | ||||
-rw-r--r-- | arch/s390/kernel/smp.c | 2 | ||||
-rw-r--r-- | arch/sh/kernel/smp.c | 2 | ||||
-rw-r--r-- | arch/sparc/kernel/sun4d_smp.c | 1 | ||||
-rw-r--r-- | arch/sparc/kernel/sun4m_smp.c | 2 | ||||
-rw-r--r-- | arch/um/kernel/smp.c | 1 | ||||
-rw-r--r-- | arch/x86/kernel/smpboot.c | 1 | ||||
-rw-r--r-- | arch/x86/mach-voyager/voyager_smp.c | 2 | ||||
-rw-r--r-- | include/linux/cpu.h | 1 | ||||
-rw-r--r-- | include/linux/notifier.h | 10 | ||||
-rw-r--r-- | kernel/cpu.c | 19 |
17 files changed, 51 insertions, 1 deletions
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index 83df541650fc..06b6fdab639f 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c | |||
@@ -149,6 +149,9 @@ smp_callin(void) | |||
149 | atomic_inc(&init_mm.mm_count); | 149 | atomic_inc(&init_mm.mm_count); |
150 | current->active_mm = &init_mm; | 150 | current->active_mm = &init_mm; |
151 | 151 | ||
152 | /* inform the notifiers about the new cpu */ | ||
153 | notify_cpu_starting(cpuid); | ||
154 | |||
152 | /* Must have completely accurate bogos. */ | 155 | /* Must have completely accurate bogos. */ |
153 | local_irq_enable(); | 156 | local_irq_enable(); |
154 | 157 | ||
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index e9842f6767f9..e42a749a56dd 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
@@ -277,6 +277,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void) | |||
277 | /* | 277 | /* |
278 | * Enable local interrupts. | 278 | * Enable local interrupts. |
279 | */ | 279 | */ |
280 | notify_cpu_starting(cpu); | ||
280 | local_irq_enable(); | 281 | local_irq_enable(); |
281 | local_fiq_enable(); | 282 | local_fiq_enable(); |
282 | 283 | ||
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c index 952a24b2f5a9..52e16c6436f9 100644 --- a/arch/cris/arch-v32/kernel/smp.c +++ b/arch/cris/arch-v32/kernel/smp.c | |||
@@ -178,6 +178,7 @@ void __init smp_callin(void) | |||
178 | unmask_irq(IPI_INTR_VECT); | 178 | unmask_irq(IPI_INTR_VECT); |
179 | unmask_irq(TIMER0_INTR_VECT); | 179 | unmask_irq(TIMER0_INTR_VECT); |
180 | preempt_disable(); | 180 | preempt_disable(); |
181 | notify_cpu_starting(cpu); | ||
181 | local_irq_enable(); | 182 | local_irq_enable(); |
182 | 183 | ||
183 | cpu_set(cpu, cpu_online_map); | 184 | cpu_set(cpu, cpu_online_map); |
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index bcea81e432fd..333b58f218d0 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c | |||
@@ -401,6 +401,7 @@ smp_callin (void) | |||
401 | spin_lock(&vector_lock); | 401 | spin_lock(&vector_lock); |
402 | /* Setup the per cpu irq handling data structures */ | 402 | /* Setup the per cpu irq handling data structures */ |
403 | __setup_vector_irq(cpuid); | 403 | __setup_vector_irq(cpuid); |
404 | notify_cpu_starting(cpuid); | ||
404 | cpu_set(cpuid, cpu_online_map); | 405 | cpu_set(cpuid, cpu_online_map); |
405 | per_cpu(cpu_state, cpuid) = CPU_ONLINE; | 406 | per_cpu(cpu_state, cpuid) = CPU_ONLINE; |
406 | spin_unlock(&vector_lock); | 407 | spin_unlock(&vector_lock); |
diff --git a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c index 2c03ac1d005f..fc2994811f15 100644 --- a/arch/m32r/kernel/smpboot.c +++ b/arch/m32r/kernel/smpboot.c | |||
@@ -498,6 +498,8 @@ static void __init smp_online(void) | |||
498 | { | 498 | { |
499 | int cpu_id = smp_processor_id(); | 499 | int cpu_id = smp_processor_id(); |
500 | 500 | ||
501 | notify_cpu_starting(cpu_id); | ||
502 | |||
501 | local_irq_enable(); | 503 | local_irq_enable(); |
502 | 504 | ||
503 | /* Get our bogomips. */ | 505 | /* Get our bogomips. */ |
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 4410f172b8ab..7b59cfb7e602 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c | |||
@@ -121,6 +121,8 @@ asmlinkage __cpuinit void start_secondary(void) | |||
121 | cpu = smp_processor_id(); | 121 | cpu = smp_processor_id(); |
122 | cpu_data[cpu].udelay_val = loops_per_jiffy; | 122 | cpu_data[cpu].udelay_val = loops_per_jiffy; |
123 | 123 | ||
124 | notify_cpu_starting(cpu); | ||
125 | |||
124 | mp_ops->smp_finish(); | 126 | mp_ops->smp_finish(); |
125 | set_cpu_sibling_map(cpu); | 127 | set_cpu_sibling_map(cpu); |
126 | 128 | ||
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 5337ca7bb649..c27b10a1bd79 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -453,6 +453,7 @@ int __devinit start_secondary(void *unused) | |||
453 | secondary_cpu_time_init(); | 453 | secondary_cpu_time_init(); |
454 | 454 | ||
455 | ipi_call_lock(); | 455 | ipi_call_lock(); |
456 | notify_cpu_starting(cpu); | ||
456 | cpu_set(cpu, cpu_online_map); | 457 | cpu_set(cpu, cpu_online_map); |
457 | /* Update sibling maps */ | 458 | /* Update sibling maps */ |
458 | base = cpu_first_thread_in_core(cpu); | 459 | base = cpu_first_thread_in_core(cpu); |
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 00b9b4dec5eb..9e8b1f9b8f4d 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -585,6 +585,8 @@ int __cpuinit start_secondary(void *cpuvoid) | |||
585 | /* Enable pfault pseudo page faults on this cpu. */ | 585 | /* Enable pfault pseudo page faults on this cpu. */ |
586 | pfault_init(); | 586 | pfault_init(); |
587 | 587 | ||
588 | /* call cpu notifiers */ | ||
589 | notify_cpu_starting(smp_processor_id()); | ||
588 | /* Mark this cpu as online */ | 590 | /* Mark this cpu as online */ |
589 | spin_lock(&call_lock); | 591 | spin_lock(&call_lock); |
590 | cpu_set(smp_processor_id(), cpu_online_map); | 592 | cpu_set(smp_processor_id(), cpu_online_map); |
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index 60c50841143e..001778f9adaf 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c | |||
@@ -82,6 +82,8 @@ asmlinkage void __cpuinit start_secondary(void) | |||
82 | 82 | ||
83 | preempt_disable(); | 83 | preempt_disable(); |
84 | 84 | ||
85 | notify_cpu_starting(smp_processor_id()); | ||
86 | |||
85 | local_irq_enable(); | 87 | local_irq_enable(); |
86 | 88 | ||
87 | calibrate_delay(); | 89 | calibrate_delay(); |
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index 69596402a500..446767e8f569 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c | |||
@@ -88,6 +88,7 @@ void __init smp4d_callin(void) | |||
88 | local_flush_cache_all(); | 88 | local_flush_cache_all(); |
89 | local_flush_tlb_all(); | 89 | local_flush_tlb_all(); |
90 | 90 | ||
91 | notify_cpu_starting(cpuid); | ||
91 | /* | 92 | /* |
92 | * Unblock the master CPU _only_ when the scheduler state | 93 | * Unblock the master CPU _only_ when the scheduler state |
93 | * of all secondary CPUs will be up-to-date, so after | 94 | * of all secondary CPUs will be up-to-date, so after |
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c index a14a76ac7f36..9964890dc1db 100644 --- a/arch/sparc/kernel/sun4m_smp.c +++ b/arch/sparc/kernel/sun4m_smp.c | |||
@@ -71,6 +71,8 @@ void __cpuinit smp4m_callin(void) | |||
71 | local_flush_cache_all(); | 71 | local_flush_cache_all(); |
72 | local_flush_tlb_all(); | 72 | local_flush_tlb_all(); |
73 | 73 | ||
74 | notify_cpu_starting(cpuid); | ||
75 | |||
74 | /* Get our local ticker going. */ | 76 | /* Get our local ticker going. */ |
75 | smp_setup_percpu_timer(); | 77 | smp_setup_percpu_timer(); |
76 | 78 | ||
diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c index be2d50c3aa95..045772142844 100644 --- a/arch/um/kernel/smp.c +++ b/arch/um/kernel/smp.c | |||
@@ -85,6 +85,7 @@ static int idle_proc(void *cpup) | |||
85 | while (!cpu_isset(cpu, smp_commenced_mask)) | 85 | while (!cpu_isset(cpu, smp_commenced_mask)) |
86 | cpu_relax(); | 86 | cpu_relax(); |
87 | 87 | ||
88 | notify_cpu_starting(cpu); | ||
88 | cpu_set(cpu, cpu_online_map); | 89 | cpu_set(cpu, cpu_online_map); |
89 | default_idle(); | 90 | default_idle(); |
90 | return 0; | 91 | return 0; |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 7985c5b3f916..0b8261c3cac2 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -257,6 +257,7 @@ static void __cpuinit smp_callin(void) | |||
257 | end_local_APIC_setup(); | 257 | end_local_APIC_setup(); |
258 | map_cpu_to_logical_apicid(); | 258 | map_cpu_to_logical_apicid(); |
259 | 259 | ||
260 | notify_cpu_starting(cpuid); | ||
260 | /* | 261 | /* |
261 | * Get our bogomips. | 262 | * Get our bogomips. |
262 | * | 263 | * |
diff --git a/arch/x86/mach-voyager/voyager_smp.c b/arch/x86/mach-voyager/voyager_smp.c index ee0fba092157..199a5f4a873c 100644 --- a/arch/x86/mach-voyager/voyager_smp.c +++ b/arch/x86/mach-voyager/voyager_smp.c | |||
@@ -448,6 +448,8 @@ static void __init start_secondary(void *unused) | |||
448 | 448 | ||
449 | VDEBUG(("VOYAGER SMP: CPU%d, stack at about %p\n", cpuid, &cpuid)); | 449 | VDEBUG(("VOYAGER SMP: CPU%d, stack at about %p\n", cpuid, &cpuid)); |
450 | 450 | ||
451 | notify_cpu_starting(cpuid); | ||
452 | |||
451 | /* enable interrupts */ | 453 | /* enable interrupts */ |
452 | local_irq_enable(); | 454 | local_irq_enable(); |
453 | 455 | ||
diff --git a/include/linux/cpu.h b/include/linux/cpu.h index d7faf8808497..c2747ac2ae43 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h | |||
@@ -69,6 +69,7 @@ static inline void unregister_cpu_notifier(struct notifier_block *nb) | |||
69 | #endif | 69 | #endif |
70 | 70 | ||
71 | int cpu_up(unsigned int cpu); | 71 | int cpu_up(unsigned int cpu); |
72 | void notify_cpu_starting(unsigned int cpu); | ||
72 | extern void cpu_hotplug_init(void); | 73 | extern void cpu_hotplug_init(void); |
73 | extern void cpu_maps_update_begin(void); | 74 | extern void cpu_maps_update_begin(void); |
74 | extern void cpu_maps_update_done(void); | 75 | extern void cpu_maps_update_done(void); |
diff --git a/include/linux/notifier.h b/include/linux/notifier.h index da2698b0fdd1..b86fa2ffca0c 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h | |||
@@ -213,9 +213,16 @@ static inline int notifier_to_errno(int ret) | |||
213 | #define CPU_DOWN_FAILED 0x0006 /* CPU (unsigned)v NOT going down */ | 213 | #define CPU_DOWN_FAILED 0x0006 /* CPU (unsigned)v NOT going down */ |
214 | #define CPU_DEAD 0x0007 /* CPU (unsigned)v dead */ | 214 | #define CPU_DEAD 0x0007 /* CPU (unsigned)v dead */ |
215 | #define CPU_DYING 0x0008 /* CPU (unsigned)v not running any task, | 215 | #define CPU_DYING 0x0008 /* CPU (unsigned)v not running any task, |
216 | * not handling interrupts, soon dead */ | 216 | * not handling interrupts, soon dead. |
217 | * Called on the dying cpu, interrupts | ||
218 | * are already disabled. Must not | ||
219 | * sleep, must not fail */ | ||
217 | #define CPU_POST_DEAD 0x0009 /* CPU (unsigned)v dead, cpu_hotplug | 220 | #define CPU_POST_DEAD 0x0009 /* CPU (unsigned)v dead, cpu_hotplug |
218 | * lock is dropped */ | 221 | * lock is dropped */ |
222 | #define CPU_STARTING 0x000A /* CPU (unsigned)v soon running. | ||
223 | * Called on the new cpu, just before | ||
224 | * enabling interrupts. Must not sleep, | ||
225 | * must not fail */ | ||
219 | 226 | ||
220 | /* Used for CPU hotplug events occuring while tasks are frozen due to a suspend | 227 | /* Used for CPU hotplug events occuring while tasks are frozen due to a suspend |
221 | * operation in progress | 228 | * operation in progress |
@@ -229,6 +236,7 @@ static inline int notifier_to_errno(int ret) | |||
229 | #define CPU_DOWN_FAILED_FROZEN (CPU_DOWN_FAILED | CPU_TASKS_FROZEN) | 236 | #define CPU_DOWN_FAILED_FROZEN (CPU_DOWN_FAILED | CPU_TASKS_FROZEN) |
230 | #define CPU_DEAD_FROZEN (CPU_DEAD | CPU_TASKS_FROZEN) | 237 | #define CPU_DEAD_FROZEN (CPU_DEAD | CPU_TASKS_FROZEN) |
231 | #define CPU_DYING_FROZEN (CPU_DYING | CPU_TASKS_FROZEN) | 238 | #define CPU_DYING_FROZEN (CPU_DYING | CPU_TASKS_FROZEN) |
239 | #define CPU_STARTING_FROZEN (CPU_STARTING | CPU_TASKS_FROZEN) | ||
232 | 240 | ||
233 | /* Hibernation and suspend events */ | 241 | /* Hibernation and suspend events */ |
234 | #define PM_HIBERNATION_PREPARE 0x0001 /* Going to hibernate */ | 242 | #define PM_HIBERNATION_PREPARE 0x0001 /* Going to hibernate */ |
diff --git a/kernel/cpu.c b/kernel/cpu.c index f17e9854c246..dc45f2459efb 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
@@ -453,6 +453,25 @@ out: | |||
453 | } | 453 | } |
454 | #endif /* CONFIG_PM_SLEEP_SMP */ | 454 | #endif /* CONFIG_PM_SLEEP_SMP */ |
455 | 455 | ||
456 | /** | ||
457 | * notify_cpu_starting(cpu) - call the CPU_STARTING notifiers | ||
458 | * @cpu: cpu that just started | ||
459 | * | ||
460 | * This function calls the cpu_chain notifiers with CPU_STARTING. | ||
461 | * It must be called by the arch code on the new cpu, before the new cpu | ||
462 | * enables interrupts and before the "boot" cpu returns from __cpu_up(). | ||
463 | */ | ||
464 | void notify_cpu_starting(unsigned int cpu) | ||
465 | { | ||
466 | unsigned long val = CPU_STARTING; | ||
467 | |||
468 | #ifdef CONFIG_PM_SLEEP_SMP | ||
469 | if (cpu_isset(cpu, frozen_cpus)) | ||
470 | val = CPU_STARTING_FROZEN; | ||
471 | #endif /* CONFIG_PM_SLEEP_SMP */ | ||
472 | raw_notifier_call_chain(&cpu_chain, val, (void *)(long)cpu); | ||
473 | } | ||
474 | |||
456 | #endif /* CONFIG_SMP */ | 475 | #endif /* CONFIG_SMP */ |
457 | 476 | ||
458 | /* | 477 | /* |