aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorManfred Spraul <manfred@colorfullife.com>2008-09-07 10:57:22 -0400
committerIngo Molnar <mingo@elte.hu>2008-09-08 13:25:24 -0400
commite545a6140b698b2494daf0b32107bdcc5e901390 (patch)
tree63f302e25ba7a0705bbf051f3817fac8f8b98aba /arch
parent7686ad5606f08d9dfb33a2087a36c8366366015b (diff)
kernel/cpu.c: create a CPU_STARTING cpu_chain notifier
Right now, there is no notifier that is called on a new cpu, before the new cpu begins processing interrupts/softirqs. Various kernel function would need that notification, e.g. kvm works around by calling smp_call_function_single(), rcu polls cpu_online_map. The patch adds a CPU_STARTING notification. It also adds a helper function that sends the message to all cpu_chain handlers. Tested on x86-64. All other archs are untested. Especially on sparc, I'm not sure if I got it right. Signed-off-by: Manfred Spraul <manfred@colorfullife.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/kernel/smp.c3
-rw-r--r--arch/arm/kernel/smp.c1
-rw-r--r--arch/cris/arch-v32/kernel/smp.c1
-rw-r--r--arch/ia64/kernel/smpboot.c1
-rw-r--r--arch/m32r/kernel/smpboot.c2
-rw-r--r--arch/mips/kernel/smp.c2
-rw-r--r--arch/powerpc/kernel/smp.c1
-rw-r--r--arch/s390/kernel/smp.c2
-rw-r--r--arch/sh/kernel/smp.c2
-rw-r--r--arch/sparc/kernel/sun4d_smp.c1
-rw-r--r--arch/sparc/kernel/sun4m_smp.c2
-rw-r--r--arch/um/kernel/smp.c1
-rw-r--r--arch/x86/kernel/smpboot.c1
-rw-r--r--arch/x86/mach-voyager/voyager_smp.c2
14 files changed, 22 insertions, 0 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