[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] return CPU status for off/online sysctl calls
The following patch makes the CPU off/online sysctl hypercalls return the old status, and also adds a call to retrieve the status only. Having the status is useful, and this matches the Solaris p_online call more closely, which is what the Solaris FMA code likes to have. This patch also makes sure to restore the warm boot vector (as the normal boot code does after bringing up CPU(s)), since not doing that can result in problems at the next reboot, with the CPU jumping back into Xen instead of into the BIOS to reboot. - Frank Add CPU status info and a status call to the CPU on/offline sysctls. Signed-off-by: Frank van der Linden <frank.vanderlinden@xxxxxxx> diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c --- a/xen/arch/x86/smpboot.c +++ b/xen/arch/x86/smpboot.c @@ -1426,8 +1426,10 @@ int __devinit __cpu_up(unsigned int cpu) * cpu_callin_map is set during AP kickstart process. Its reset * when a cpu is taken offline from cpu_exit_clear(). */ - if (!cpu_isset(cpu, cpu_callin_map)) + if (!cpu_isset(cpu, cpu_callin_map)) { ret = __smp_prepare_cpu(cpu); + smpboot_restore_warm_reset_vector(); + } if (ret) return -EIO; diff --git a/xen/arch/x86/sysctl.c b/xen/arch/x86/sysctl.c --- a/xen/arch/x86/sysctl.c +++ b/xen/arch/x86/sysctl.c @@ -38,7 +38,7 @@ long arch_do_sysctl( long arch_do_sysctl( struct xen_sysctl *sysctl, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl) { - long ret = 0; + long ret = 0, status; switch ( sysctl->cmd ) { @@ -102,19 +102,41 @@ long arch_do_sysctl( { unsigned int cpu = sysctl->u.cpu_hotplug.cpu; + if (cpu_present(cpu)) { + status = cpu_online(cpu) ? XEN_CPU_HOTPLUG_STATUS_ONLINE : + XEN_CPU_HOTPLUG_STATUS_OFFLINE; + } else { + status = -EINVAL; + } + switch ( sysctl->u.cpu_hotplug.op ) { case XEN_SYSCTL_CPU_HOTPLUG_ONLINE: ret = cpu_up(cpu); + /* + * In the case of a true hotplug, this CPU wasn't present + * before, so return the 'new' status for it. + */ + if (ret == 0 && status == -EINVAL) + status = XEN_CPU_HOTPLUG_STATUS_NEW; break; case XEN_SYSCTL_CPU_HOTPLUG_OFFLINE: ret = continue_hypercall_on_cpu( 0, cpu_down_helper, (void *)(unsigned long)cpu); break; + case XEN_SYSCTL_CPU_HOTPLUG_STATUS: + ret = 0; + break; default: ret = -EINVAL; break; } + + /* + * If the operation was successful, return the old status. + */ + if (ret >= 0) + ret = status; } break; diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h --- a/xen/include/public/sysctl.h +++ b/xen/include/public/sysctl.h @@ -262,12 +262,21 @@ typedef struct xen_sysctl_get_pmstat xen typedef struct xen_sysctl_get_pmstat xen_sysctl_get_pmstat_t; DEFINE_XEN_GUEST_HANDLE(xen_sysctl_get_pmstat_t); +/* + * Status codes. Must be greater than 0 to avoid confusing + * sysctl callers that see 0 as a plain successful return. + */ +#define XEN_CPU_HOTPLUG_STATUS_OFFLINE 1 +#define XEN_CPU_HOTPLUG_STATUS_ONLINE 2 +#define XEN_CPU_HOTPLUG_STATUS_NEW 3 + #define XEN_SYSCTL_cpu_hotplug 11 struct xen_sysctl_cpu_hotplug { /* IN variables */ uint32_t cpu; /* Physical cpu. */ #define XEN_SYSCTL_CPU_HOTPLUG_ONLINE 0 #define XEN_SYSCTL_CPU_HOTPLUG_OFFLINE 1 +#define XEN_SYSCTL_CPU_HOTPLUG_STATUS 2 uint32_t op; /* hotplug opcode */ }; typedef struct xen_sysctl_cpu_hotplug xen_sysctl_cpu_hotplug_t; _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |