Message ID | 57A20720020000780010238D@prv-mh.provo.novell.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Ping? >>> On 03.08.16 at 15:00, <JBeulich@suse.com> wrote: > As such clearing of flags may have an impact on the selected rendezvous > function, handle such in a central place. > > But don't allow such feature flags to be cleared during CPU hotplug: > Platform and local system times may have diverged significantly by > then, potentially causing noticably (even if only temporary) strange > behavior. As we're anyway expecting only sufficiently similar CPUs to > appear during hotplug, this shouldn't be introducing new limitations. > > Reported-by: Joao Martins <joao.m.martins@oracle.com> > Signed-off-by: Jan Beulich <jbeulich@suse.com> > Tested-by: Dario Faggioli <dario.faggioli@citrix.com> > Tested-by: Joao Martins <joao.m.martins@oracle.com> > > --- a/xen/arch/x86/cpu/mwait-idle.c > +++ b/xen/arch/x86/cpu/mwait-idle.c > @@ -1162,8 +1162,8 @@ static int mwait_idle_cpu_init(struct no > } > > if (state > 2 && !boot_cpu_has(X86_FEATURE_NONSTOP_TSC) && > - !pm_idle_save) > - setup_clear_cpu_cap(X86_FEATURE_TSC_RELIABLE); > + !pm_idle_save && system_state < SYS_STATE_active) > + clear_tsc_cap(X86_FEATURE_TSC_RELIABLE); > > cx = dev->states + dev->count; > cx->type = state; > --- a/xen/arch/x86/time.c > +++ b/xen/arch/x86/time.c > @@ -1353,6 +1353,24 @@ static void time_calibration(void *unuse > &r, 1); > } > > +void __init clear_tsc_cap(unsigned int feature) > +{ > + void (*rendezvous_fn)(void *) = time_calibration_std_rendezvous; > + > + if ( feature ) > + setup_clear_cpu_cap(feature); > + > + /* If we have constant-rate TSCs then scale factor can be shared. */ > + if ( boot_cpu_has(X86_FEATURE_CONSTANT_TSC) ) > + { > + /* If TSCs are not marked as 'reliable', re-sync during rendezvous. > */ > + if ( !boot_cpu_has(X86_FEATURE_TSC_RELIABLE) ) > + rendezvous_fn = time_calibration_tsc_rendezvous; > + } > + > + time_calibration_rendezvous_fn = rendezvous_fn; > +} > + > static struct { > s_time_t local_stime, master_stime; > } ap_bringup_ref; > @@ -1478,7 +1496,7 @@ static int __init verify_tsc_reliability > { > printk("%s: TSC warp detected, disabling TSC_RELIABLE\n", > __func__); > - setup_clear_cpu_cap(X86_FEATURE_TSC_RELIABLE); > + clear_tsc_cap(X86_FEATURE_TSC_RELIABLE); > } > } > > @@ -1491,13 +1509,7 @@ int __init init_xen_time(void) > { > tsc_check_writability(); > > - /* If we have constant-rate TSCs then scale factor can be shared. */ > - if ( boot_cpu_has(X86_FEATURE_CONSTANT_TSC) ) > - { > - /* If TSCs are not marked as 'reliable', re-sync during rendezvous. > */ > - if ( !boot_cpu_has(X86_FEATURE_TSC_RELIABLE) ) > - time_calibration_rendezvous_fn = > time_calibration_tsc_rendezvous; > - } > + clear_tsc_cap(0); > > open_softirq(TIME_CALIBRATE_SOFTIRQ, local_time_calibration); > > --- a/xen/include/asm-x86/time.h > +++ b/xen/include/asm-x86/time.h > @@ -70,6 +70,7 @@ void tsc_get_info(struct domain *d, uint > void force_update_vcpu_system_time(struct vcpu *v); > > int host_tsc_is_safe(void); > +void clear_tsc_cap(unsigned int feature); > void cpuid_time_leaf(uint32_t sub_idx, uint32_t *eax, uint32_t *ebx, > uint32_t *ecx, uint32_t *edx); >
--- a/xen/arch/x86/cpu/mwait-idle.c +++ b/xen/arch/x86/cpu/mwait-idle.c @@ -1162,8 +1162,8 @@ static int mwait_idle_cpu_init(struct no } if (state > 2 && !boot_cpu_has(X86_FEATURE_NONSTOP_TSC) && - !pm_idle_save) - setup_clear_cpu_cap(X86_FEATURE_TSC_RELIABLE); + !pm_idle_save && system_state < SYS_STATE_active) + clear_tsc_cap(X86_FEATURE_TSC_RELIABLE); cx = dev->states + dev->count; cx->type = state; --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -1353,6 +1353,24 @@ static void time_calibration(void *unuse &r, 1); } +void __init clear_tsc_cap(unsigned int feature) +{ + void (*rendezvous_fn)(void *) = time_calibration_std_rendezvous; + + if ( feature ) + setup_clear_cpu_cap(feature); + + /* If we have constant-rate TSCs then scale factor can be shared. */ + if ( boot_cpu_has(X86_FEATURE_CONSTANT_TSC) ) + { + /* If TSCs are not marked as 'reliable', re-sync during rendezvous. */ + if ( !boot_cpu_has(X86_FEATURE_TSC_RELIABLE) ) + rendezvous_fn = time_calibration_tsc_rendezvous; + } + + time_calibration_rendezvous_fn = rendezvous_fn; +} + static struct { s_time_t local_stime, master_stime; } ap_bringup_ref; @@ -1478,7 +1496,7 @@ static int __init verify_tsc_reliability { printk("%s: TSC warp detected, disabling TSC_RELIABLE\n", __func__); - setup_clear_cpu_cap(X86_FEATURE_TSC_RELIABLE); + clear_tsc_cap(X86_FEATURE_TSC_RELIABLE); } } @@ -1491,13 +1509,7 @@ int __init init_xen_time(void) { tsc_check_writability(); - /* If we have constant-rate TSCs then scale factor can be shared. */ - if ( boot_cpu_has(X86_FEATURE_CONSTANT_TSC) ) - { - /* If TSCs are not marked as 'reliable', re-sync during rendezvous. */ - if ( !boot_cpu_has(X86_FEATURE_TSC_RELIABLE) ) - time_calibration_rendezvous_fn = time_calibration_tsc_rendezvous; - } + clear_tsc_cap(0); open_softirq(TIME_CALIBRATE_SOFTIRQ, local_time_calibration); --- a/xen/include/asm-x86/time.h +++ b/xen/include/asm-x86/time.h @@ -70,6 +70,7 @@ void tsc_get_info(struct domain *d, uint void force_update_vcpu_system_time(struct vcpu *v); int host_tsc_is_safe(void); +void clear_tsc_cap(unsigned int feature); void cpuid_time_leaf(uint32_t sub_idx, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx);