[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>

authored by Heiko Carstens and committed by Linus Torvalds 255acee7 1fca251f

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