[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", &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