[patch 1/3] rework ppc64 cpu map setup
Joel Schopp
jschopp at austin.ibm.com
Sat Aug 28 01:40:58 EST 2004
Patch looks great. Now that this is done I think we could remove
systemcfg->processorCount and replace it with num_present_cpus()
everywhere. Simplify the code a bit.
Nathan Lynch wrote:
> Move all cpu map initializations to one place (except for the online
> map -- cpus mark themselves online as they come up). This sets up
> cpu_possible_map early enough that we can use num_possible_cpus for
> allocating irqstacks instead of NR_CPUS. Hopefully this should also
> help set the stage for kexec.
>
> Signed-off-by: Nathan Lynch <nathanl at austin.ibm.com>
>
>
> ---
>
>
> diff -puN arch/ppc64/kernel/setup.c~ppc64-rework-cpumap-setup arch/ppc64/kernel/setup.c
> --- 2.6.9-rc1-bk2/arch/ppc64/kernel/setup.c~ppc64-rework-cpumap-setup 2004-08-26 15:45:45.000000000 -0500
> +++ 2.6.9-rc1-bk2-nathanl/arch/ppc64/kernel/setup.c 2004-08-26 21:52:43.000000000 -0500
> @@ -155,6 +155,94 @@ void __init disable_early_printk(void)
> early_console_initialized = 0;
> }
>
> +#if !defined(CONFIG_PPC_ISERIES) && defined(CONFIG_SMP)
> +/**
> + * setup_cpu_maps - initialize the following cpu maps:
> + * cpu_possible_map
> + * cpu_present_map
> + * cpu_sibling_map
> + *
> + * Having the possible map set up early allows us to restrict allocations
> + * of things like irqstacks to num_possible_cpus() rather than NR_CPUS.
> + *
> + * We do not initialize the online map here; cpus set their own bits in
> + * cpu_online_map as they come up.
> + *
> + * This function is valid only for Open Firmware systems. finish_device_tree
> + * must be called before using this.
> + */
> +static void __init setup_cpu_maps(void)
> +{
> + struct device_node *dn = NULL;
> + int cpu = 0;
> +
> + while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
> + u32 *intserv;
> + int j, len = sizeof(u32), nthreads;
> +
> + intserv = (u32 *)get_property(dn, "ibm,ppc-interrupt-server#s",
> + &len);
> + nthreads = len / sizeof(u32);
> +
> + for (j = 0; j < nthreads && cpu < NR_CPUS; j++) {
> + cpu_set(cpu, cpu_possible_map);
> + cpu_set(cpu, cpu_present_map);
> + cpu++;
> + }
> + }
> +
> + /*
> + * On pSeries LPAR, we need to know how many cpus
> + * could possibly be added to this partition.
> + */
> + if (systemcfg->platform == PLATFORM_PSERIES_LPAR &&
> + (dn = of_find_node_by_path("/rtas"))) {
> + int num_addr_cell, num_size_cell, maxcpus;
> + unsigned int *ireg;
> +
> + num_addr_cell = prom_n_addr_cells(dn);
> + num_size_cell = prom_n_size_cells(dn);
> +
> + ireg = (unsigned int *)
> + get_property(dn, "ibm,lrdr-capacity", NULL);
> +
> + if (!ireg)
> + goto out;
> +
> + maxcpus = ireg[num_addr_cell + num_size_cell];
> +
> + /* Double maxcpus for processors which have SMT capability */
> + if (cur_cpu_spec->cpu_features & CPU_FTR_SMT)
> + maxcpus *= 2;
> +
> + if (maxcpus > NR_CPUS) {
> + printk(KERN_WARNING
> + "Partition configured for %d cpus, "
> + "operating system maximum is %d.\n",
> + maxcpus, NR_CPUS);
> + maxcpus = NR_CPUS;
> + } else
> + printk(KERN_INFO "Partition configured for %d cpus.\n",
> + maxcpus);
> +
> + for (cpu = 0; cpu < maxcpus; cpu++)
> + cpu_set(cpu, cpu_possible_map);
> + out:
> + of_node_put(dn);
> + }
> +
> + /*
> + * Do the sibling map; assume only two threads per processor.
> + */
> + for_each_cpu(cpu) {
> + cpu_set(cpu, cpu_sibling_map[cpu]);
> + if (cur_cpu_spec->cpu_features & CPU_FTR_SMT)
> + cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]);
> + }
> +
> + systemcfg->processorCount = num_present_cpus();
> +}
> +#endif /* !defined(CONFIG_PPC_ISERIES) && defined(CONFIG_SMP) */
> /*
> * Do some initial setup of the system. The parameters are those which
> * were passed in from the bootloader.
> @@ -220,6 +308,13 @@ void setup_system(unsigned long r3, unsi
> }
> #endif /* CONFIG_BOOTX_TEXT */
>
> +#ifdef CONFIG_PPC_PMAC
> + if (systemcfg->platform == PLATFORM_POWERMAC) {
> + finish_device_tree();
> + pmac_init(r3, r4, r5, r6, r7);
> + }
> +#endif /* CONFIG_PPC_PMAC */
> +
> #ifdef CONFIG_PPC_PSERIES
> if (systemcfg->platform & PLATFORM_PSERIES) {
> early_console_initialized = 1;
> @@ -227,31 +322,32 @@ void setup_system(unsigned long r3, unsi
> __irq_offset_value = NUM_ISA_INTERRUPTS;
> finish_device_tree();
> chrp_init(r3, r4, r5, r6, r7);
> + }
> +#endif /* CONFIG_PPC_PSERIES */
>
> #ifdef CONFIG_SMP
> - /* Start secondary threads on SMT systems; primary threads
> - * are already in the running state.
> - */
> - for_each_present_cpu(i) {
> - if (query_cpu_stopped
> - (get_hard_smp_processor_id(i)) == 0) {
> - printk("%16.16x : starting thread\n", i);
> - rtas_call(rtas_token("start-cpu"), 3, 1, &ret,
> - get_hard_smp_processor_id(i),
> - (u32)*((unsigned long *)pseries_secondary_smp_init),
> - i);
> - }
> +#ifndef CONFIG_PPC_ISERIES
> + /*
> + * iSeries has already initialized the cpu maps at this point.
> + */
> + setup_cpu_maps();
> +#endif /* CONFIG_PPC_ISERIES */
> +
> +#ifdef CONFIG_PPC_PSERIES
> + /* Start secondary threads on SMT systems; primary threads
> + * are already in the running state.
> + */
> + for_each_present_cpu(i) {
> + if (query_cpu_stopped(get_hard_smp_processor_id(i)) == 0) {
> + printk("%16.16x : starting thread\n", i);
> + rtas_call(rtas_token("start-cpu"), 3, 1, &ret,
> + get_hard_smp_processor_id(i),
> + (u32)*((unsigned long *)pseries_secondary_smp_init),
> + i);
> }
> -#endif /* CONFIG_SMP */
> }
> #endif /* CONFIG_PPC_PSERIES */
> -
> -#ifdef CONFIG_PPC_PMAC
> - if (systemcfg->platform == PLATFORM_POWERMAC) {
> - finish_device_tree();
> - pmac_init(r3, r4, r5, r6, r7);
> - }
> -#endif /* CONFIG_PPC_PMAC */
> +#endif /* CONFIG_SMP */
>
> #if defined(CONFIG_HOTPLUG_CPU) && !defined(CONFIG_PPC_PMAC)
> rtas_stop_self_args.token = rtas_token("stop-self");
> diff -puN arch/ppc64/kernel/prom.c~ppc64-rework-cpumap-setup arch/ppc64/kernel/prom.c
> --- 2.6.9-rc1-bk2/arch/ppc64/kernel/prom.c~ppc64-rework-cpumap-setup 2004-08-26 15:45:57.000000000 -0500
> +++ 2.6.9-rc1-bk2-nathanl/arch/ppc64/kernel/prom.c 2004-08-26 21:51:56.000000000 -0500
> @@ -939,20 +939,11 @@ static void __init prom_hold_cpus(unsign
> prom_getprop(node, "reg", ®, sizeof(reg));
> lpaca[cpuid].hw_cpu_id = reg;
>
> -#ifdef CONFIG_SMP
> - cpu_set(cpuid, RELOC(cpu_possible_map));
> - cpu_set(cpuid, RELOC(cpu_present_map));
> - if (reg == 0)
> - cpu_set(cpuid, RELOC(cpu_online_map));
> -#endif /* CONFIG_SMP */
> cpuid++;
> }
> return;
> }
>
> - /* Initially, we must have one active CPU. */
> - _systemcfg->processorCount = 1;
> -
> prom_debug("prom_hold_cpus: start...\n");
> prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop);
> prom_debug(" 1) *spinloop = 0x%x\n", *spinloop);
> @@ -1038,23 +1029,13 @@ static void __init prom_hold_cpus(unsign
> * even if we never start it. */
> if (cpuid >= NR_CPUS)
> goto next;
> -#ifdef CONFIG_SMP
> - /* Set the number of active processors. */
> - _systemcfg->processorCount++;
> - cpu_set(cpuid, RELOC(cpu_possible_map));
> - cpu_set(cpuid, RELOC(cpu_present_map));
> -#endif
> } else {
> prom_printf("... failed: %x\n", *acknowledge);
> }
> }
> #ifdef CONFIG_SMP
> - else {
> + else
> prom_printf("%x : booting cpu %s\n", cpuid, path);
> - cpu_set(cpuid, RELOC(cpu_possible_map));
> - cpu_set(cpuid, RELOC(cpu_online_map));
> - cpu_set(cpuid, RELOC(cpu_present_map));
> - }
> #endif
> next:
> #ifdef CONFIG_SMP
> @@ -1067,9 +1048,6 @@ next:
> prom_printf("%x : preparing thread ... ",
> interrupt_server[i]);
> if (_naca->smt_state) {
> - cpu_set(cpuid, RELOC(cpu_present_map));
> - cpu_set(cpuid, RELOC(cpu_possible_map));
> - _systemcfg->processorCount++;
> prom_printf("available\n");
> } else {
> prom_printf("not available\n");
> @@ -1099,11 +1077,7 @@ next:
> pir & 0x3ff;
> }
> }
> -/* cpu_set(i+1, cpu_online_map); */
> - cpu_set(i+1, RELOC(cpu_possible_map));
> - cpu_set(i+1, RELOC(cpu_present_map));
> }
> - _systemcfg->processorCount *= 2;
> } else {
> prom_printf("Processor is not HMT capable\n");
> }
> diff -puN arch/ppc64/kernel/smp.c~ppc64-rework-cpumap-setup arch/ppc64/kernel/smp.c
> --- 2.6.9-rc1-bk2/arch/ppc64/kernel/smp.c~ppc64-rework-cpumap-setup 2004-08-26 17:21:29.000000000 -0500
> +++ 2.6.9-rc1-bk2-nathanl/arch/ppc64/kernel/smp.c 2004-08-26 17:48:56.000000000 -0500
> @@ -401,56 +401,11 @@ static inline int __devinit smp_startup_
> }
> return 1;
> }
> -
> -static inline void look_for_more_cpus(void)
> -{
> - int num_addr_cell, num_size_cell, len, i, maxcpus;
> - struct device_node *np;
> - unsigned int *ireg;
> -
> - /* Find the property which will tell us about how many CPUs
> - * we're allowed to have. */
> - if ((np = find_path_device("/rtas")) == NULL) {
> - printk(KERN_ERR "Could not find /rtas in device tree!");
> - return;
> - }
> - num_addr_cell = prom_n_addr_cells(np);
> - num_size_cell = prom_n_size_cells(np);
> -
> - ireg = (unsigned int *)get_property(np, "ibm,lrdr-capacity", &len);
> - if (ireg == NULL) {
> - /* FIXME: make sure not marked as lrdr_capable() */
> - return;
> - }
> -
> - maxcpus = ireg[num_addr_cell + num_size_cell];
> -
> - /* Double maxcpus for processors which have SMT capability */
> - if (cur_cpu_spec->cpu_features & CPU_FTR_SMT)
> - maxcpus *= 2;
> -
> -
> - if (maxcpus > NR_CPUS) {
> - printk(KERN_WARNING
> - "Partition configured for %d cpus, "
> - "operating system maximum is %d.\n", maxcpus, NR_CPUS);
> - maxcpus = NR_CPUS;
> - } else
> - printk(KERN_INFO "Partition configured for %d cpus.\n",
> - maxcpus);
> -
> - /* Make those cpus (which might appear later) possible too. */
> - for (i = 0; i < maxcpus; i++)
> - cpu_set(i, cpu_possible_map);
> -}
> #else /* ... CONFIG_HOTPLUG_CPU */
> static inline int __devinit smp_startup_cpu(unsigned int lcpu)
> {
> return 1;
> }
> -static inline void look_for_more_cpus(void)
> -{
> -}
> #endif /* CONFIG_HOTPLUG_CPU */
>
> static void smp_pSeries_kick_cpu(int nr)
> @@ -837,8 +792,6 @@ void __init smp_prepare_cpus(unsigned in
> */
> do_gtod.tb_orig_stamp = tb_last_stamp;
> systemcfg->tb_orig_stamp = tb_last_stamp;
> -
> - look_for_more_cpus();
> #endif
>
> max_cpus = smp_ops->probe();
> @@ -851,19 +804,12 @@ void __init smp_prepare_cpus(unsigned in
> for_each_cpu(cpu)
> if (cpu != boot_cpuid)
> smp_create_idle(cpu);
> -
> - for_each_cpu(cpu) {
> - cpu_set(cpu, cpu_sibling_map[cpu]);
> - if (cur_cpu_spec->cpu_features & CPU_FTR_SMT)
> - cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]);
> - }
> }
>
> void __devinit smp_prepare_boot_cpu(void)
> {
> BUG_ON(smp_processor_id() != boot_cpuid);
>
> - /* cpu_possible is set up in prom.c */
> cpu_set(boot_cpuid, cpu_online_map);
>
> paca[boot_cpuid].__current = current;
>
> _
>
>
>
>
** Sent via the linuxppc64-dev mail list. See http://lists.linuxppc.org/
More information about the Linuxppc64-dev
mailing list