[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] x86/vpmu: add cpu hot unplug notifier for vpmu
Currently, hot unplug a cpu with vpmu enabled may cause system hang due to send IPI to a die physical cpu. This patch add a cpu hot unplug notifer to save vpmu context before cpu offline. Consider one scene, hotplug physical cpu N with vpmu is enabled. The vcpu which running on this physical cpu before will be switch to other online cpu. Before load the vpmu context to new physical cpu, a IPI will be send to cpu N to save the vpmu context. System will hang in function on_select_cpus because of that physical cpu is offline and can not do any response. Signed-off-by: Luwei Kang <luwei.kang@xxxxxxxxx> --- xen/arch/x86/cpu/vpmu.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/cpu/vpmu.c b/xen/arch/x86/cpu/vpmu.c index 03401fd..89e0ea8 100644 --- a/xen/arch/x86/cpu/vpmu.c +++ b/xen/arch/x86/cpu/vpmu.c @@ -35,6 +35,7 @@ #include <asm/apic.h> #include <public/pmu.h> #include <xsm/xsm.h> +#include <xen/cpu.h> #include <compat/pmu.h> CHECK_pmu_cntr_pair; @@ -835,6 +836,36 @@ long do_xenpmu_op(unsigned int op, XEN_GUEST_HANDLE_PARAM(xen_pmu_params_t) arg) return ret; } +static int cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) +{ + unsigned int cpu = (unsigned long)hcpu; + struct vcpu *vcpu = per_cpu(last_vcpu, cpu); + struct vpmu_struct *vpmu; + + if ( !vcpu ) + return NOTIFY_DONE; + + vpmu = vcpu_vpmu(vcpu); + if ( !vpmu_is_set(vpmu, VPMU_CONTEXT_ALLOCATED) ) + return NOTIFY_DONE; + + switch ( action ) + { + case CPU_DYING: + vpmu_save_force(vcpu); + vpmu_reset(vpmu, VPMU_CONTEXT_LOADED); + break; + default: + break; + } + + return NOTIFY_DONE; +} + +static struct notifier_block vpmu_cpu_nfb = { + .notifier_call = cpu_callback +}; + static int __init vpmu_init(void) { int vendor = current_cpu_data.x86_vendor; @@ -871,10 +902,11 @@ static int __init vpmu_init(void) break; } - if ( vpmu_mode != XENPMU_MODE_OFF ) + if ( vpmu_mode != XENPMU_MODE_OFF ) { + register_cpu_notifier(&vpmu_cpu_nfb); printk(XENLOG_INFO "VPMU: version " __stringify(XENPMU_VER_MAJ) "." __stringify(XENPMU_VER_MIN) "\n"); - else + } else opt_vpmu_enabled = 0; return 0; -- 1.8.3.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |