[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 1/3] 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 array for fast lookups. Signed-off-by: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx> --- Changes in v3: * Renamed p2n to pxm2node (and struct pxm2node to struct pxm_to_node) * Changed node type in pxm_to_node to u8 * pxm_to_node(), setup_node() and node_to_pxm()) use unsigned as node argument * Reinitialized pxm2node in abd_srat(); * Added BUILD_BUG_ON(MAX_NUMNODES >= NUMA_NO_NODE); * Made changes to K&R style (which is what this file uses) xen/arch/x86/srat.c | 96 ++++++++++++++++++++++++++++++++------------ xen/include/asm-x86/numa.h | 4 +- 2 files changed, 72 insertions(+), 28 deletions(-) diff --git a/xen/arch/x86/srat.c b/xen/arch/x86/srat.c index 29fc724..1664393 100644 --- a/xen/arch/x86/srat.c +++ b/xen/arch/x86/srat.c @@ -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 pxm_to_node { + unsigned pxm; + u8 node; +}; +static struct pxm_to_node __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 inline bool_t node_found(unsigned idx, unsigned pxm) +{ + return ((pxm2node[idx].pxm == pxm) && + (pxm2node[idx].node != NUMA_NO_NODE)); +} -static int node_to_pxm(int n); - -int pxm_to_node(int pxm) +int pxm_to_node(unsigned pxm) { - if ((unsigned)pxm >= 256) - return -1; + unsigned i; + + if ((pxm < MAX_NUMNODES) && node_found(pxm, pxm)) + return pxm2node[pxm].node; + + for (i = 0; i < MAX_NUMNODES; i++) + if (node_found(i, pxm)) + return pxm2node[i].node; + /* Extend 0xff to (int)-1 */ - return (signed char)pxm2node[pxm]; + return (signed char)NUMA_NO_NODE; } -__devinit int setup_node(int pxm) +__devinit int setup_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; + int node; + unsigned idx; + static bool_t warned; + + BUILD_BUG_ON(MAX_NUMNODES >= NUMA_NO_NODE); + + if (pxm < MAX_NUMNODES) { + 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; + } + } + + for (idx = 0; idx < MAX_NUMNODES; idx++) + if (pxm2node[idx].node == NUMA_NO_NODE) + goto finish; + + if (!warned) { + printk(XENLOG_WARNING "More PXMs than available nodes\n"); + warned = 1; } - return pxm2node[pxm]; + + 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) @@ -111,8 +154,8 @@ static __init void bad_srat(void) acpi_numa = -1; 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; + for (i = 0; i < MAX_NUMNODES; i++) + 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 < MAX_NUMNODES) && (pxm2node[n].node == n)) + return pxm2node[n].pxm; + for (i = 0; i < MAX_NUMNODES; i++) + if (pxm2node[i].node == n) + return pxm2node[i].pxm; + return 0; } int __node_distance(int a, int b) diff --git a/xen/include/asm-x86/numa.h b/xen/include/asm-x86/numa.h index 5959860..e491a9e 100644 --- a/xen/include/asm-x86/numa.h +++ b/xen/include/asm-x86/numa.h @@ -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 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 pxm); extern void srat_detect_node(int cpu); extern void setup_node_bootmem(int nodeid, u64 start, u64 end); -- 1.7.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |