aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2006-02-17 16:52:46 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-02-17 16:59:26 -0500
commit255acee706b333b79f593dd366f16e1f107cccc3 (patch)
tree47c68487eda1df3bf026444045106301bd3a3ff5 /arch/s390/kernel
parent1fca251f36fac3fae7d9cf10de69c2c93f6c0000 (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.c2
-rw-r--r--arch/s390/kernel/smp.c58
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
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);