svn commit: r356858 - in head/sys/powerpc: include ofw powernv powerpc
Justin Hibbits
jhibbits at FreeBSD.org
Sat Jan 18 01:26:55 UTC 2020
Author: jhibbits
Date: Sat Jan 18 01:26:54 2020
New Revision: 356858
URL: https://svnweb.freebsd.org/changeset/base/356858
Log:
powerpc: Fix the NUMA domain list on powernv
Summary:
Consolidate the NUMA associativity handling into a platform function.
Non-NUMA platforms will just fall back to the default (0). Currently
only implemented for powernv, which uses a lookup table to map the
device tree associativity into a system NUMA domain.
Fixes hangs on powernv after r356534, and corrects a fairly longstanding
bug in powernv's NUMA handling, which ended up using domains 1 and 2 for
devices and memory on power9, while CPUs were bound to domains 0 and 1.
Reviewed by: bdragon, luporl
Differential Revision: https://reviews.freebsd.org/D23220
Modified:
head/sys/powerpc/include/ofw_machdep.h
head/sys/powerpc/include/platform.h
head/sys/powerpc/ofw/ofw_machdep.c
head/sys/powerpc/ofw/ofw_pcibus.c
head/sys/powerpc/powernv/platform_powernv.c
head/sys/powerpc/powerpc/platform.c
head/sys/powerpc/powerpc/platform_if.m
Modified: head/sys/powerpc/include/ofw_machdep.h
==============================================================================
--- head/sys/powerpc/include/ofw_machdep.h Sat Jan 18 01:22:54 2020 (r356857)
+++ head/sys/powerpc/include/ofw_machdep.h Sat Jan 18 01:26:54 2020 (r356858)
@@ -37,6 +37,9 @@
#include <dev/ofw/openfirm.h>
#include <machine/platform.h>
+struct mem_region;
+struct numa_mem_region;
+
typedef uint32_t cell_t;
void OF_getetheraddr(device_t dev, u_char *addr);
Modified: head/sys/powerpc/include/platform.h
==============================================================================
--- head/sys/powerpc/include/platform.h Sat Jan 18 01:22:54 2020 (r356857)
+++ head/sys/powerpc/include/platform.h Sat Jan 18 01:26:54 2020 (r356858)
@@ -37,6 +37,7 @@
#ifndef _MACHINE_PLATFORM_H_
#define _MACHINE_PLATFORM_H_
+#include <machine/ofw_machdep.h>
#include <machine/smp.h>
#include <machine/pcpu.h>
@@ -66,6 +67,7 @@ int platform_smp_start_cpu(struct pcpu *);
void platform_smp_timebase_sync(u_long tb, int ap);
void platform_smp_ap_init(void);
void platform_smp_probe_threads(void);
+int platform_node_numa_domain(phandle_t);
const char *installed_platform(void);
void platform_probe_and_attach(void);
Modified: head/sys/powerpc/ofw/ofw_machdep.c
==============================================================================
--- head/sys/powerpc/ofw/ofw_machdep.c Sat Jan 18 01:22:54 2020 (r356857)
+++ head/sys/powerpc/ofw/ofw_machdep.c Sat Jan 18 01:26:54 2020 (r356858)
@@ -466,9 +466,8 @@ void
ofw_numa_mem_regions(struct numa_mem_region *memp, int *memsz)
{
phandle_t phandle;
- int res, count, msz;
+ int count, msz;
char name[31];
- cell_t associativity[5];
struct numa_mem_region *curmemp;
msz = 0;
@@ -486,13 +485,8 @@ ofw_numa_mem_regions(struct numa_mem_region *memp, int
if (count == 0)
continue;
curmemp = &memp[msz];
- res = OF_getproplen(phandle, "ibm,associativity");
- if (res <= 0)
- continue;
MPASS(count == 1);
- OF_getencprop(phandle, "ibm,associativity",
- associativity, res);
- curmemp->mr_domain = associativity[3];
+ curmemp->mr_domain = platform_node_numa_domain(phandle);
if (bootverbose)
printf("%s %#jx-%#jx domain(%ju)\n",
name, (uintmax_t)curmemp->mr_start,
Modified: head/sys/powerpc/ofw/ofw_pcibus.c
==============================================================================
--- head/sys/powerpc/ofw/ofw_pcibus.c Sat Jan 18 01:22:54 2020 (r356857)
+++ head/sys/powerpc/ofw/ofw_pcibus.c Sat Jan 18 01:26:54 2020 (r356858)
@@ -385,39 +385,13 @@ ofw_pcibus_get_devinfo(device_t bus, device_t dev)
return (&dinfo->opd_obdinfo);
}
-static int
-ofw_pcibus_parse_associativity(device_t dev, int *domain)
-{
- phandle_t node;
- cell_t associativity[5];
- int res;
-
- if ((node = ofw_bus_get_node(dev)) == -1) {
- if (bootverbose)
- device_printf(dev, "no ofw node found\n");
- return (ENXIO);
- }
- res = OF_getproplen(node, "ibm,associativity");
- if (res <= 0)
- return (ENXIO);
- OF_getencprop(node, "ibm,associativity",
- associativity, res);
-
- *domain = associativity[3];
- if (bootverbose)
- device_printf(dev, "domain(%d)\n", *domain);
- return (0);
-}
-
int
ofw_pcibus_get_cpus(device_t dev, device_t child, enum cpu_sets op, size_t setsize,
cpuset_t *cpuset)
{
int d, error;
- error = ofw_pcibus_parse_associativity(child, &d);
- if (error)
- return (bus_generic_get_cpus(dev, child, op, setsize, cpuset));
+ d = platform_node_numa_domain(ofw_bus_get_node(dev));
switch (op) {
case LOCAL_CPUS:
@@ -450,12 +424,7 @@ ofw_pcibus_get_cpus(device_t dev, device_t child, enum
int
ofw_pcibus_get_domain(device_t dev, device_t child, int *domain)
{
- int d, error;
+ *domain = platform_node_numa_domain(ofw_bus_get_node(child));
- error = ofw_pcibus_parse_associativity(child, &d);
- /* No ofw node; go up a level */
- if (error)
- return (bus_generic_get_domain(dev, child, domain));
- *domain = d;
return (0);
}
Modified: head/sys/powerpc/powernv/platform_powernv.c
==============================================================================
--- head/sys/powerpc/powernv/platform_powernv.c Sat Jan 18 01:22:54 2020 (r356857)
+++ head/sys/powerpc/powernv/platform_powernv.c Sat Jan 18 01:26:54 2020 (r356858)
@@ -79,6 +79,7 @@ static struct cpu_group *powernv_smp_topo(platform_t p
static void powernv_reset(platform_t);
static void powernv_cpu_idle(sbintime_t sbt);
static int powernv_cpuref_init(void);
+static int powernv_node_numa_domain(platform_t platform, phandle_t node);
static platform_method_t powernv_methods[] = {
PLATFORMMETHOD(platform_probe, powernv_probe),
@@ -96,6 +97,7 @@ static platform_method_t powernv_methods[] = {
PLATFORMMETHOD(platform_smp_probe_threads, powernv_smp_probe_threads),
PLATFORMMETHOD(platform_smp_topo, powernv_smp_topo),
#endif
+ PLATFORMMETHOD(platform_node_numa_domain, powernv_node_numa_domain),
PLATFORMMETHOD(platform_reset, powernv_reset),
@@ -111,6 +113,7 @@ static platform_def_t powernv_platform = {
static struct cpuref platform_cpuref[MAXCPU];
static int platform_cpuref_cnt;
static int platform_cpuref_valid;
+static int platform_associativity;
PLATFORM_DEF(powernv_platform);
@@ -131,8 +134,10 @@ powernv_attach(platform_t plat)
uint32_t nptlp, shift = 0, slb_encoding = 0;
int32_t lp_size, lp_encoding;
char buf[255];
+ pcell_t refpoints[3];
pcell_t prop;
phandle_t cpu;
+ phandle_t opal;
int res, len, idx;
register_t msr;
@@ -144,7 +149,14 @@ powernv_attach(platform_t plat)
#else
opal_call(OPAL_REINIT_CPUS, 1 /* Big endian */);
#endif
+ opal = OF_finddevice("/ibm,opal");
+ platform_associativity = 4; /* Skiboot default. */
+ if (OF_getencprop(opal, "ibm,associativity-reference-points", refpoints,
+ sizeof(refpoints)) > 0) {
+ platform_associativity = refpoints[0];
+ }
+
if (cpu_idle_hook == NULL)
cpu_idle_hook = powernv_cpu_idle;
@@ -328,7 +340,8 @@ powernv_cpuref_init(void)
for (a = 0; a < res/sizeof(cell_t); a++) {
tmp_cpuref[tmp_cpuref_cnt].cr_hwref = interrupt_servers[a];
tmp_cpuref[tmp_cpuref_cnt].cr_cpuid = tmp_cpuref_cnt;
- tmp_cpuref[tmp_cpuref_cnt].cr_domain = interrupt_servers[a] >> 11;
+ tmp_cpuref[tmp_cpuref_cnt].cr_domain =
+ powernv_node_numa_domain(NULL, cpu);
if (interrupt_servers[a] == (uint32_t)powernv_boot_pir)
bsp = tmp_cpuref_cnt;
@@ -493,6 +506,40 @@ powernv_smp_ap_init(platform_t platform)
static void
powernv_cpu_idle(sbintime_t sbt)
{
+}
+
+static int
+powernv_node_numa_domain(platform_t platform, phandle_t node)
+{
+ /* XXX: Is locking necessary in here? */
+ static int numa_domains[MAXMEMDOM];
+ static int numa_max_domain;
+ cell_t associativity[5];
+ int i, res;
+
+ res = OF_getproplen(node, "ibm,associativity");
+
+ /* If already at the root, use default domain. */
+ if (res == 0)
+ return (0);
+ else if (res < 0)
+ /* If this node doesn't have associativity, check its parent. */
+ return (powernv_node_numa_domain(platform, OF_parent(node)));
+
+ OF_getencprop(node, "ibm,associativity",
+ associativity, res);
+
+ for (i = 0; i < numa_max_domain; i++) {
+ if (numa_domains[i] == associativity[platform_associativity])
+ return (i);
+ }
+ if (i < MAXMEMDOM)
+ numa_domains[numa_max_domain++] =
+ associativity[platform_associativity];
+ else
+ i = 0;
+
+ return (i);
}
/* Set up the Nest MMU on POWER9 relatively early, but after pmap is setup. */
Modified: head/sys/powerpc/powerpc/platform.c
==============================================================================
--- head/sys/powerpc/powerpc/platform.c Sat Jan 18 01:22:54 2020 (r356857)
+++ head/sys/powerpc/powerpc/platform.c Sat Jan 18 01:26:54 2020 (r356858)
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
#include <machine/cpu.h>
#include <machine/md_var.h>
+#include <machine/ofw_machdep.h>
#include <machine/platform.h>
#include <machine/platformvar.h>
#include <machine/smp.h>
@@ -309,6 +310,12 @@ cpu_topo(void)
return (PLATFORM_SMP_TOPO(plat_obj));
}
#endif
+
+int
+platform_node_numa_domain(phandle_t node)
+{
+ return (PLATFORM_NODE_NUMA_DOMAIN(plat_obj, node));
+}
/*
* Reset back to firmware.
Modified: head/sys/powerpc/powerpc/platform_if.m
==============================================================================
--- head/sys/powerpc/powerpc/platform_if.m Sat Jan 18 01:22:54 2020 (r356857)
+++ head/sys/powerpc/powerpc/platform_if.m Sat Jan 18 01:26:54 2020 (r356858)
@@ -32,6 +32,7 @@
#include <sys/systm.h>
#include <sys/smp.h>
+#include <machine/ofw_machdep.h>
#include <machine/platform.h>
#include <machine/platformvar.h>
#include <machine/smp.h>
@@ -88,6 +89,11 @@ CODE {
{
return;
}
+ static int platform_null_node_numa_domain(platform_t plat,
+ phandle_t node)
+ {
+ return (0);
+ }
};
/**
@@ -255,3 +261,12 @@ METHOD void smp_timebase_sync {
int _ap;
};
+/**
+ * @brief Return the NUMA domain for the given device tree node. Always returns
+ * a valid domain.
+ *
+ */
+METHOD int node_numa_domain {
+ platform_t _plat;
+ phandle_t _node;
+} DEFAULT platform_null_node_numa_domain;
More information about the svn-src-all
mailing list