[patch 1/3] rework ppc64 cpu map setup

Nathan Lynch nathanl at austin.ibm.com
Fri Aug 27 13:16:48 EST 2004


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