[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.