[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] RE: [PATCH] Support physical CPU hot-add in xen hypervisor
This patch depends on the "Update pcpu_info hypercall interface" patch I sent just now. Sorry that I should sent them out as series. Thanks Yunhong Jiang Jiang, Yunhong wrote: > This patch add CPU hot-add in system. > a) It mark all CPU as possible when booting, if > CONFIG_HOTPLUG_CPU is set. BTW, this will increase per_cpu area. > > b) When a CPU is added through hypercall, the CPU will be > marked as present and offline, and the numa information is > setup if numa is supported. The CPU will be brought to online > by dom0 online explicitly. > > Signed-off-by: Jiang, Yunhong <yunhong.jiang@xxxxxxxxx> > > diff -r 68b6bf9b5c8b xen/arch/x86/acpi/boot.c > --- a/xen/arch/x86/acpi/boot.c Thu Nov 12 04:08:25 2009 +0800 > +++ b/xen/arch/x86/acpi/boot.c Thu Nov 12 04:08:43 2009 +0800 > @@ -81,7 +81,6 @@ u8 acpi_enable_value, acpi_disable_value > #warning ACPI uses CMPXCHG, i486 and later hardware #endif > > -#define MAX_MADT_ENTRIES 256 > u8 x86_acpiid_to_apicid[MAX_MADT_ENTRIES] = > {[0 ... MAX_MADT_ENTRIES - 1] = 0xff }; > EXPORT_SYMBOL(x86_acpiid_to_apicid); > diff -r 68b6bf9b5c8b xen/arch/x86/mpparse.c > --- a/xen/arch/x86/mpparse.c Thu Nov 12 04:08:25 2009 +0800 > +++ b/xen/arch/x86/mpparse.c Thu Nov 12 04:08:43 2009 +0800 @@ -35,7 > +35,7 @@ > > /* Have we found an MP table */ > int smp_found_config; > -unsigned int __initdata maxcpus = NR_CPUS; > +unsigned int __devinitdata maxcpus = NR_CPUS; > > /* > * Various Linux-internal data structures created from the > @@ -868,6 +868,20 @@ int __devinit mp_register_lapic ( > return MP_processor_info(&processor); > } > > +void mp_unregister_lapic(uint32_t apic_id, uint32_t cpu) +{ > + if (!cpu || (apic_id == boot_cpu_physical_apicid)) + > return; + > + if (x86_cpu_to_apicid[cpu] != apic_id) > + return; > + > + physid_clear(apic_id, phys_cpu_present_map); > + > + x86_cpu_to_apicid[cpu] = BAD_APICID; > + cpu_clear(cpu, cpu_present_map); > + } > + > #ifdef CONFIG_X86_IO_APIC > > #define MP_ISA_BUS 0 > diff -r 68b6bf9b5c8b xen/arch/x86/numa.c > --- a/xen/arch/x86/numa.c Thu Nov 12 04:08:25 2009 +0800 > +++ b/xen/arch/x86/numa.c Thu Nov 12 04:08:43 2009 +0800 > @@ -42,9 +42,9 @@ nodemask_t __read_mostly node_online_map > nodemask_t __read_mostly node_online_map = { { [0] = 1UL } }; > > /* Default NUMA to off for now. acpi=on required to enable it. */ > -int numa_off __initdata = 1; > - > -int acpi_numa __initdata; > +int numa_off __devinitdata = 1; > + > +int acpi_numa __devinitdata; > > /* > * Given a shift value, try to populate memnodemap[] > @@ -53,7 +53,7 @@ int acpi_numa __initdata; > * 0 if memnodmap[] too small (of shift too small) > * -1 if node overlap or lost ram (shift too big) > */ > -static int __init > +static int __devinit > populate_memnodemap(const struct node *nodes, int numnodes, int > shift) { int i; > @@ -259,7 +259,7 @@ static __init int numa_setup(char *opt) > * prior to this call, and this initialization is good enough > * for the fake NUMA cases. > */ > -void __init init_cpu_to_node(void) > +void __devinit init_cpu_to_node(void) > { > int i; > for (i = 0; i < NR_CPUS; i++) { > diff -r 68b6bf9b5c8b xen/arch/x86/platform_hypercall.c > --- a/xen/arch/x86/platform_hypercall.c Thu Nov 12 > 04:08:25 2009 +0800 > +++ b/xen/arch/x86/platform_hypercall.c Thu Nov 12 > 04:08:43 2009 +0800 > @@ -463,6 +463,12 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe } > break; > > + case XENPF_cpu_hotadd: > + ret = cpu_add(op->u.cpu_add.apic_id, > + op->u.cpu_add.acpi_id, > + op->u.cpu_add.pxm); > + break; > + > default: > ret = -ENOSYS; > break; > diff -r 68b6bf9b5c8b xen/arch/x86/setup.c > --- a/xen/arch/x86/setup.c Thu Nov 12 04:08:25 2009 +0800 > +++ b/xen/arch/x86/setup.c Thu Nov 12 04:08:43 2009 +0800 > @@ -246,7 +246,7 @@ static void __init init_idle_domain(void > setup_idle_pagetable(); } > > -static void __init srat_detect_node(int cpu) > +void __devinit srat_detect_node(int cpu) > { > unsigned node; > u32 apicid = x86_cpu_to_apicid[cpu]; > @@ -483,6 +483,10 @@ void __init __start_xen(unsigned long mb > asm volatile ( "mov %%cr4,%0" : "=r" (this_cpu(cr4)) ); > > smp_prepare_boot_cpu(); > + > +#ifdef CONFIG_HOTPLUG_CPU > + prefill_possible_map(); > +#endif > > /* We initialise the serial devices very early so we can > get debugging. */ > ns16550.io_base = 0x3f8; > diff -r 68b6bf9b5c8b xen/arch/x86/smpboot.c > --- a/xen/arch/x86/smpboot.c Thu Nov 12 04:08:25 2009 +0800 > +++ b/xen/arch/x86/smpboot.c Thu Nov 12 04:08:43 2009 +0800 > @@ -1435,6 +1435,78 @@ void enable_nonboot_cpus(void) */ > smpboot_restore_warm_reset_vector(); > } > + > +int prefill_possible_map(void) > +{ > + int i; > + > + for (i = 0; i < NR_CPUS; i++) > + cpu_set(i, cpu_possible_map); > + return 0; > +} > + > +int cpu_add(uint32_t apic_id, uint32_t acpi_id, uint32_t pxm) +{ > + int cpu = -1; > + > +#ifndef CONFIG_ACPI > + return -ENOSYS; > +#endif > + > + dprintk(XENLOG_DEBUG, "cpu_add apic_id %x acpi_id %x pxm %x\n", > + apic_id, acpi_id, pxm); > + > + if ( acpi_id > MAX_MADT_ENTRIES || apic_id > MAX_APICS || > pxm > 256 ) > + return -EINVAL; > + > + /* Detect if the cpu has been added before */ > + if ( x86_acpiid_to_apicid[acpi_id] != 0xff) > + { > + if (x86_acpiid_to_apicid[acpi_id] != apic_id) + > return -EINVAL; + else > + return -EEXIST; > + } > + > + if ( physid_isset(apic_id, phys_cpu_present_map) ) + > return -EEXIST; + > + spin_lock(&cpu_add_remove_lock); > + > + cpu = mp_register_lapic(apic_id, 1); > + > + if (cpu < 0) > + { > + spin_unlock(&cpu_add_remove_lock); > + return cpu; > + } > + > + x86_acpiid_to_apicid[acpi_id] = apic_id; > + > + if ( !srat_disabled() ) > + { > + int node; > + > + node = setup_node(pxm); > + if (node < 0) > + { > + dprintk(XENLOG_WARNING, "Setup node failed for > pxm %x\n", pxm); > + x86_acpiid_to_apicid[acpi_id] = 0xff; > + mp_unregister_lapic(apic_id, cpu); > + spin_unlock(&cpu_add_remove_lock); > + return node; > + } > + apicid_to_node[apic_id] = node; > + } > + > + srat_detect_node(cpu); > + numa_add_cpu(cpu); > + spin_unlock(&cpu_add_remove_lock); > + dprintk(XENLOG_INFO, "Add CPU %x with index %x\n", apic_id, > cpu); + return cpu; +} > + > + > #else /* ... !CONFIG_HOTPLUG_CPU */ > int __cpu_disable(void) > { > @@ -1445,6 +1517,11 @@ void __cpu_die(unsigned int cpu) { > /* We said "no" in __cpu_disable */ > BUG(); > +} > + > +int cpu_add(uint32_t apic_id, uint32_t acpi_id, uint32_t pxm) +{ > + return -ENOSYS; > } > #endif /* CONFIG_HOTPLUG_CPU */ > > diff -r 68b6bf9b5c8b xen/arch/x86/srat.c > --- a/xen/arch/x86/srat.c Thu Nov 12 04:08:25 2009 +0800 > +++ b/xen/arch/x86/srat.c Thu Nov 12 04:08:43 2009 +0800 > @@ -41,7 +41,7 @@ int pxm_to_node(int pxm) > return (signed char)pxm2node[pxm]; > } > > -static __init int setup_node(int pxm) > +__devinit int setup_node(int pxm) > { > unsigned node = pxm2node[pxm]; > if (node == 0xff) { > @@ -91,11 +91,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; > -} > - > -static __init inline int srat_disabled(void) > -{ > - return numa_off || acpi_numa < 0; > } > > /* > diff -r 68b6bf9b5c8b xen/include/asm-x86/acpi.h > --- a/xen/include/asm-x86/acpi.h Thu Nov 12 04:08:25 2009 +0800 > +++ b/xen/include/asm-x86/acpi.h Thu Nov 12 04:08:43 2009 +0800 > @@ -150,6 +150,7 @@ struct acpi_sleep_info { > > #endif /* CONFIG_ACPI_SLEEP */ > > +#define MAX_MADT_ENTRIES 256 > extern u8 x86_acpiid_to_apicid[]; > #define MAX_LOCAL_APIC 256 > > diff -r 68b6bf9b5c8b xen/include/asm-x86/numa.h > --- a/xen/include/asm-x86/numa.h Thu Nov 12 04:08:25 2009 +0800 > +++ b/xen/include/asm-x86/numa.h Thu Nov 12 04:08:43 2009 +0800 > @@ -30,7 +30,13 @@ extern void numa_init_array(void); > extern void numa_init_array(void); > extern int numa_off; > > +static __devinit inline int srat_disabled(void) > +{ > + return numa_off || acpi_numa < 0; > +} > extern void numa_set_node(int cpu, int node); > +extern int setup_node(int pxm); > +extern void srat_detect_node(int cpu); > > extern void setup_node_bootmem(int nodeid, u64 start, u64 end); > extern unsigned char apicid_to_node[256]; > diff -r 68b6bf9b5c8b xen/include/asm-x86/smp.h > --- a/xen/include/asm-x86/smp.h Thu Nov 12 04:08:25 2009 +0800 > +++ b/xen/include/asm-x86/smp.h Thu Nov 12 04:08:43 2009 +0800 > @@ -66,6 +66,8 @@ extern void cpu_uninit(void); > extern void cpu_uninit(void); > extern void disable_nonboot_cpus(void); > extern void enable_nonboot_cpus(void); > +int prefill_possible_map(void); > +int cpu_add(uint32_t apic_id, uint32_t acpi_id, uint32_t pxm); #else > static inline int cpu_is_offline(int cpu) {return 0;} > static inline void disable_nonboot_cpus(void) {} > diff -r 68b6bf9b5c8b xen/include/public/platform.h > --- a/xen/include/public/platform.h Thu Nov 12 04:08:25 2009 +0800 > +++ b/xen/include/public/platform.h Thu Nov 12 04:08:43 2009 +0800 > @@ -338,6 +338,14 @@ typedef struct xenpf_cpu_ol xenpf_cpu_ol > typedef struct xenpf_cpu_ol xenpf_cpu_ol_t; > DEFINE_XEN_GUEST_HANDLE(xenpf_cpu_ol_t); > > +#define XENPF_cpu_hotadd 58 > +struct xenpf_cpu_hotadd > +{ > + uint32_t apic_id; > + uint32_t acpi_id; > + uint32_t pxm; > +}; > + > struct xen_platform_op { > uint32_t cmd; > uint32_t interface_version; /* XENPF_INTERFACE_VERSION */ > @@ -355,6 +363,7 @@ struct xen_platform_op { > struct xenpf_set_processor_pminfo set_pminfo; > struct xenpf_pcpuinfo pcpu_info; > struct xenpf_cpu_ol cpu_ol; > + struct xenpf_cpu_hotadd cpu_add; > uint8_t pad[128]; > } u; > }; _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |