[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] RE: [PATCH] Add hypercall to expose physical CPU in xen hypervisor
I adjust the patch according to your feedback, please have a look. I leave some space in struct xen_physical_cpuinfo for future usage, like cpu topolonogy, or other stastic information. Thanks Yunhong Jiang This patch add hypercall to xen hypervisor to expose physical CPU information. It also make some changes to current cpu online/offline logic: 1) Firstly, cpu online/offline will trigger a vIRQ to dom0 for status changes notification. 2) It also add an interface to platform operation to online/offline physical CPU. Currently the cpu online/offline interface is in sysctl, which can't be triggered in kernel. With this change, it is possible to trigger cpu online/offline in dom0 through sysfs interface. Signed-off-by: Jiang, Yunhong <yunhong.jiang@xxxxxxxxx> diff -r 494ad84ad38c xen/arch/x86/platform_hypercall.c --- a/xen/arch/x86/platform_hypercall.c Mon Nov 09 22:41:23 2009 +0000 +++ b/xen/arch/x86/platform_hypercall.c Tue Nov 10 05:18:25 2009 +0800 @@ -53,6 +53,12 @@ static long cpu_frequency_change_helper( return cpu_frequency_change(this_cpu(freq)); } +static long cpu_down_helper(void *data) +{ + int cpu = (unsigned long)data; + return cpu_down(cpu); +} + ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op) { ret_t ret = 0; @@ -385,7 +391,97 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe break; } break; - + + case XENPF_get_cpuinfo: + { + int i; + struct xenpf_pcpu_info *g_info; + struct xen_physical_cpuinfo pcpu; + XEN_GUEST_HANDLE(xen_physical_cpuinfo_t) g_cpus; + + g_info = &op->u.pcpu_info; + if (g_info->info_num <= 0 ) + { + op->u.pcpu_info.max_present = last_cpu(cpu_present_map); + op->u.pcpu_info.max_possible = last_cpu(cpu_possible_map); + goto done; + } + + guest_from_compat_handle(g_cpus, g_info->info); + + spin_lock(&cpu_add_remove_lock); + + ret = -EFAULT; + for (i = 0; i < g_info->info_num; i++) + { + if (copy_from_guest_offset(&pcpu, g_cpus, i, 1) ) + goto out; + + if ( (pcpu.xen_cpuid >= NR_CPUS) || + (pcpu.xen_cpuid < 0) || + !cpu_present(pcpu.xen_cpuid) ) + { + pcpu.flags |= XEN_PCPU_FLAGS_INVALID; + } + else + { + pcpu.apic_id = x86_cpu_to_apicid[pcpu.xen_cpuid]; + pcpu.acpi_id = acpi_get_processor_id(pcpu.xen_cpuid); + ASSERT(pcpu.apic_id != BAD_APICID); + if (cpu_online(pcpu.xen_cpuid)) + pcpu.flags |= XEN_PCPU_FLAGS_ONLINE; + } + + if ( copy_to_guest_offset(g_cpus, i, &pcpu, 1) ) + goto out; + } + op->u.pcpu_info.max_present = last_cpu(cpu_present_map); + op->u.pcpu_info.max_possible = last_cpu(cpu_possible_map); + spin_unlock(&cpu_add_remove_lock); +done: + ret = copy_to_guest(u_xenpf_op, op, 1) ? -EFAULT : 0; + } + break; + + case XENPF_resource_hotplug: + { + int cpu; + + switch ( op->u.resource.sub_cmd) + { + case XEN_CPU_online: + cpu = op->u.resource.u.cpu_ol.cpuid; + if (!cpu_present(cpu)) + { + ret = -EINVAL; + break; + } + else if (cpu_online(cpu)) + { + ret = 0; + break; + } + + ret = cpu_up(cpu); + break; + case XEN_CPU_offline: + cpu = op->u.resource.u.cpu_ol.cpuid; + if (!cpu_present(cpu)) + { + ret = -EINVAL; + break; + } else if (!cpu_online(cpu)) + { + ret = 0; + break; + } + ret = continue_hypercall_on_cpu( + 0, cpu_down_helper, (void *)(unsigned long)cpu); + break; + } + } + break; + default: ret = -ENOSYS; break; diff -r 494ad84ad38c xen/arch/x86/smpboot.c --- a/xen/arch/x86/smpboot.c Mon Nov 09 22:41:23 2009 +0000 +++ b/xen/arch/x86/smpboot.c Tue Nov 10 05:18:25 2009 +0800 @@ -44,6 +44,7 @@ #include <xen/softirq.h> #include <xen/serial.h> #include <xen/numa.h> +#include <xen/event.h> #include <asm/current.h> #include <asm/mc146818rtc.h> #include <asm/desc.h> @@ -104,7 +105,7 @@ DEFINE_PER_CPU(int, cpu_state) = { 0 }; DEFINE_PER_CPU(int, cpu_state) = { 0 }; static void *stack_base[NR_CPUS]; -static DEFINE_SPINLOCK(cpu_add_remove_lock); +DEFINE_SPINLOCK(cpu_add_remove_lock); /* * The bootstrap kernel entry code has set these up. Save them for @@ -1342,6 +1343,8 @@ int cpu_down(unsigned int cpu) cpu_mcheck_distribute_cmci(); out: + if (!err) + send_guest_global_virq(dom0, VIRQ_PCPU_STATE); spin_unlock(&cpu_add_remove_lock); return err; } @@ -1362,6 +1365,8 @@ int cpu_up(unsigned int cpu) goto out; out: + if (!err) + send_guest_global_virq(dom0, VIRQ_PCPU_STATE); spin_unlock(&cpu_add_remove_lock); return err; } diff -r 494ad84ad38c xen/arch/x86/x86_64/platform_hypercall.c --- a/xen/arch/x86/x86_64/platform_hypercall.c Mon Nov 09 22:41:23 2009 +0000 +++ b/xen/arch/x86/x86_64/platform_hypercall.c Tue Nov 10 05:18:25 2009 +0800 @@ -23,6 +23,12 @@ DEFINE_XEN_GUEST_HANDLE(compat_platform_ #define xen_processor_power_t compat_processor_power_t #define set_cx_pminfo compat_set_cx_pminfo +DEFINE_XEN_GUEST_HANDLE(compat_physical_cpuinfo_t); +#define xen_physical_cpuinfo compat_physical_cpuinfo +#define xen_physical_cpuinfo_t compat_physical_cpuinfo_t +#define xenpf_pcpu_info compat_pf_pcpu_info +#define xenpf_pcpu_info_t compat_pf_pcpu_info_t + #define xenpf_enter_acpi_sleep compat_pf_enter_acpi_sleep #define COMPAT diff -r 494ad84ad38c xen/include/asm-x86/smp.h --- a/xen/include/asm-x86/smp.h Mon Nov 09 22:41:23 2009 +0000 +++ b/xen/include/asm-x86/smp.h Tue Nov 10 05:18:25 2009 +0800 @@ -56,6 +56,7 @@ extern u32 cpu_2_logical_apicid[]; #define CPU_ONLINE 0x0002 /* CPU is up */ #define CPU_DEAD 0x0004 /* CPU is dead */ DECLARE_PER_CPU(int, cpu_state); +extern spinlock_t(cpu_add_remove_lock); #ifdef CONFIG_HOTPLUG_CPU #define cpu_is_offline(cpu) unlikely(!cpu_online(cpu)) diff -r 494ad84ad38c xen/include/public/platform.h --- a/xen/include/public/platform.h Mon Nov 09 22:41:23 2009 +0000 +++ b/xen/include/public/platform.h Tue Nov 10 05:18:25 2009 +0800 @@ -312,6 +312,57 @@ typedef struct xenpf_set_processor_pminf typedef struct xenpf_set_processor_pminfo xenpf_set_processor_pminfo_t; DEFINE_XEN_GUEST_HANDLE(xenpf_set_processor_pminfo_t); +#define XENPF_get_cpuinfo 55 +struct xen_physical_cpuinfo { + /* IN */ + uint32_t xen_cpuid; + /* OUT */ + uint32_t apic_id; + uint32_t acpi_id; +#define XEN_PCPU_FLAGS_ONLINE 1 + /* Correponding xen_cpuid is not present*/ +#define XEN_PCPU_FLAGS_INVALID 2 + uint32_t flags; + uint8_t pad[128]; +}; +typedef struct xen_physical_cpuinfo xen_physical_cpuinfo_t; +DEFINE_XEN_GUEST_HANDLE(xen_physical_cpuinfo_t); + +/* + * Fetch physical CPUs information + */ +struct xenpf_pcpu_info +{ + /* OUT */ + /* The maxium cpu_id that is present */ + uint32_t max_present; + /* The maxium possible cpus */ + uint32_t max_possible; + + /* IN */ + uint32_t info_num; + + XEN_GUEST_HANDLE(xen_physical_cpuinfo_t) info; +}; +typedef struct xenpf_pcpu_info xenpf_pcpu_info_t; +DEFINE_XEN_GUEST_HANDLE(xenpf_pcpu_info_t); + +struct xenpf_cpu_ol +{ + uint32_t cpuid; +}; + +#define XENPF_resource_hotplug 56 +struct xenpf_resource_hotplug { + uint32_t sub_cmd; +#define XEN_CPU_online 1 +#define XEN_CPU_offline 2 + union { + struct xenpf_cpu_ol cpu_ol; + uint8_t pad[64]; + }u; +}; + struct xen_platform_op { uint32_t cmd; uint32_t interface_version; /* XENPF_INTERFACE_VERSION */ @@ -327,6 +378,8 @@ struct xen_platform_op { struct xenpf_change_freq change_freq; struct xenpf_getidletime getidletime; struct xenpf_set_processor_pminfo set_pminfo; + struct xenpf_pcpu_info pcpu_info; + struct xenpf_resource_hotplug resource; uint8_t pad[128]; } u; }; diff -r 494ad84ad38c xen/include/public/xen.h --- a/xen/include/public/xen.h Mon Nov 09 22:41:23 2009 +0000 +++ b/xen/include/public/xen.h Tue Nov 10 05:18:25 2009 +0800 @@ -145,6 +145,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_pfn_t); #define VIRQ_DEBUGGER 6 /* G. (DOM0) A domain has paused for debugging. */ #define VIRQ_XENOPROF 7 /* V. XenOprofile interrupt: new sample available */ #define VIRQ_CON_RING 8 /* G. (DOM0) Bytes received on console */ +#define VIRQ_PCPU_STATE 9 /* G. (DOM0) PCPU state changed */ /* Architecture-specific VIRQ definitions. */ #define VIRQ_ARCH_0 16 Keir Fraser wrote: > On 08/11/2009 01:59, "Jiang, Yunhong" <yunhong.jiang@xxxxxxxxx> wrote: > >> The Linux patch is initially part of patch for CPU hotplug. > > Ah, I see it's part of the phys hotplug stuff. It's okay with > me if Jeremy > will ack it. Also XENPF_get_cpuinfo should be made extensible, > and should > get a comment in public/platform.h, e.g., about what ncpus and > max_cpus mean. > > -- Keir Attachment:
xen_pcpu.patch _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |