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