[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 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> --- xen/arch/x86/srat.c | 93 +++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 68 insertions(+), 25 deletions(-) diff --git a/xen/arch/x86/srat.c b/xen/arch/x86/srat.c index 29fc724..c8841b9 100644 --- a/xen/arch/x86/srat.c +++ b/xen/arch/x86/srat.c @@ -27,35 +27,79 @@ 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; + int node; +}; +static struct pxm2node __read_mostly p2n[MAX_NUMNODES] = + { [0 ... MAX_NUMNODES - 1] = {.node = NUMA_NO_NODE} }; + +static int node_to_pxm(int 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); +static inline bool_t node_found(unsigned idx, unsigned pxm) +{ + return ((p2n[idx].pxm == pxm) && + (p2n[idx].node != NUMA_NO_NODE)); +} int pxm_to_node(int pxm) { - if ((unsigned)pxm >= 256) - return -1; - /* Extend 0xff to (int)-1 */ - return (signed char)pxm2node[pxm]; + unsigned i; + + if ( (pxm < MAX_NUMNODES) && node_found(pxm, pxm) ) + return p2n[pxm].node; + + for ( i = 0; i < MAX_NUMNODES; i++ ) + if ( node_found(i, pxm) ) + return p2n[i].node; + + /* Extend 0xff to (int)-1 */ + return (signed char)NUMA_NO_NODE; } __devinit int setup_node(int 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; - } - return pxm2node[pxm]; + int node; + unsigned idx; + static bool_t warned; + + if ( pxm < MAX_NUMNODES ) + { + if ( node_found(pxm, pxm) ) + return p2n[pxm].node; + + /* Try to maintain indexing of p2n by pxm */ + if ( p2n[pxm].node == NUMA_NO_NODE ) + { + idx = pxm; + goto finish; + } + } + + for ( idx = 0; idx < MAX_NUMNODES; idx++ ) + if ( p2n[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); + p2n[idx].pxm = pxm; + p2n[pxm].node = node; + + return node; } int valid_numa_range(u64 start, u64 end, int node) @@ -111,8 +155,6 @@ 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; mem_hotplug = 0; } @@ -440,13 +482,14 @@ int __init acpi_scan_nodes(u64 start, u64 end) static int node_to_pxm(int 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 ( p2n[n].node == n ) + return p2n[n].pxm; + for ( i = 0; i < MAX_NUMNODES; i++ ) + if ( p2n[i].node == n ) + return p2n[i].pxm; + return 0; } int __node_distance(int a, int b) -- 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 |