aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/smpboot.c
diff options
context:
space:
mode:
authorAshok Raj <ashok.raj@intel.com>2005-11-11 17:32:40 -0500
committerTony Luck <tony.luck@intel.com>2006-01-05 13:24:20 -0500
commitff741906ad3cf4b8ca1a958acb013a97a6381ca2 (patch)
tree66a4c2dbacd4c10015824a6789f9206693003092 /arch/ia64/kernel/smpboot.c
parentdb9edfd7e339ca4113153d887e782dd05be5a9eb (diff)
[IA64] support for cpu0 removal
here is the BSP removal support for IA64. Its pretty much the same thing that was released a while back, but has your feedback incorporated. - Removed CONFIG_BSP_REMOVE_WORKAROUND and associated cmdline param - Fixed compile issue with sn2/zx1 due to a undefined fix_b0_for_bsp - some formatting nits (whitespace etc) This has been tested on tiger and long back by alex on hp systems as well. Signed-off-by: Ashok Raj <ashok.raj@intel.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64/kernel/smpboot.c')
-rw-r--r--arch/ia64/kernel/smpboot.c114
1 files changed, 108 insertions, 6 deletions
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index 8f44e7d2df66..e9d37bf67d69 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -70,6 +70,12 @@
70#endif 70#endif
71 71
72#ifdef CONFIG_HOTPLUG_CPU 72#ifdef CONFIG_HOTPLUG_CPU
73#ifdef CONFIG_PERMIT_BSP_REMOVE
74#define bsp_remove_ok 1
75#else
76#define bsp_remove_ok 0
77#endif
78
73/* 79/*
74 * Store all idle threads, this can be reused instead of creating 80 * Store all idle threads, this can be reused instead of creating
75 * a new thread. Also avoids complicated thread destroy functionality 81 * a new thread. Also avoids complicated thread destroy functionality
@@ -104,7 +110,7 @@ struct sal_to_os_boot *sal_state_for_booting_cpu = &sal_boot_rendez_state[0];
104/* 110/*
105 * ITC synchronization related stuff: 111 * ITC synchronization related stuff:
106 */ 112 */
107#define MASTER 0 113#define MASTER (0)
108#define SLAVE (SMP_CACHE_BYTES/8) 114#define SLAVE (SMP_CACHE_BYTES/8)
109 115
110#define NUM_ROUNDS 64 /* magic value */ 116#define NUM_ROUNDS 64 /* magic value */
@@ -151,6 +157,27 @@ char __initdata no_int_routing;
151 157
152unsigned char smp_int_redirect; /* are INT and IPI redirectable by the chipset? */ 158unsigned char smp_int_redirect; /* are INT and IPI redirectable by the chipset? */
153 159
160#ifdef CONFIG_FORCE_CPEI_RETARGET
161#define CPEI_OVERRIDE_DEFAULT (1)
162#else
163#define CPEI_OVERRIDE_DEFAULT (0)
164#endif
165
166unsigned int force_cpei_retarget = CPEI_OVERRIDE_DEFAULT;
167
168static int __init
169cmdl_force_cpei(char *str)
170{
171 int value=0;
172
173 get_option (&str, &value);
174 force_cpei_retarget = value;
175
176 return 1;
177}
178
179__setup("force_cpei=", cmdl_force_cpei);
180
154static int __init 181static int __init
155nointroute (char *str) 182nointroute (char *str)
156{ 183{
@@ -161,6 +188,27 @@ nointroute (char *str)
161 188
162__setup("nointroute", nointroute); 189__setup("nointroute", nointroute);
163 190
191static void fix_b0_for_bsp(void)
192{
193#ifdef CONFIG_HOTPLUG_CPU
194 int cpuid;
195 static int fix_bsp_b0 = 1;
196
197 cpuid = smp_processor_id();
198
199 /*
200 * Cache the b0 value on the first AP that comes up
201 */
202 if (!(fix_bsp_b0 && cpuid))
203 return;
204
205 sal_boot_rendez_state[0].br[0] = sal_boot_rendez_state[cpuid].br[0];
206 printk ("Fixed BSP b0 value from CPU %d\n", cpuid);
207
208 fix_bsp_b0 = 0;
209#endif
210}
211
164void 212void
165sync_master (void *arg) 213sync_master (void *arg)
166{ 214{
@@ -327,8 +375,9 @@ smp_setup_percpu_timer (void)
327static void __devinit 375static void __devinit
328smp_callin (void) 376smp_callin (void)
329{ 377{
330 int cpuid, phys_id; 378 int cpuid, phys_id, itc_master;
331 extern void ia64_init_itm(void); 379 extern void ia64_init_itm(void);
380 extern volatile int time_keeper_id;
332 381
333#ifdef CONFIG_PERFMON 382#ifdef CONFIG_PERFMON
334 extern void pfm_init_percpu(void); 383 extern void pfm_init_percpu(void);
@@ -336,6 +385,7 @@ smp_callin (void)
336 385
337 cpuid = smp_processor_id(); 386 cpuid = smp_processor_id();
338 phys_id = hard_smp_processor_id(); 387 phys_id = hard_smp_processor_id();
388 itc_master = time_keeper_id;
339 389
340 if (cpu_online(cpuid)) { 390 if (cpu_online(cpuid)) {
341 printk(KERN_ERR "huh, phys CPU#0x%x, CPU#0x%x already present??\n", 391 printk(KERN_ERR "huh, phys CPU#0x%x, CPU#0x%x already present??\n",
@@ -343,6 +393,8 @@ smp_callin (void)
343 BUG(); 393 BUG();
344 } 394 }
345 395
396 fix_b0_for_bsp();
397
346 lock_ipi_calllock(); 398 lock_ipi_calllock();
347 cpu_set(cpuid, cpu_online_map); 399 cpu_set(cpuid, cpu_online_map);
348 unlock_ipi_calllock(); 400 unlock_ipi_calllock();
@@ -365,8 +417,8 @@ smp_callin (void)
365 * calls spin_unlock_bh(), which calls spin_unlock_bh(), which calls 417 * calls spin_unlock_bh(), which calls spin_unlock_bh(), which calls
366 * local_bh_enable(), which bugs out if irqs are not enabled... 418 * local_bh_enable(), which bugs out if irqs are not enabled...
367 */ 419 */
368 Dprintk("Going to syncup ITC with BP.\n"); 420 Dprintk("Going to syncup ITC with ITC Master.\n");
369 ia64_sync_itc(0); 421 ia64_sync_itc(itc_master);
370 } 422 }
371 423
372 /* 424 /*
@@ -638,6 +690,47 @@ remove_siblinginfo(int cpu)
638} 690}
639 691
640extern void fixup_irqs(void); 692extern void fixup_irqs(void);
693
694int migrate_platform_irqs(unsigned int cpu)
695{
696 int new_cpei_cpu;
697 irq_desc_t *desc = NULL;
698 cpumask_t mask;
699 int retval = 0;
700
701 /*
702 * dont permit CPEI target to removed.
703 */
704 if (cpe_vector > 0 && is_cpu_cpei_target(cpu)) {
705 printk ("CPU (%d) is CPEI Target\n", cpu);
706 if (can_cpei_retarget()) {
707 /*
708 * Now re-target the CPEI to a different processor
709 */
710 new_cpei_cpu = any_online_cpu(cpu_online_map);
711 mask = cpumask_of_cpu(new_cpei_cpu);
712 set_cpei_target_cpu(new_cpei_cpu);
713 desc = irq_descp(ia64_cpe_irq);
714 /*
715 * Switch for now, immediatly, we need to do fake intr
716 * as other interrupts, but need to study CPEI behaviour with
717 * polling before making changes.
718 */
719 if (desc) {
720 desc->handler->disable(ia64_cpe_irq);
721 desc->handler->set_affinity(ia64_cpe_irq, mask);
722 desc->handler->enable(ia64_cpe_irq);
723 printk ("Re-targetting CPEI to cpu %d\n", new_cpei_cpu);
724 }
725 }
726 if (!desc) {
727 printk ("Unable to retarget CPEI, offline cpu [%d] failed\n", cpu);
728 retval = -EBUSY;
729 }
730 }
731 return retval;
732}
733
641/* must be called with cpucontrol mutex held */ 734/* must be called with cpucontrol mutex held */
642int __cpu_disable(void) 735int __cpu_disable(void)
643{ 736{
@@ -646,8 +739,17 @@ int __cpu_disable(void)
646 /* 739 /*
647 * dont permit boot processor for now 740 * dont permit boot processor for now
648 */ 741 */
649 if (cpu == 0) 742 if (cpu == 0 && !bsp_remove_ok) {
650 return -EBUSY; 743 printk ("Your platform does not support removal of BSP\n");
744 return (-EBUSY);
745 }
746
747 cpu_clear(cpu, cpu_online_map);
748
749 if (migrate_platform_irqs(cpu)) {
750 cpu_set(cpu, cpu_online_map);
751 return (-EBUSY);
752 }
651 753
652 remove_siblinginfo(cpu); 754 remove_siblinginfo(cpu);
653 cpu_clear(cpu, cpu_online_map); 755 cpu_clear(cpu, cpu_online_map);