svn commit: r327566 - head/sys/powerpc/pseries

Nathan Whitehorn nwhitehorn at FreeBSD.org
Thu Jan 4 23:07:52 UTC 2018


Author: nwhitehorn
Date: Thu Jan  4 23:07:51 2018
New Revision: 327566
URL: https://svnweb.freebsd.org/changeset/base/327566

Log:
  Revert r327360, which can cause boot problems on high-CPU-count (>60)
  POWER8 and POWER9 systems, pending further analysis.
  
  PR:		224841

Modified:
  head/sys/powerpc/pseries/platform_chrp.c

Modified: head/sys/powerpc/pseries/platform_chrp.c
==============================================================================
--- head/sys/powerpc/pseries/platform_chrp.c	Thu Jan  4 22:59:24 2018	(r327565)
+++ head/sys/powerpc/pseries/platform_chrp.c	Thu Jan  4 23:07:51 2018	(r327566)
@@ -114,8 +114,6 @@ static platform_def_t chrp_platform = {
 
 PLATFORM_DEF(chrp_platform);
 
-#define BSP_MUST_BE_CPU_ZERO
-
 static int
 chrp_probe(platform_t plat)
 {
@@ -281,31 +279,13 @@ chrp_real_maxaddr(platform_t plat)
 static u_long
 chrp_timebase_freq(platform_t plat, struct cpuref *cpuref)
 {
-	char buf[8];
-	phandle_t cpu, dev, root;
-	int res;
+	phandle_t phandle;
 	int32_t ticks = -1;
 
-	root = OF_peer(0);
+	phandle = cpuref->cr_hwref;
 
-	dev = OF_child(root);
-	while (dev != 0) {
-		res = OF_getprop(dev, "name", buf, sizeof(buf));
-		if (res > 0 && strcmp(buf, "cpus") == 0)
-			break;
-		dev = OF_peer(dev);
-	}
+	OF_getencprop(phandle, "timebase-frequency", &ticks, sizeof(ticks));
 
-	for (cpu = OF_child(dev); cpu != 0; cpu = OF_peer(cpu)) {
-		res = OF_getprop(cpu, "device_type", buf, sizeof(buf));
-		if (res > 0 && strcmp(buf, "cpu") == 0)
-			break;
-	}
-	if (cpu == 0)
-		return (512000000);
-
-	OF_getencprop(cpu, "timebase-frequency", &ticks, sizeof(ticks));
-
 	if (ticks <= 0)
 		panic("Unable to determine timebase frequency!");
 
@@ -313,11 +293,11 @@ chrp_timebase_freq(platform_t plat, struct cpuref *cpu
 }
 
 static int
-chrp_cpuref_for_server(struct cpuref *cpuref, int cpu_n, int server)
+chrp_smp_first_cpu(platform_t plat, struct cpuref *cpuref)
 {
 	char buf[8];
 	phandle_t cpu, dev, root;
-	int res, cpuid, i, j;
+	int res, cpuid;
 
 	root = OF_peer(0);
 
@@ -338,84 +318,71 @@ chrp_cpuref_for_server(struct cpuref *cpuref, int cpu_
 			return (ENOENT);
 	}
 
-	i = 0;
-	for (cpu = OF_child(dev); cpu != 0; cpu = OF_peer(cpu)) {
-		res = OF_getprop(cpu, "device_type", buf, sizeof(buf));
-		if (res <= 0 || strcmp(buf, "cpu") != 0)
-			continue;
+	cpu = OF_child(dev);
 
-		res = OF_getproplen(cpu, "ibm,ppc-interrupt-server#s");
-		if (res > 0) {
-			cell_t interrupt_servers[res/sizeof(cell_t)];
-			OF_getencprop(cpu, "ibm,ppc-interrupt-server#s",
-			    interrupt_servers, res);
-			for (j = 0; j < res/sizeof(cell_t); j++) {
-				cpuid = interrupt_servers[j];
-				if (server != -1 && cpuid == server)
-					break;
-				if (cpu_n != -1 && cpu_n == i)
-					break;
-				i++;
-			}
-
-			if (j != res/sizeof(cell_t))
-				break;
-		} else {
-			res = OF_getencprop(cpu, "reg", &cpuid, sizeof(cpuid));
-			if (res <= 0)
-				cpuid = 0;
-			if (server != -1 && cpuid == server)
-				break;
-			if (cpu_n != -1 && cpu_n == i)
-				break;
-			i++;
-		}
+	while (cpu != 0) {
+		res = OF_getprop(cpu, "device_type", buf, sizeof(buf));
+		if (res > 0 && strcmp(buf, "cpu") == 0)
+			break;
+		cpu = OF_peer(cpu);
 	}
-
 	if (cpu == 0)
 		return (ENOENT);
 
-	cpuref->cr_hwref = cpuid;
-	cpuref->cr_cpuid = i;
+	cpuref->cr_hwref = cpu;
+	res = OF_getencprop(cpu, "ibm,ppc-interrupt-server#s", &cpuid,
+	    sizeof(cpuid));
+	if (res <= 0)
+		res = OF_getencprop(cpu, "reg", &cpuid, sizeof(cpuid));
+	if (res <= 0)
+		cpuid = 0;
+	cpuref->cr_cpuid = cpuid;
 
 	return (0);
 }
 
 static int
-chrp_smp_first_cpu(platform_t plat, struct cpuref *cpuref)
-{
-#ifdef BSP_MUST_BE_CPU_ZERO
-	return (chrp_smp_get_bsp(plat, cpuref));
-#else
-	return (chrp_cpuref_for_server(cpuref, 0, -1));
-#endif
-}
-
-static int
 chrp_smp_next_cpu(platform_t plat, struct cpuref *cpuref)
 {
-#ifdef BSP_MUST_BE_CPU_ZERO
-	int bsp, ncpus, err;
-	struct cpuref scratch;
+	char buf[8];
+	phandle_t cpu;
+	int i, res, cpuid;
 
-	chrp_smp_get_bsp(plat, &scratch);
-	chrp_cpuref_for_server(&scratch, -1, scratch.cr_hwref);
-	bsp = scratch.cr_cpuid;
+	/* Check for whether it should be the next thread */
+	res = OF_getproplen(cpuref->cr_hwref, "ibm,ppc-interrupt-server#s");
+	if (res > 0) {
+		cell_t interrupt_servers[res/sizeof(cell_t)];
+		OF_getencprop(cpuref->cr_hwref, "ibm,ppc-interrupt-server#s",
+		    interrupt_servers, res);
+		for (i = 0; i < res/sizeof(cell_t) - 1; i++) {
+			if (interrupt_servers[i] == cpuref->cr_cpuid) {
+				cpuref->cr_cpuid = interrupt_servers[i+1];
+				return (0);
+			}
+		}
+	}
 
-	for (ncpus = bsp; chrp_cpuref_for_server(&scratch, ncpus, -1) !=
-	    ENOENT; ncpus++) {}
-	if (cpuref->cr_cpuid + 1 == ncpus)
+	/* Next CPU core/package */
+	cpu = OF_peer(cpuref->cr_hwref);
+	while (cpu != 0) {
+		res = OF_getprop(cpu, "device_type", buf, sizeof(buf));
+		if (res > 0 && strcmp(buf, "cpu") == 0)
+			break;
+		cpu = OF_peer(cpu);
+	}
+	if (cpu == 0)
 		return (ENOENT);
-	err = chrp_cpuref_for_server(cpuref,
-	    (cpuref->cr_cpuid + bsp + 1) % ncpus, -1);
-	if (cpuref->cr_cpuid >= bsp)
-		cpuref->cr_cpuid -= bsp;
-	else
-		cpuref->cr_cpuid = ncpus - (bsp - cpuref->cr_cpuid);
-	return (err);
-#else
-	return (chrp_cpuref_for_server(cpuref, cpuref->cr_cpuid+1, -1));
-#endif
+
+	cpuref->cr_hwref = cpu;
+	res = OF_getencprop(cpu, "ibm,ppc-interrupt-server#s", &cpuid,
+	    sizeof(cpuid));
+	if (res <= 0)
+		res = OF_getencprop(cpu, "reg", &cpuid, sizeof(cpuid));
+	if (res <= 0)
+		cpuid = 0;
+	cpuref->cr_cpuid = cpuid;
+
+	return (0);
 }
 
 static int
@@ -436,17 +403,14 @@ chrp_smp_get_bsp(platform_t plat, struct cpuref *cpure
 	bsp = OF_instance_to_package(inst);
 
 	/* Pick the primary thread. Can it be any other? */
+	cpuref->cr_hwref = bsp;
 	res = OF_getencprop(bsp, "ibm,ppc-interrupt-server#s", &cpuid,
 	    sizeof(cpuid));
 	if (res <= 0)
 		res = OF_getencprop(bsp, "reg", &cpuid, sizeof(cpuid));
 	if (res <= 0)
 		cpuid = 0;
-
-	chrp_cpuref_for_server(cpuref, -1, cpuid);
-#ifdef BSP_MUST_BE_CPU_ZERO
 	cpuref->cr_cpuid = cpuid;
-#endif
 
 	return (0);
 }
@@ -474,7 +438,7 @@ chrp_smp_start_cpu(platform_t plat, struct pcpu *pc)
 	ap_pcpu = pc;
 	powerpc_sync();
 
-	result = rtas_call_method(start_cpu, 3, 1, pc->pc_hwref, EXC_RST, pc,
+	result = rtas_call_method(start_cpu, 3, 1, pc->pc_cpuid, EXC_RST, pc,
 	    &err);
 	if (result < 0 || err != 0) {
 		printf("RTAS error (%d/%d): unable to start AP %d\n",
@@ -492,62 +456,39 @@ chrp_smp_start_cpu(platform_t plat, struct pcpu *pc)
 static struct cpu_group *
 chrp_smp_topo(platform_t plat)
 {
-	char buf[8];
-	phandle_t cpu, dev, root;
-	int res, nthreads;
+	struct pcpu *pc, *last_pc;
+	int i, ncores, ncpus;
 
-	root = OF_peer(0);
-
-	dev = OF_child(root);
-	while (dev != 0) {
-		res = OF_getprop(dev, "name", buf, sizeof(buf));
-		if (res > 0 && strcmp(buf, "cpus") == 0)
-			break;
-		dev = OF_peer(dev);
-	}
-
-	nthreads = 1;
-	for (cpu = OF_child(dev); cpu != 0; cpu = OF_peer(cpu)) {
-		res = OF_getprop(cpu, "device_type", buf, sizeof(buf));
-		if (res <= 0 || strcmp(buf, "cpu") != 0)
+	ncores = ncpus = 0;
+	last_pc = NULL;
+	for (i = 0; i <= mp_maxid; i++) {
+		pc = pcpu_find(i);
+		if (pc == NULL)
 			continue;
-
-		res = OF_getproplen(cpu, "ibm,ppc-interrupt-server#s");
-
-		if (res >= 0)
-			nthreads = res / sizeof(cell_t);
-		else
-			nthreads = 1;
-		break;
+		if (last_pc == NULL || pc->pc_hwref != last_pc->pc_hwref)
+			ncores++;
+		last_pc = pc;
+		ncpus++;
 	}
 
-	if (mp_ncpus % nthreads != 0) {
+	if (ncpus % ncores != 0) {
 		printf("WARNING: Irregular SMP topology. Performance may be "
-		     "suboptimal (%d threads, %d on first core)\n",
-		     mp_ncpus, nthreads);
+		     "suboptimal (%d CPUS, %d cores)\n", ncpus, ncores);
 		return (smp_topo_none());
 	}
 
 	/* Don't do anything fancier for non-threaded SMP */
-	if (nthreads == 1)
+	if (ncpus == ncores)
 		return (smp_topo_none());
 
-	return (smp_topo_1level(CG_SHARE_L1, nthreads, CG_FLAG_SMT));
+	return (smp_topo_1level(CG_SHARE_L1, ncpus / ncores, CG_FLAG_SMT));
 }
 #endif
 
 static void
 chrp_reset(platform_t platform)
 {
-	cell_t token, status;
-
-	if (rtas_exists()) {
-		token = rtas_token_lookup("system-reboot");
-		if (token != -1)
-			rtas_call_method(token, 0, 1, &status);
-	} else {
-		OF_reboot();
-	}
+	OF_reboot();
 }
 
 #ifdef __powerpc64__


More information about the svn-src-all mailing list