[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 |