Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 204703
b: refs/heads/master
c: 41eab6f
h: refs/heads/master
i:
  204701: b919d76
  204699: 40816e2
  204695: 72d96d3
  204687: 150712a
  204671: 179fa34
v: v3
  • Loading branch information
Anton Blanchard authored and Benjamin Herrenschmidt committed Jul 9, 2010
1 parent 2463f18 commit d446ef1
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 34 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a591f6b56d6fbd7d1951e352fe5b0acf6b91e497
refs/heads/master: 41eab6f88f24124df89e38067b3766b7bef06ddb
3 changes: 3 additions & 0 deletions trunk/arch/powerpc/include/asm/topology.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ static inline int pcibus_to_node(struct pci_bus *bus)
.balance_interval = 1, \
}

extern int __node_distance(int, int);
#define node_distance(a, b) __node_distance(a, b)

extern void __init dump_numa_cpu_topology(void);

extern int sysfs_add_device_to_node(struct sys_device *dev, int nid);
Expand Down
122 changes: 89 additions & 33 deletions trunk/arch/powerpc/mm/numa.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ EXPORT_SYMBOL(node_data);

static int min_common_depth;
static int n_mem_addr_cells, n_mem_size_cells;
static int form1_affinity;

#define MAX_DISTANCE_REF_POINTS 4
static int distance_ref_points_depth;
static const unsigned int *distance_ref_points;
static int distance_lookup_table[MAX_NUMNODES][MAX_DISTANCE_REF_POINTS];

/*
* Allocate node_to_cpumask_map based on number of available nodes
Expand Down Expand Up @@ -204,6 +210,39 @@ static const u32 *of_get_usable_memory(struct device_node *memory)
return prop;
}

int __node_distance(int a, int b)
{
int i;
int distance = LOCAL_DISTANCE;

if (!form1_affinity)
return distance;

for (i = 0; i < distance_ref_points_depth; i++) {
if (distance_lookup_table[a][i] == distance_lookup_table[b][i])
break;

/* Double the distance for each NUMA level */
distance *= 2;
}

return distance;
}

static void initialize_distance_lookup_table(int nid,
const unsigned int *associativity)
{
int i;

if (!form1_affinity)
return;

for (i = 0; i < distance_ref_points_depth; i++) {
distance_lookup_table[nid][i] =
associativity[distance_ref_points[i]];
}
}

/* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa
* info is found.
*/
Expand All @@ -225,6 +264,10 @@ static int of_node_to_nid_single(struct device_node *device)
/* POWER4 LPAR uses 0xffff as invalid node */
if (nid == 0xffff || nid >= MAX_NUMNODES)
nid = -1;

if (nid > 0 && tmp[0] >= distance_ref_points_depth)
initialize_distance_lookup_table(nid, tmp);

out:
return nid;
}
Expand All @@ -251,26 +294,10 @@ int of_node_to_nid(struct device_node *device)
}
EXPORT_SYMBOL_GPL(of_node_to_nid);

/*
* In theory, the "ibm,associativity" property may contain multiple
* associativity lists because a resource may be multiply connected
* into the machine. This resource then has different associativity
* characteristics relative to its multiple connections. We ignore
* this for now. We also assume that all cpu and memory sets have
* their distances represented at a common level. This won't be
* true for hierarchical NUMA.
*
* In any case the ibm,associativity-reference-points should give
* the correct depth for a normal NUMA system.
*
* - Dave Hansen <haveblue@us.ibm.com>
*/
static int __init find_min_common_depth(void)
{
int depth, index;
const unsigned int *ref_points;
int depth;
struct device_node *rtas_root;
unsigned int len;
struct device_node *chosen;
const char *vec5;

Expand All @@ -280,38 +307,67 @@ static int __init find_min_common_depth(void)
return -1;

/*
* this property is 2 32-bit integers, each representing a level of
* depth in the associativity nodes. The first is for an SMP
* configuration (should be all 0's) and the second is for a normal
* NUMA configuration.
* This property is a set of 32-bit integers, each representing
* an index into the ibm,associativity nodes.
*
* With form 0 affinity the first integer is for an SMP configuration
* (should be all 0's) and the second is for a normal NUMA
* configuration. We have only one level of NUMA.
*
* With form 1 affinity the first integer is the most significant
* NUMA boundary and the following are progressively less significant
* boundaries. There can be more than one level of NUMA.
*/
index = 1;
ref_points = of_get_property(rtas_root,
"ibm,associativity-reference-points", &len);
distance_ref_points = of_get_property(rtas_root,
"ibm,associativity-reference-points",
&distance_ref_points_depth);

if (!distance_ref_points) {
dbg("NUMA: ibm,associativity-reference-points not found.\n");
goto err;
}

distance_ref_points_depth /= sizeof(int);

/*
* For form 1 affinity information we want the first field
*/
#define VEC5_AFFINITY_BYTE 5
#define VEC5_AFFINITY 0x80
chosen = of_find_node_by_path("/chosen");
if (chosen) {
vec5 = of_get_property(chosen, "ibm,architecture-vec-5", NULL);
if (vec5 && (vec5[VEC5_AFFINITY_BYTE] & VEC5_AFFINITY)) {
dbg("Using form 1 affinity\n");
index = 0;
form1_affinity = 1;
}
}

if ((len >= 2 * sizeof(unsigned int)) && ref_points) {
depth = ref_points[index];
if (form1_affinity) {
depth = distance_ref_points[0];
} else {
dbg("NUMA: ibm,associativity-reference-points not found.\n");
depth = -1;
if (distance_ref_points_depth < 2) {
printk(KERN_WARNING "NUMA: "
"short ibm,associativity-reference-points\n");
goto err;
}

depth = distance_ref_points[1];
}
of_node_put(rtas_root);

/*
* Warn and cap if the hardware supports more than
* MAX_DISTANCE_REF_POINTS domains.
*/
if (distance_ref_points_depth > MAX_DISTANCE_REF_POINTS) {
printk(KERN_WARNING "NUMA: distance array capped at "
"%d entries\n", MAX_DISTANCE_REF_POINTS);
distance_ref_points_depth = MAX_DISTANCE_REF_POINTS;
}

of_node_put(rtas_root);
return depth;

err:
of_node_put(rtas_root);
return -1;
}

static void __init get_n_mem_cells(int *n_addr_cells, int *n_size_cells)
Expand Down

0 comments on commit d446ef1

Please sign in to comment.