diff options
| -rw-r--r-- | Documentation/cpu-hotplug.txt | 10 | ||||
| -rw-r--r-- | arch/s390/kernel/setup.c | 2 | ||||
| -rw-r--r-- | arch/s390/kernel/smp.c | 58 | ||||
| -rw-r--r-- | include/asm-s390/smp.h | 2 |
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 | ||
| 15 | Authors: Ashok Raj <ashok.raj@intel.com> | 17 | Authors: Ashok Raj <ashok.raj@intel.com> |
| 16 | Lots of feedback: Nathan Lynch <nathanl@austin.ibm.com>, | 18 | Lots 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 | ||
| 47 | additional_cpus*=n Use this to limit hotpluggable cpus. This option sets | 49 | additional_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 | ||
| 53 | ia64 and x86_64 use the number of disabled local apics in ACPI tables MADT | 53 | ia64 and x86_64 use the number of disabled local apics in ACPI tables MADT |
| 54 | to determine the number of potentially hot-pluggable cpus. The implementation | 54 | to 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 | |||
| 46 | extern volatile int __cpu_logical_map[]; | 43 | extern volatile int __cpu_logical_map[]; |
| 47 | 44 | ||
| 48 | /* | 45 | /* |
| @@ -51,13 +48,11 @@ extern volatile int __cpu_logical_map[]; | |||
| 51 | 48 | ||
| 52 | struct _lowcore *lowcore_ptr[NR_CPUS]; | 49 | struct _lowcore *lowcore_ptr[NR_CPUS]; |
| 53 | 50 | ||
| 54 | cpumask_t cpu_online_map; | 51 | cpumask_t cpu_online_map = CPU_MASK_NONE; |
| 55 | cpumask_t cpu_possible_map = CPU_MASK_ALL; | 52 | cpumask_t cpu_possible_map = CPU_MASK_NONE; |
| 56 | 53 | ||
| 57 | static struct task_struct *current_set[NR_CPUS]; | 54 | static struct task_struct *current_set[NR_CPUS]; |
| 58 | 55 | ||
| 59 | EXPORT_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 | ||
| 493 | void | 488 | static 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 | ||
| 675 | static unsigned int __initdata additional_cpus; | ||
| 676 | |||
| 677 | void __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 | |||
| 694 | static int __init setup_additional_cpus(char *s) | ||
| 695 | { | ||
| 696 | additional_cpus = simple_strtoul(s, NULL, 0); | ||
| 697 | return 0; | ||
| 698 | } | ||
| 699 | early_param("additional_cpus", setup_additional_cpus); | ||
| 700 | |||
| 679 | int | 701 | int |
| 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 | ||
| 814 | void smp_cpus_done(unsigned int max_cpus) | 836 | void 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 | ||
| 846 | subsys_initcall(topology_init); | 867 | subsys_initcall(topology_init); |
| 847 | 868 | ||
| 869 | EXPORT_SYMBOL(cpu_online_map); | ||
| 848 | EXPORT_SYMBOL(cpu_possible_map); | 870 | EXPORT_SYMBOL(cpu_possible_map); |
| 849 | EXPORT_SYMBOL(lowcore_ptr); | 871 | EXPORT_SYMBOL(lowcore_ptr); |
| 850 | EXPORT_SYMBOL(smp_ctl_set_bit); | 872 | EXPORT_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 | ||
| 34 | extern void smp_setup_cpu_possible_map(void); | ||
| 34 | extern int smp_call_function_on(void (*func) (void *info), void *info, | 35 | extern 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 |
