[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH RFC 06/44] x86/boot: Allocate percpu pagetables for the idle vcpus



Introduce cpu_smpboot_alloc_common(), for state shared between
cpu_smpboot_alloc() and cpu_smpboot_bsp().

A necessary requirement now is that cpu_smpboot_nfb must be called between
allocating the percpu areas, and calling into the scheduler logic.

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
 xen/arch/x86/smpboot.c    | 51 ++++++++++++++++++++++++++++++++++++++++++++---
 xen/include/asm-x86/smp.h |  2 ++
 2 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c
index 36b87dd..221d9c7 100644
--- a/xen/arch/x86/smpboot.c
+++ b/xen/arch/x86/smpboot.c
@@ -56,6 +56,8 @@
 
 unsigned long __read_mostly trampoline_phys;
 
+DEFINE_PER_CPU_READ_MOSTLY(paddr_t, percpu_idle_pt);
+
 /* representing HT siblings of each logical CPU */
 DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_mask);
 /* representing HT and core siblings of each logical CPU */
@@ -633,6 +635,36 @@ void cpu_exit_clear(unsigned int cpu)
     set_cpu_state(CPU_STATE_DEAD);
 }
 
+/* Allocate data common between the BSP and APs. */
+static int cpu_smpboot_alloc_common(unsigned int cpu)
+{
+    unsigned int memflags = 0;
+    nodeid_t node = cpu_to_node(cpu);
+    l4_pgentry_t *l4t = NULL;
+    struct page_info *pg;
+    int rc = -ENOMEM;
+
+    if ( node != NUMA_NO_NODE )
+        memflags = MEMF_node(node);
+
+    /* Percpu L4 table, used by the idle cpus. */
+    pg = alloc_domheap_page(NULL, memflags);
+    if ( !pg )
+        goto out;
+    per_cpu(percpu_idle_pt, cpu) = page_to_maddr(pg);
+    l4t = __map_domain_page(pg);
+    clear_page(l4t);
+    init_xen_l4_slots(l4t, page_to_mfn(pg), NULL, INVALID_MFN, false);
+
+    rc = 0; /* Success */
+
+ out:
+    if ( l4t )
+        unmap_domain_page(l4t);
+
+    return rc;
+}
+
 static void cpu_smpboot_free(unsigned int cpu)
 {
     unsigned int order, socket = cpu_to_socket(cpu);
@@ -686,6 +718,12 @@ static void cpu_smpboot_free(unsigned int cpu)
         free_xenheap_pages(stack_base[cpu], STACK_ORDER);
         stack_base[cpu] = NULL;
     }
+
+    if ( per_cpu(percpu_idle_pt, cpu) )
+    {
+        free_domheap_page(maddr_to_page(per_cpu(percpu_idle_pt, cpu)));
+        per_cpu(percpu_idle_pt, cpu) = 0;
+    }
 }
 
 static int cpu_smpboot_alloc(unsigned int cpu)
@@ -747,7 +785,7 @@ static int cpu_smpboot_alloc(unsigned int cpu)
            alloc_cpumask_var(&per_cpu(scratch_cpumask, cpu))) )
         goto out;
 
-    rc = 0;
+    rc = cpu_smpboot_alloc_common(cpu);
 
  out:
     if ( rc )
@@ -759,11 +797,17 @@ static int cpu_smpboot_alloc(unsigned int cpu)
 void __init cpu_smpboot_bsp(void)
 {
     unsigned int cpu = smp_processor_id();
-    int rc = -ENOMEM;
+    int rc;
+
+    if ( (rc = cpu_smpboot_alloc_common(cpu)) != 0 )
+        goto err;
 
     if ( (per_cpu(stubs.addr, cpu) =
           alloc_stub_page(cpu, &per_cpu(stubs, cpu).mfn)) == 0 )
+    {
+        rc = -ENOMEM;
         goto err;
+    }
 
     return;
 
@@ -794,7 +838,8 @@ static int cpu_smpboot_callback(
 }
 
 static struct notifier_block cpu_smpboot_nfb = {
-    .notifier_call = cpu_smpboot_callback
+    .notifier_call = cpu_smpboot_callback,
+    .priority = 99, /* Must be after percpu area, before idle vcpu. */
 };
 
 void __init smp_prepare_cpus(unsigned int max_cpus)
diff --git a/xen/include/asm-x86/smp.h b/xen/include/asm-x86/smp.h
index 409f3af..7fcc946 100644
--- a/xen/include/asm-x86/smp.h
+++ b/xen/include/asm-x86/smp.h
@@ -19,6 +19,8 @@
 #define INVALID_CUID (~0U)   /* AMD Compute Unit ID */
 #ifndef __ASSEMBLY__
 
+DECLARE_PER_CPU(paddr_t, percpu_idle_pt);
+
 /*
  * Private routines/data
  */
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

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