aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/cpu-hotplug.txt10
-rw-r--r--arch/s390/kernel/setup.c2
-rw-r--r--arch/s390/kernel/smp.c58
-rw-r--r--include/asm-s390/smp.h2
4 files changed, 49 insertions, 23 deletions
diff --git a/Documentation/cpu-hotplug.txt b/Documentation/cpu-hotplug.txt
index e05278087ffa..4d3355da0e26 100644
--- a/Documentation/cpu-hotplug.txt
+++ b/Documentation/cpu-hotplug.txt
@@ -11,6 +11,8 @@
11 Joel Schopp <jschopp@austin.ibm.com> 11 Joel Schopp <jschopp@austin.ibm.com>
12 ia64/x86_64: 12 ia64/x86_64:
13 Ashok Raj <ashok.raj@intel.com> 13 Ashok Raj <ashok.raj@intel.com>
14 s390:
15 Heiko Carstens <heiko.carstens@de.ibm.com>
14 16
15Authors: Ashok Raj <ashok.raj@intel.com> 17Authors: Ashok Raj <ashok.raj@intel.com>
16Lots of feedback: Nathan Lynch <nathanl@austin.ibm.com>, 18Lots of feedback: Nathan Lynch <nathanl@austin.ibm.com>,
@@ -44,11 +46,9 @@ maxcpus=n Restrict boot time cpus to n. Say if you have 4 cpus, using
44 maxcpus=2 will only boot 2. You can choose to bring the 46 maxcpus=2 will only boot 2. You can choose to bring the
45 other cpus later online, read FAQ's for more info. 47 other cpus later online, read FAQ's for more info.
46 48
47additional_cpus*=n Use this to limit hotpluggable cpus. This option sets 49additional_cpus=n [x86_64, s390 only] use this to limit hotpluggable cpus.
48 cpu_possible_map = cpu_present_map + additional_cpus 50 This option sets
49 51 cpu_possible_map = cpu_present_map + additional_cpus
50(*) Option valid only for following architectures
51- x86_64, ia64
52 52
53ia64 and x86_64 use the number of disabled local apics in ACPI tables MADT 53ia64 and x86_64 use the number of disabled local apics in ACPI tables MADT
54to determine the number of potentially hot-pluggable cpus. The implementation 54to determine the number of potentially hot-pluggable cpus. The implementation
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index de8784267473..24f62f16c0e5 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -600,6 +600,7 @@ setup_arch(char **cmdline_p)
600 init_mm.brk = (unsigned long) &_end; 600 init_mm.brk = (unsigned long) &_end;
601 601
602 parse_cmdline_early(cmdline_p); 602 parse_cmdline_early(cmdline_p);
603 parse_early_param();
603 604
604 setup_memory(); 605 setup_memory();
605 setup_resources(); 606 setup_resources();
@@ -607,6 +608,7 @@ setup_arch(char **cmdline_p)
607 608
608 cpu_init(); 609 cpu_init();
609 __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr; 610 __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr;
611 smp_setup_cpu_possible_map();
610 612
611 /* 613 /*
612 * Create kernel page tables and switch to virtual addressing. 614 * Create kernel page tables and switch to virtual addressing.
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 0d1ad5dbe2b1..53291e94ac7b 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -1,8 +1,7 @@
1/* 1/*
2 * arch/s390/kernel/smp.c 2 * arch/s390/kernel/smp.c
3 * 3 *
4 * S390 version 4 * Copyright (C) IBM Corp. 1999,2006
5 * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
6 * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), 5 * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
7 * Martin Schwidefsky (schwidefsky@de.ibm.com) 6 * Martin Schwidefsky (schwidefsky@de.ibm.com)
8 * Heiko Carstens (heiko.carstens@de.ibm.com) 7 * Heiko Carstens (heiko.carstens@de.ibm.com)
@@ -41,8 +40,6 @@
41#include <asm/cpcmd.h> 40#include <asm/cpcmd.h>
42#include <asm/tlbflush.h> 41#include <asm/tlbflush.h>
43 42
44/* prototypes */
45
46extern volatile int __cpu_logical_map[]; 43extern volatile int __cpu_logical_map[];
47 44
48/* 45/*
@@ -51,13 +48,11 @@ extern volatile int __cpu_logical_map[];
51 48
52struct _lowcore *lowcore_ptr[NR_CPUS]; 49struct _lowcore *lowcore_ptr[NR_CPUS];
53 50
54cpumask_t cpu_online_map; 51cpumask_t cpu_online_map = CPU_MASK_NONE;
55cpumask_t cpu_possible_map = CPU_MASK_ALL; 52cpumask_t cpu_possible_map = CPU_MASK_NONE;
56 53
57static struct task_struct *current_set[NR_CPUS]; 54static struct task_struct *current_set[NR_CPUS];
58 55
59EXPORT_SYMBOL(cpu_online_map);
60
61/* 56/*
62 * Reboot, halt and power_off routines for SMP. 57 * Reboot, halt and power_off routines for SMP.
63 */ 58 */
@@ -490,10 +485,10 @@ void smp_ctl_clear_bit(int cr, int bit) {
490 * Lets check how many CPUs we have. 485 * Lets check how many CPUs we have.
491 */ 486 */
492 487
493void 488static unsigned int
494__init smp_check_cpus(unsigned int max_cpus) 489__init smp_count_cpus(void)
495{ 490{
496 int cpu, num_cpus; 491 unsigned int cpu, num_cpus;
497 __u16 boot_cpu_addr; 492 __u16 boot_cpu_addr;
498 493
499 /* 494 /*
@@ -503,19 +498,20 @@ __init smp_check_cpus(unsigned int max_cpus)
503 boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr; 498 boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
504 current_thread_info()->cpu = 0; 499 current_thread_info()->cpu = 0;
505 num_cpus = 1; 500 num_cpus = 1;
506 for (cpu = 0; cpu <= 65535 && num_cpus < max_cpus; cpu++) { 501 for (cpu = 0; cpu <= 65535; cpu++) {
507 if ((__u16) cpu == boot_cpu_addr) 502 if ((__u16) cpu == boot_cpu_addr)
508 continue; 503 continue;
509 __cpu_logical_map[num_cpus] = (__u16) cpu; 504 __cpu_logical_map[1] = (__u16) cpu;
510 if (signal_processor(num_cpus, sigp_sense) == 505 if (signal_processor(1, sigp_sense) ==
511 sigp_not_operational) 506 sigp_not_operational)
512 continue; 507 continue;
513 cpu_set(num_cpus, cpu_present_map);
514 num_cpus++; 508 num_cpus++;
515 } 509 }
516 510
517 printk("Detected %d CPU's\n",(int) num_cpus); 511 printk("Detected %d CPU's\n",(int) num_cpus);
518 printk("Boot cpu address %2X\n", boot_cpu_addr); 512 printk("Boot cpu address %2X\n", boot_cpu_addr);
513
514 return num_cpus;
519} 515}
520 516
521/* 517/*
@@ -676,6 +672,32 @@ __cpu_up(unsigned int cpu)
676 return 0; 672 return 0;
677} 673}
678 674
675static unsigned int __initdata additional_cpus;
676
677void __init smp_setup_cpu_possible_map(void)
678{
679 unsigned int pcpus, cpu;
680
681 pcpus = smp_count_cpus() + additional_cpus;
682
683 if (pcpus > NR_CPUS)
684 pcpus = NR_CPUS;
685
686 for (cpu = 0; cpu < pcpus; cpu++)
687 cpu_set(cpu, cpu_possible_map);
688
689 cpu_present_map = cpu_possible_map;
690}
691
692#ifdef CONFIG_HOTPLUG_CPU
693
694static int __init setup_additional_cpus(char *s)
695{
696 additional_cpus = simple_strtoul(s, NULL, 0);
697 return 0;
698}
699early_param("additional_cpus", setup_additional_cpus);
700
679int 701int
680__cpu_disable(void) 702__cpu_disable(void)
681{ 703{
@@ -744,6 +766,8 @@ cpu_die(void)
744 for(;;); 766 for(;;);
745} 767}
746 768
769#endif /* CONFIG_HOTPLUG_CPU */
770
747/* 771/*
748 * Cycle through the processors and setup structures. 772 * Cycle through the processors and setup structures.
749 */ 773 */
@@ -757,7 +781,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
757 /* request the 0x1201 emergency signal external interrupt */ 781 /* request the 0x1201 emergency signal external interrupt */
758 if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0) 782 if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0)
759 panic("Couldn't request external interrupt 0x1201"); 783 panic("Couldn't request external interrupt 0x1201");
760 smp_check_cpus(max_cpus);
761 memset(lowcore_ptr,0,sizeof(lowcore_ptr)); 784 memset(lowcore_ptr,0,sizeof(lowcore_ptr));
762 /* 785 /*
763 * Initialize prefix pages and stacks for all possible cpus 786 * Initialize prefix pages and stacks for all possible cpus
@@ -806,14 +829,12 @@ void __devinit smp_prepare_boot_cpu(void)
806 BUG_ON(smp_processor_id() != 0); 829 BUG_ON(smp_processor_id() != 0);
807 830
808 cpu_set(0, cpu_online_map); 831 cpu_set(0, cpu_online_map);
809 cpu_set(0, cpu_present_map);
810 S390_lowcore.percpu_offset = __per_cpu_offset[0]; 832 S390_lowcore.percpu_offset = __per_cpu_offset[0];
811 current_set[0] = current; 833 current_set[0] = current;
812} 834}
813 835
814void smp_cpus_done(unsigned int max_cpus) 836void smp_cpus_done(unsigned int max_cpus)
815{ 837{
816 cpu_present_map = cpu_possible_map;
817} 838}
818 839
819/* 840/*
@@ -845,6 +866,7 @@ static int __init topology_init(void)
845 866
846subsys_initcall(topology_init); 867subsys_initcall(topology_init);
847 868
869EXPORT_SYMBOL(cpu_online_map);
848EXPORT_SYMBOL(cpu_possible_map); 870EXPORT_SYMBOL(cpu_possible_map);
849EXPORT_SYMBOL(lowcore_ptr); 871EXPORT_SYMBOL(lowcore_ptr);
850EXPORT_SYMBOL(smp_ctl_set_bit); 872EXPORT_SYMBOL(smp_ctl_set_bit);
diff --git a/include/asm-s390/smp.h b/include/asm-s390/smp.h
index 9c6e9c300eb9..444dae5912e6 100644
--- a/include/asm-s390/smp.h
+++ b/include/asm-s390/smp.h
@@ -31,6 +31,7 @@ typedef struct
31 __u16 cpu; 31 __u16 cpu;
32} sigp_info; 32} sigp_info;
33 33
34extern void smp_setup_cpu_possible_map(void);
34extern int smp_call_function_on(void (*func) (void *info), void *info, 35extern int smp_call_function_on(void (*func) (void *info), void *info,
35 int nonatomic, int wait, int cpu); 36 int nonatomic, int wait, int cpu);
36#define NO_PROC_ID 0xFF /* No processor magic marker */ 37#define NO_PROC_ID 0xFF /* No processor magic marker */
@@ -104,6 +105,7 @@ smp_call_function_on(void (*func) (void *info), void *info,
104#define smp_cpu_not_running(cpu) 1 105#define smp_cpu_not_running(cpu) 1
105#define smp_get_cpu(cpu) ({ 0; }) 106#define smp_get_cpu(cpu) ({ 0; })
106#define smp_put_cpu(cpu) ({ 0; }) 107#define smp_put_cpu(cpu) ({ 0; })
108#define smp_setup_cpu_possible_map()
107#endif 109#endif
108 110
109#endif 111#endif