mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
x86/numa: allow arbitrary value of PXM in PXM<->node mapping
ACPI defines proximity domain identifier as a 32-bit integer. While in most cases the values will be zero-based this is not guaranteed, making current pxm2node[256] mapping structure not appropriate. We will instead use MAX_NUMNODES-sized array of struct pxm2node to store PXM-to-node mapping. To accommodate common case of zero-based and contiguios PXMs we will, whenever possible, try to use PXM as index into this array for fast lookups. Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> Use ARRAY_SIZE(pxm2node) instead of MAX_NUMNODES in bounds checks. Rename struct pxm_to_node to struct pxm2node (the structure tag aliasing with the array defined using it is better than it aliasing with a function name). Signed-off-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
ccb50193a7
commit
ebeefe181c
2 files changed
+73
-29
No files matched your search
+71
-27
@@ -27,35 +27,78 @@ static nodemask_t memory_nodes_parsed __initdata;
|
||||
static nodemask_t processor_nodes_parsed __initdata;
|
||||
static nodemask_t nodes_found __initdata;
|
||||
static struct node nodes[MAX_NUMNODES] __initdata;
|
||||
static u8 __read_mostly pxm2node[256] = { [0 ... 255] = NUMA_NO_NODE };
|
||||
|
||||
struct pxm2node {
|
||||
unsigned pxm;
|
||||
u8 node;
|
||||
};
|
||||
static struct pxm2node __read_mostly pxm2node[MAX_NUMNODES] =
|
||||
{ [0 ... MAX_NUMNODES - 1] = {.node = NUMA_NO_NODE} };
|
||||
|
||||
static int node_to_pxm(unsigned n);
|
||||
|
||||
static int num_node_memblks;
|
||||
static struct node node_memblk_range[NR_NODE_MEMBLKS];
|
||||
static int memblk_nodeid[NR_NODE_MEMBLKS];
|
||||
|
||||
|
||||
static int node_to_pxm(int n);
|
||||
|
||||
int pxm_to_node(int pxm)
|
||||
static inline bool_t node_found(unsigned idx, unsigned pxm)
|
||||
{
|
||||
if ((unsigned)pxm >= 256)
|
||||
return -1;
|
||||
/* Extend 0xff to (int)-1 */
|
||||
return (signed char)pxm2node[pxm];
|
||||
return ((pxm2node[idx].pxm == pxm) &&
|
||||
(pxm2node[idx].node != NUMA_NO_NODE));
|
||||
}
|
||||
|
||||
__devinit int setup_node(int pxm)
|
||||
int pxm_to_node(unsigned pxm)
|
||||
{
|
||||
unsigned node = pxm2node[pxm];
|
||||
if (node == 0xff) {
|
||||
if (nodes_weight(nodes_found) >= MAX_NUMNODES)
|
||||
return -1;
|
||||
node = first_unset_node(nodes_found);
|
||||
node_set(node, nodes_found);
|
||||
pxm2node[pxm] = node;
|
||||
unsigned i;
|
||||
|
||||
if ((pxm < ARRAY_SIZE(pxm2node)) && node_found(pxm, pxm))
|
||||
return pxm2node[pxm].node;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(pxm2node); i++)
|
||||
if (node_found(i, pxm))
|
||||
return pxm2node[i].node;
|
||||
|
||||
/* Extend 0xff to (int)-1 */
|
||||
return (signed char)NUMA_NO_NODE;
|
||||
}
|
||||
|
||||
__devinit int setup_node(unsigned pxm)
|
||||
{
|
||||
int node;
|
||||
unsigned idx;
|
||||
static bool_t warned;
|
||||
|
||||
BUILD_BUG_ON(MAX_NUMNODES >= NUMA_NO_NODE);
|
||||
|
||||
if (pxm < ARRAY_SIZE(pxm2node)) {
|
||||
if (node_found(pxm, pxm))
|
||||
return pxm2node[pxm].node;
|
||||
|
||||
/* Try to maintain indexing of pxm2node by pxm */
|
||||
if (pxm2node[pxm].node == NUMA_NO_NODE) {
|
||||
idx = pxm;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
return pxm2node[pxm];
|
||||
|
||||
for (idx = 0; idx < ARRAY_SIZE(pxm2node); idx++)
|
||||
if (pxm2node[idx].node == NUMA_NO_NODE)
|
||||
goto finish;
|
||||
|
||||
if (!warned) {
|
||||
printk(XENLOG_WARNING "More PXMs than available nodes\n");
|
||||
warned = 1;
|
||||
}
|
||||
|
||||
return (signed char)NUMA_NO_NODE;
|
||||
|
||||
finish:
|
||||
node = first_unset_node(nodes_found);
|
||||
node_set(node, nodes_found);
|
||||
pxm2node[idx].pxm = pxm;
|
||||
pxm2node[idx].node = node;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
int valid_numa_range(u64 start, u64 end, int node)
|
||||
@@ -112,7 +155,7 @@ static __init void bad_srat(void)
|
||||
for (i = 0; i < MAX_LOCAL_APIC; i++)
|
||||
apicid_to_node[i] = NUMA_NO_NODE;
|
||||
for (i = 0; i < ARRAY_SIZE(pxm2node); i++)
|
||||
pxm2node[i] = NUMA_NO_NODE;
|
||||
pxm2node[i].node = NUMA_NO_NODE;
|
||||
mem_hotplug = 0;
|
||||
}
|
||||
|
||||
@@ -438,15 +481,16 @@ int __init acpi_scan_nodes(u64 start, u64 end)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int node_to_pxm(int n)
|
||||
static int node_to_pxm(unsigned n)
|
||||
{
|
||||
int i;
|
||||
if (pxm2node[n] == n)
|
||||
return n;
|
||||
for (i = 0; i < 256; i++)
|
||||
if (pxm2node[i] == n)
|
||||
return i;
|
||||
return 0;
|
||||
unsigned i;
|
||||
|
||||
if ((n < ARRAY_SIZE(pxm2node)) && (pxm2node[n].node == n))
|
||||
return pxm2node[n].pxm;
|
||||
for (i = 0; i < ARRAY_SIZE(pxm2node); i++)
|
||||
if (pxm2node[i].node == n)
|
||||
return pxm2node[i].pxm;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __node_distance(int a, int b)
|
||||
|
||||
@@ -21,7 +21,7 @@ struct node {
|
||||
|
||||
extern int compute_hash_shift(struct node *nodes, int numnodes,
|
||||
int *nodeids);
|
||||
extern int pxm_to_node(int nid);
|
||||
extern int pxm_to_node(unsigned int pxm);
|
||||
|
||||
#define ZONE_ALIGN (1UL << (MAX_ORDER+PAGE_SHIFT))
|
||||
#define VIRTUAL_BUG_ON(x)
|
||||
@@ -33,7 +33,7 @@ extern int numa_off;
|
||||
|
||||
extern int srat_disabled(void);
|
||||
extern void numa_set_node(int cpu, int node);
|
||||
extern int setup_node(int pxm);
|
||||
extern int setup_node(unsigned int pxm);
|
||||
extern void srat_detect_node(int cpu);
|
||||
|
||||
extern void setup_node_bootmem(int nodeid, u64 start, u64 end);
|
||||
|
||||