diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2006-02-17 16:52:46 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-02-17 16:59:26 -0500 |
commit | 255acee706b333b79f593dd366f16e1f107cccc3 (patch) | |
tree | 47c68487eda1df3bf026444045106301bd3a3ff5 /arch/s390/kernel | |
parent | 1fca251f36fac3fae7d9cf10de69c2c93f6c0000 (diff) |
[PATCH] s390: additional_cpus parameter
Introduce additional_cpus command line option. By default no additional cpu
can be attached to the system anymore. Only the cpus present at IPL time can
be switched on/off. If it is desired that additional cpus can be attached to
the system the maximum number of additional cpus needs to be specified with
this option.
This change is necessary in order to limit the waste of per_cpu data
structures.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r-- | arch/s390/kernel/setup.c | 2 | ||||
-rw-r--r-- | arch/s390/kernel/smp.c | 58 |
2 files changed, 42 insertions, 18 deletions
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); |