|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |