Jan Beulich
2011-Mar-18 15:07 UTC
[Xen-devel] [PATCH] x86/mce: CPU notifiers must not be registered a second time during resume
While c/s 22964:f71212f712fd and 23051:93c864c16ab1 fixed issues with CPU onlining, they introduced a problem with resume: mcheck_init() is also being called on that path, and hence checking whether it''s running on CPU 0, which is generally not a really good thing, is particularly inappropriate here. Signed-off-by: Jan Beulich <jbeulich@novell.com> --- a/xen/arch/x86/acpi/power.c +++ b/xen/arch/x86/acpi/power.c @@ -187,7 +187,7 @@ static int enter_state(u32 state) device_power_up(); - mcheck_init(&boot_cpu_data); + mcheck_init(&boot_cpu_data, 0); write_cr4(cr4); printk(XENLOG_INFO "Finishing wakeup from ACPI S%d state.\n", state); --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -431,19 +431,13 @@ void __cpuinit identify_cpu(struct cpuin /* AND the already accumulated flags with these */ for ( i = 0 ; i < NCAPINTS ; i++ ) boot_cpu_data.x86_capability[i] &= c->x86_capability[i]; - } - - /* Init Machine Check Exception if available. */ - mcheck_init(c); -#if 0 - if (c == &boot_cpu_data) - sysenter_setup(); - enable_sep_cpu(); -#endif + mcheck_init(c, 0); + } else { + mcheck_init(c, 1); - if (c == &boot_cpu_data) mtrr_bp_init(); + } } /* cpuid returns the value latched in the HW at reset, not the APIC ID --- a/xen/arch/x86/cpu/mcheck/mce.c +++ b/xen/arch/x86/cpu/mcheck/mce.c @@ -793,7 +793,7 @@ static struct notifier_block cpu_nfb = { }; /* This has to be run for each processor */ -void mcheck_init(struct cpuinfo_x86 *c) +void mcheck_init(struct cpuinfo_x86 *c, bool_t bsp) { enum mcheck_type inited = mcheck_none; @@ -822,7 +822,7 @@ void mcheck_init(struct cpuinfo_x86 *c) switch (c->x86) { case 6: case 15: - inited = intel_mcheck_init(c); + inited = intel_mcheck_init(c, bsp); break; } break; @@ -844,7 +844,7 @@ void mcheck_init(struct cpuinfo_x86 *c) /* Turn on MCE now */ set_in_cr4(X86_CR4_MCE); - if ( smp_processor_id() == 0 ) + if ( bsp ) { /* Early MCE initialisation for BSP. */ if ( cpu_poll_bankmask_alloc(0) ) --- a/xen/arch/x86/cpu/mcheck/mce.h +++ b/xen/arch/x86/cpu/mcheck/mce.h @@ -42,7 +42,7 @@ enum mcheck_type amd_k7_mcheck_init(stru enum mcheck_type amd_k8_mcheck_init(struct cpuinfo_x86 *c); enum mcheck_type amd_f10_mcheck_init(struct cpuinfo_x86 *c); -enum mcheck_type intel_mcheck_init(struct cpuinfo_x86 *c); +enum mcheck_type intel_mcheck_init(struct cpuinfo_x86 *c, bool_t bsp); void intel_mcheck_timer(struct cpuinfo_x86 *c); void mce_intel_feature_init(struct cpuinfo_x86 *c); --- a/xen/arch/x86/cpu/mcheck/mce_intel.c +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c @@ -1297,9 +1297,9 @@ static struct notifier_block cpu_nfb = { }; /* p4/p6 family have similar MCA initialization process */ -enum mcheck_type intel_mcheck_init(struct cpuinfo_x86 *c) +enum mcheck_type intel_mcheck_init(struct cpuinfo_x86 *c, bool_t bsp) { - if ( smp_processor_id() == 0 ) + if ( bsp ) { /* Early MCE initialisation for BSP. */ if ( cpu_mcabank_alloc(0) ) --- a/xen/include/asm-x86/processor.h +++ b/xen/include/asm-x86/processor.h @@ -555,7 +555,7 @@ void compat_show_guest_stack(struct vcpu extern void mtrr_ap_init(void); extern void mtrr_bp_init(void); -void mcheck_init(struct cpuinfo_x86 *c); +void mcheck_init(struct cpuinfo_x86 *c, bool_t bsp); #define DECLARE_TRAP_HANDLER(_name) \ asmlinkage void _name(void); \ _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2011-Mar-18 15:43 UTC
Re: [Xen-devel] [PATCH] x86/mce: CPU notifiers must not be registered a second time during resume
On 18/03/2011 15:07, "Jan Beulich" <JBeulich@novell.com> wrote:> While c/s 22964:f71212f712fd and 23051:93c864c16ab1 fixed issues with > CPU onlining, they introduced a problem with resume: mcheck_init() is > also being called on that path, and hence checking whether it''s running > on CPU 0, which is generally not a really good thing, is particularly > inappropriate here.Just have a ''static bool_t early_init_done'' or similar in intel_mcheck_init(). if ( !early_init_done ) { BUG_ON(smp_processor_id() != 0); ... early_init_done = 1; } It''s clearer anyway -- we''re simply protecting one-time-only early-boot-time initialisation stuff. -- Keir> Signed-off-by: Jan Beulich <jbeulich@novell.com> > > --- a/xen/arch/x86/acpi/power.c > +++ b/xen/arch/x86/acpi/power.c > @@ -187,7 +187,7 @@ static int enter_state(u32 state) > > device_power_up(); > > - mcheck_init(&boot_cpu_data); > + mcheck_init(&boot_cpu_data, 0); > write_cr4(cr4); > > printk(XENLOG_INFO "Finishing wakeup from ACPI S%d state.\n", state); > --- a/xen/arch/x86/cpu/common.c > +++ b/xen/arch/x86/cpu/common.c > @@ -431,19 +431,13 @@ void __cpuinit identify_cpu(struct cpuin > /* AND the already accumulated flags with these */ > for ( i = 0 ; i < NCAPINTS ; i++ ) > boot_cpu_data.x86_capability[i] &= c->x86_capability[i]; > - } > - > - /* Init Machine Check Exception if available. */ > - mcheck_init(c); > > -#if 0 > - if (c == &boot_cpu_data) > - sysenter_setup(); > - enable_sep_cpu(); > -#endif > + mcheck_init(c, 0); > + } else { > + mcheck_init(c, 1); > > - if (c == &boot_cpu_data) > mtrr_bp_init(); > + } > } > > /* cpuid returns the value latched in the HW at reset, not the APIC ID > --- a/xen/arch/x86/cpu/mcheck/mce.c > +++ b/xen/arch/x86/cpu/mcheck/mce.c > @@ -793,7 +793,7 @@ static struct notifier_block cpu_nfb = { > }; > > /* This has to be run for each processor */ > -void mcheck_init(struct cpuinfo_x86 *c) > +void mcheck_init(struct cpuinfo_x86 *c, bool_t bsp) > { > enum mcheck_type inited = mcheck_none; > > @@ -822,7 +822,7 @@ void mcheck_init(struct cpuinfo_x86 *c) > switch (c->x86) { > case 6: > case 15: > - inited = intel_mcheck_init(c); > + inited = intel_mcheck_init(c, bsp); > break; > } > break; > @@ -844,7 +844,7 @@ void mcheck_init(struct cpuinfo_x86 *c) > /* Turn on MCE now */ > set_in_cr4(X86_CR4_MCE); > > - if ( smp_processor_id() == 0 ) > + if ( bsp ) > { > /* Early MCE initialisation for BSP. */ > if ( cpu_poll_bankmask_alloc(0) ) > --- a/xen/arch/x86/cpu/mcheck/mce.h > +++ b/xen/arch/x86/cpu/mcheck/mce.h > @@ -42,7 +42,7 @@ enum mcheck_type amd_k7_mcheck_init(stru > enum mcheck_type amd_k8_mcheck_init(struct cpuinfo_x86 *c); > enum mcheck_type amd_f10_mcheck_init(struct cpuinfo_x86 *c); > > -enum mcheck_type intel_mcheck_init(struct cpuinfo_x86 *c); > +enum mcheck_type intel_mcheck_init(struct cpuinfo_x86 *c, bool_t bsp); > > void intel_mcheck_timer(struct cpuinfo_x86 *c); > void mce_intel_feature_init(struct cpuinfo_x86 *c); > --- a/xen/arch/x86/cpu/mcheck/mce_intel.c > +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c > @@ -1297,9 +1297,9 @@ static struct notifier_block cpu_nfb = { > }; > > /* p4/p6 family have similar MCA initialization process */ > -enum mcheck_type intel_mcheck_init(struct cpuinfo_x86 *c) > +enum mcheck_type intel_mcheck_init(struct cpuinfo_x86 *c, bool_t bsp) > { > - if ( smp_processor_id() == 0 ) > + if ( bsp ) > { > /* Early MCE initialisation for BSP. */ > if ( cpu_mcabank_alloc(0) ) > --- a/xen/include/asm-x86/processor.h > +++ b/xen/include/asm-x86/processor.h > @@ -555,7 +555,7 @@ void compat_show_guest_stack(struct vcpu > extern void mtrr_ap_init(void); > extern void mtrr_bp_init(void); > > -void mcheck_init(struct cpuinfo_x86 *c); > +void mcheck_init(struct cpuinfo_x86 *c, bool_t bsp); > > #define DECLARE_TRAP_HANDLER(_name) \ > asmlinkage void _name(void); \ > > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xensource.com > http://lists.xensource.com/xen-devel_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jan Beulich
2011-Mar-18 16:35 UTC
Re: [Xen-devel] [PATCH] x86/mce: CPU notifiers must not be registered a second time during resume
>>> On 18.03.11 at 16:43, Keir Fraser <keir.xen@gmail.com> wrote: > On 18/03/2011 15:07, "Jan Beulich" <JBeulich@novell.com> wrote: > >> While c/s 22964:f71212f712fd and 23051:93c864c16ab1 fixed issues with >> CPU onlining, they introduced a problem with resume: mcheck_init() is >> also being called on that path, and hence checking whether it''s running >> on CPU 0, which is generally not a really good thing, is particularly >> inappropriate here. > > Just have a ''static bool_t early_init_done'' or similar in > intel_mcheck_init().And another in mcheck_init(). If the proliferates, an alternative I would like a little better would be to just have a global variable (e.g. extending early_boot).> if ( !early_init_done ) { > BUG_ON(smp_processor_id() != 0); > ... > early_init_done = 1; > } > > It''s clearer anyway -- we''re simply protecting one-time-only early-boot-time > initialisation stuff.What''s wrong with doing the protection by passing down the necessary information? Jan _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2011-Mar-18 17:11 UTC
Re: [Xen-devel] [PATCH] x86/mce: CPU notifiers must not be registered a second time during resume
On 18/03/2011 16:35, "Jan Beulich" <JBeulich@novell.com> wrote:>> if ( !early_init_done ) { >> BUG_ON(smp_processor_id() != 0); >> ... >> early_init_done = 1; >> } >> >> It''s clearer anyway -- we''re simply protecting one-time-only early-boot-time >> initialisation stuff. > > What''s wrong with doing the protection by passing down the > necessary information?Hm, yes, fair enough, I''ll apply it. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Liu, Jinsong
2011-Mar-19 15:53 UTC
RE: [Xen-devel] [PATCH] x86/mce: CPU notifiers must not be registered a second time during resume
Thanks Jan and Keir! Sorry for late check email at weekend. I think a while, how about following solution (draft scheme): ----------------------------------------------- 1. at mce_intel.c, keep old intel_mce_initcall() func (it has been removed at c/s 22964), and do --- a/xen/arch/x86/cpu/mcheck/mce_intel.c Fri Feb 25 01:26:01 2011 +0800 +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c Mon Feb 28 19:19:20 2011 +0800 static int __init intel_mce_initcall(void) { + void *hcpu = (void *)(long)smp_processor_id(); + cpu_callback(&cpu_nfb, CPU_UP_PREPARE, hcpu); register_cpu_notifier(&cpu_nfb); return 0; } ----------------------------------------------- 2. at setup.c, do_presmp_initcalls() at little bit earlier diff -r 1a364b17d66a xen/arch/x86/setup.c --- a/xen/arch/x86/setup.c Fri Feb 25 01:26:01 2011 +0800 +++ b/xen/arch/x86/setup.c Mon Feb 28 19:19:20 2011 +0800 @@ -1203,6 +1203,8 @@ void __init __start_xen(unsigned long mb arch_init_memory(); + do_presmp_initcalls(); + identify_cpu(&boot_cpu_data); if ( cpu_has_fxsr ) set_in_cr4(X86_CR4_OSFXSR); @@ -1235,8 +1237,6 @@ void __init __start_xen(unsigned long mb initialize_keytable(); console_init_postirq(); - - do_presmp_initcalls(); for_each_present_cpu ( i ) ----------------------------------------------- How do you think? it don''t need to add bsp para to mcheck_int() as -void mcheck_init(struct cpuinfo_x86 *c) +void mcheck_init(struct cpuinfo_x86 *c, bool_t bsp) BTW, it can go further to unify cpu0 and cpux, like: ---------------------------------------------- diff -r 682880e909db xen/arch/x86/setup.c --- a/xen/arch/x86/setup.c Mon Feb 28 09:17:40 2011 +0800 +++ b/xen/arch/x86/setup.c Mon Feb 28 09:53:54 2011 +0800 @@ -1205,7 +1205,8 @@ void __init __start_xen(unsigned long mb do_presmp_initcalls(); - identify_cpu(&boot_cpu_data); + smp_prepare_cpus(max_cpus); + boot_cpu_data = cpu_data[0]; if ( cpu_has_fxsr ) set_in_cr4(X86_CR4_OSFXSR); if ( cpu_has_xmm ) @@ -1221,8 +1222,6 @@ void __init __start_xen(unsigned long mb max_cpus = 0; iommu_setup(); /* setup iommu if available */ - - smp_prepare_cpus(max_cpus); spin_debug_enable(); diff -r 682880e909db xen/arch/x86/smpboot.c --- a/xen/arch/x86/smpboot.c Mon Feb 28 09:17:40 2011 +0800 +++ b/xen/arch/x86/smpboot.c Mon Feb 28 09:53:54 2011 +0800 @@ -88,9 +88,7 @@ static void smp_store_cpu_info(int id) { struct cpuinfo_x86 *c = cpu_data + id; - *c = boot_cpu_data; - if ( id != 0 ) - identify_cpu(c); + identify_cpu(c); /* Mask B, Pentium, but not Pentium MMX -- remember it, as it has bugs. */ if ( (c->x86_vendor == X86_VENDOR_INTEL) && ----------------------------------------- Thanks, Jinsong Keir Fraser wrote:> On 18/03/2011 15:07, "Jan Beulich" <JBeulich@novell.com> wrote: > >> While c/s 22964:f71212f712fd and 23051:93c864c16ab1 fixed issues with >> CPU onlining, they introduced a problem with resume: mcheck_init() is >> also being called on that path, and hence checking whether it''s >> running on CPU 0, which is generally not a really good thing, is >> particularly inappropriate here. > > Just have a ''static bool_t early_init_done'' or similar in > intel_mcheck_init(). > > if ( !early_init_done ) { > BUG_ON(smp_processor_id() != 0); > ... > early_init_done = 1; > } > > It''s clearer anyway -- we''re simply protecting one-time-only > early-boot-time initialisation stuff. > > -- Keir > >> Signed-off-by: Jan Beulich <jbeulich@novell.com> >> >> --- a/xen/arch/x86/acpi/power.c >> +++ b/xen/arch/x86/acpi/power.c >> @@ -187,7 +187,7 @@ static int enter_state(u32 state) >> >> device_power_up(); >> >> - mcheck_init(&boot_cpu_data); >> + mcheck_init(&boot_cpu_data, 0); >> write_cr4(cr4); >> >> printk(XENLOG_INFO "Finishing wakeup from ACPI S%d state.\n", >> state); --- a/xen/arch/x86/cpu/common.c >> +++ b/xen/arch/x86/cpu/common.c >> @@ -431,19 +431,13 @@ void __cpuinit identify_cpu(struct cpuin >> /* AND the already accumulated flags with these */ >> for ( i = 0 ; i < NCAPINTS ; i++ ) >> boot_cpu_data.x86_capability[i] &= c->x86_capability[i]; >> - } >> - >> - /* Init Machine Check Exception if available. */ >> - mcheck_init(c); >> >> -#if 0 >> - if (c == &boot_cpu_data) >> - sysenter_setup(); >> - enable_sep_cpu(); >> -#endif >> + mcheck_init(c, 0); >> + } else { >> + mcheck_init(c, 1); >> >> - if (c == &boot_cpu_data) >> mtrr_bp_init(); >> + } >> } >> >> /* cpuid returns the value latched in the HW at reset, not the APIC >> ID --- a/xen/arch/x86/cpu/mcheck/mce.c >> +++ b/xen/arch/x86/cpu/mcheck/mce.c >> @@ -793,7 +793,7 @@ static struct notifier_block cpu_nfb = { }; >> >> /* This has to be run for each processor */ >> -void mcheck_init(struct cpuinfo_x86 *c) >> +void mcheck_init(struct cpuinfo_x86 *c, bool_t bsp) { >> enum mcheck_type inited = mcheck_none; >> >> @@ -822,7 +822,7 @@ void mcheck_init(struct cpuinfo_x86 *c) >> switch (c->x86) { case 6: >> case 15: >> - inited = intel_mcheck_init(c); >> + inited = intel_mcheck_init(c, bsp); >> break; >> } >> break; >> @@ -844,7 +844,7 @@ void mcheck_init(struct cpuinfo_x86 *c) /* >> Turn on MCE now */ set_in_cr4(X86_CR4_MCE); >> >> - if ( smp_processor_id() == 0 ) >> + if ( bsp ) >> { >> /* Early MCE initialisation for BSP. */ >> if ( cpu_poll_bankmask_alloc(0) ) >> --- a/xen/arch/x86/cpu/mcheck/mce.h >> +++ b/xen/arch/x86/cpu/mcheck/mce.h >> @@ -42,7 +42,7 @@ enum mcheck_type amd_k7_mcheck_init(stru >> enum mcheck_type amd_k8_mcheck_init(struct cpuinfo_x86 *c); >> enum mcheck_type amd_f10_mcheck_init(struct cpuinfo_x86 *c); >> >> -enum mcheck_type intel_mcheck_init(struct cpuinfo_x86 *c); >> +enum mcheck_type intel_mcheck_init(struct cpuinfo_x86 *c, bool_t >> bsp); >> >> void intel_mcheck_timer(struct cpuinfo_x86 *c); >> void mce_intel_feature_init(struct cpuinfo_x86 *c); >> --- a/xen/arch/x86/cpu/mcheck/mce_intel.c >> +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c >> @@ -1297,9 +1297,9 @@ static struct notifier_block cpu_nfb = { }; >> >> /* p4/p6 family have similar MCA initialization process */ >> -enum mcheck_type intel_mcheck_init(struct cpuinfo_x86 *c) >> +enum mcheck_type intel_mcheck_init(struct cpuinfo_x86 *c, bool_t >> bsp) { - if ( smp_processor_id() == 0 ) >> + if ( bsp ) >> { >> /* Early MCE initialisation for BSP. */ >> if ( cpu_mcabank_alloc(0) ) >> --- a/xen/include/asm-x86/processor.h >> +++ b/xen/include/asm-x86/processor.h >> @@ -555,7 +555,7 @@ void compat_show_guest_stack(struct vcpu >> extern void mtrr_ap_init(void); >> extern void mtrr_bp_init(void); >> >> -void mcheck_init(struct cpuinfo_x86 *c); >> +void mcheck_init(struct cpuinfo_x86 *c, bool_t bsp); >> >> #define DECLARE_TRAP_HANDLER(_name) \ >> asmlinkage void _name(void); \ >> >> >> >> _______________________________________________ >> Xen-devel mailing list >> Xen-devel@lists.xensource.com >> http://lists.xensource.com/xen-devel_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2011-Mar-19 22:20 UTC
Re: [Xen-devel] [PATCH] x86/mce: CPU notifiers must not be registered a second time during resume
I checked in Jan''s patch as it is more suitable for 4.1 anyway, compared with moving do_presmp_initcalls(). We could consider replacing it with your approach below in xen-unstable however. If it makes the ordering of setup closer to that in Linux, that would probably be a good thing. -- Keir On 19/03/2011 15:53, "Liu, Jinsong" <jinsong.liu@intel.com> wrote:> Thanks Jan and Keir! > Sorry for late check email at weekend. > > I think a while, how about following solution (draft scheme): > ----------------------------------------------- > 1. at mce_intel.c, keep old intel_mce_initcall() func (it has been removed at > c/s 22964), and do > > --- a/xen/arch/x86/cpu/mcheck/mce_intel.c Fri Feb 25 01:26:01 2011 +0800 > +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c Mon Feb 28 19:19:20 2011 +0800 > static int __init intel_mce_initcall(void) > { > + void *hcpu = (void *)(long)smp_processor_id(); > + cpu_callback(&cpu_nfb, CPU_UP_PREPARE, hcpu); > register_cpu_notifier(&cpu_nfb); > return 0; > } > ----------------------------------------------- > 2. at setup.c, do_presmp_initcalls() at little bit earlier > > diff -r 1a364b17d66a xen/arch/x86/setup.c > --- a/xen/arch/x86/setup.c Fri Feb 25 01:26:01 2011 +0800 > +++ b/xen/arch/x86/setup.c Mon Feb 28 19:19:20 2011 +0800 > @@ -1203,6 +1203,8 @@ void __init __start_xen(unsigned long mb > > arch_init_memory(); > > + do_presmp_initcalls(); > + > identify_cpu(&boot_cpu_data); > if ( cpu_has_fxsr ) > set_in_cr4(X86_CR4_OSFXSR); > @@ -1235,8 +1237,6 @@ void __init __start_xen(unsigned long mb > initialize_keytable(); > > console_init_postirq(); > - > - do_presmp_initcalls(); > > for_each_present_cpu ( i ) > ----------------------------------------------- > > How do you think? it don''t need to add bsp para to mcheck_int() as > -void mcheck_init(struct cpuinfo_x86 *c) > +void mcheck_init(struct cpuinfo_x86 *c, bool_t bsp) > > BTW, it can go further to unify cpu0 and cpux, like: > ---------------------------------------------- > diff -r 682880e909db xen/arch/x86/setup.c > --- a/xen/arch/x86/setup.c Mon Feb 28 09:17:40 2011 +0800 > +++ b/xen/arch/x86/setup.c Mon Feb 28 09:53:54 2011 +0800 > @@ -1205,7 +1205,8 @@ void __init __start_xen(unsigned long mb > > do_presmp_initcalls(); > > - identify_cpu(&boot_cpu_data); > + smp_prepare_cpus(max_cpus); > + boot_cpu_data = cpu_data[0]; > if ( cpu_has_fxsr ) > set_in_cr4(X86_CR4_OSFXSR); > if ( cpu_has_xmm ) > @@ -1221,8 +1222,6 @@ void __init __start_xen(unsigned long mb > max_cpus = 0; > > iommu_setup(); /* setup iommu if available */ > - > - smp_prepare_cpus(max_cpus); > > spin_debug_enable(); > > diff -r 682880e909db xen/arch/x86/smpboot.c > --- a/xen/arch/x86/smpboot.c Mon Feb 28 09:17:40 2011 +0800 > +++ b/xen/arch/x86/smpboot.c Mon Feb 28 09:53:54 2011 +0800 > @@ -88,9 +88,7 @@ static void smp_store_cpu_info(int id) > { > struct cpuinfo_x86 *c = cpu_data + id; > > - *c = boot_cpu_data; > - if ( id != 0 ) > - identify_cpu(c); > + identify_cpu(c); > > /* Mask B, Pentium, but not Pentium MMX -- remember it, as it has bugs. > */ > if ( (c->x86_vendor == X86_VENDOR_INTEL) && > ----------------------------------------- > > > Thanks, > Jinsong > > > > Keir Fraser wrote: >> On 18/03/2011 15:07, "Jan Beulich" <JBeulich@novell.com> wrote: >> >>> While c/s 22964:f71212f712fd and 23051:93c864c16ab1 fixed issues with >>> CPU onlining, they introduced a problem with resume: mcheck_init() is >>> also being called on that path, and hence checking whether it''s >>> running on CPU 0, which is generally not a really good thing, is >>> particularly inappropriate here. >> >> Just have a ''static bool_t early_init_done'' or similar in >> intel_mcheck_init(). >> >> if ( !early_init_done ) { >> BUG_ON(smp_processor_id() != 0); >> ... >> early_init_done = 1; >> } >> >> It''s clearer anyway -- we''re simply protecting one-time-only >> early-boot-time initialisation stuff. >> >> -- Keir >> >>> Signed-off-by: Jan Beulich <jbeulich@novell.com> >>> >>> --- a/xen/arch/x86/acpi/power.c >>> +++ b/xen/arch/x86/acpi/power.c >>> @@ -187,7 +187,7 @@ static int enter_state(u32 state) >>> >>> device_power_up(); >>> >>> - mcheck_init(&boot_cpu_data); >>> + mcheck_init(&boot_cpu_data, 0); >>> write_cr4(cr4); >>> >>> printk(XENLOG_INFO "Finishing wakeup from ACPI S%d state.\n", >>> state); --- a/xen/arch/x86/cpu/common.c >>> +++ b/xen/arch/x86/cpu/common.c >>> @@ -431,19 +431,13 @@ void __cpuinit identify_cpu(struct cpuin >>> /* AND the already accumulated flags with these */ >>> for ( i = 0 ; i < NCAPINTS ; i++ ) >>> boot_cpu_data.x86_capability[i] &= c->x86_capability[i]; >>> - } >>> - >>> - /* Init Machine Check Exception if available. */ >>> - mcheck_init(c); >>> >>> -#if 0 >>> - if (c == &boot_cpu_data) >>> - sysenter_setup(); >>> - enable_sep_cpu(); >>> -#endif >>> + mcheck_init(c, 0); >>> + } else { >>> + mcheck_init(c, 1); >>> >>> - if (c == &boot_cpu_data) >>> mtrr_bp_init(); >>> + } >>> } >>> >>> /* cpuid returns the value latched in the HW at reset, not the APIC >>> ID --- a/xen/arch/x86/cpu/mcheck/mce.c >>> +++ b/xen/arch/x86/cpu/mcheck/mce.c >>> @@ -793,7 +793,7 @@ static struct notifier_block cpu_nfb = { }; >>> >>> /* This has to be run for each processor */ >>> -void mcheck_init(struct cpuinfo_x86 *c) >>> +void mcheck_init(struct cpuinfo_x86 *c, bool_t bsp) { >>> enum mcheck_type inited = mcheck_none; >>> >>> @@ -822,7 +822,7 @@ void mcheck_init(struct cpuinfo_x86 *c) >>> switch (c->x86) { case 6: >>> case 15: >>> - inited = intel_mcheck_init(c); >>> + inited = intel_mcheck_init(c, bsp); >>> break; >>> } >>> break; >>> @@ -844,7 +844,7 @@ void mcheck_init(struct cpuinfo_x86 *c) /* >>> Turn on MCE now */ set_in_cr4(X86_CR4_MCE); >>> >>> - if ( smp_processor_id() == 0 ) >>> + if ( bsp ) >>> { >>> /* Early MCE initialisation for BSP. */ >>> if ( cpu_poll_bankmask_alloc(0) ) >>> --- a/xen/arch/x86/cpu/mcheck/mce.h >>> +++ b/xen/arch/x86/cpu/mcheck/mce.h >>> @@ -42,7 +42,7 @@ enum mcheck_type amd_k7_mcheck_init(stru >>> enum mcheck_type amd_k8_mcheck_init(struct cpuinfo_x86 *c); >>> enum mcheck_type amd_f10_mcheck_init(struct cpuinfo_x86 *c); >>> >>> -enum mcheck_type intel_mcheck_init(struct cpuinfo_x86 *c); >>> +enum mcheck_type intel_mcheck_init(struct cpuinfo_x86 *c, bool_t >>> bsp); >>> >>> void intel_mcheck_timer(struct cpuinfo_x86 *c); >>> void mce_intel_feature_init(struct cpuinfo_x86 *c); >>> --- a/xen/arch/x86/cpu/mcheck/mce_intel.c >>> +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c >>> @@ -1297,9 +1297,9 @@ static struct notifier_block cpu_nfb = { }; >>> >>> /* p4/p6 family have similar MCA initialization process */ >>> -enum mcheck_type intel_mcheck_init(struct cpuinfo_x86 *c) >>> +enum mcheck_type intel_mcheck_init(struct cpuinfo_x86 *c, bool_t >>> bsp) { - if ( smp_processor_id() == 0 ) >>> + if ( bsp ) >>> { >>> /* Early MCE initialisation for BSP. */ >>> if ( cpu_mcabank_alloc(0) ) >>> --- a/xen/include/asm-x86/processor.h >>> +++ b/xen/include/asm-x86/processor.h >>> @@ -555,7 +555,7 @@ void compat_show_guest_stack(struct vcpu >>> extern void mtrr_ap_init(void); >>> extern void mtrr_bp_init(void); >>> >>> -void mcheck_init(struct cpuinfo_x86 *c); >>> +void mcheck_init(struct cpuinfo_x86 *c, bool_t bsp); >>> >>> #define DECLARE_TRAP_HANDLER(_name) \ >>> asmlinkage void _name(void); \ >>> >>> >>> >>> _______________________________________________ >>> Xen-devel mailing list >>> Xen-devel@lists.xensource.com >>> http://lists.xensource.com/xen-devel >_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jan Beulich
2011-Mar-21 08:22 UTC
RE: [Xen-devel] [PATCH] x86/mce: CPU notifiers must not be registered a second time during resume
>>> On 19.03.11 at 16:53, "Liu, Jinsong" <jinsong.liu@intel.com> wrote: > Thanks Jan and Keir! > Sorry for late check email at weekend. > > I think a while, how about following solution (draft scheme): > ----------------------------------------------- > 1. at mce_intel.c, keep old intel_mce_initcall() func (it has been removed > at c/s 22964), and do > > --- a/xen/arch/x86/cpu/mcheck/mce_intel.c Fri Feb 25 01:26:01 2011 +0800 > +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c Mon Feb 28 19:19:20 2011 +0800 > static int __init intel_mce_initcall(void) > { > + void *hcpu = (void *)(long)smp_processor_id(); > + cpu_callback(&cpu_nfb, CPU_UP_PREPARE, hcpu); > register_cpu_notifier(&cpu_nfb); > return 0; > }This one may be an option, though it then is unclear to me why you removed it in 22694.> ----------------------------------------------- > 2. at setup.c, do_presmp_initcalls() at little bit earlier > > diff -r 1a364b17d66a xen/arch/x86/setup.c > --- a/xen/arch/x86/setup.c Fri Feb 25 01:26:01 2011 +0800 > +++ b/xen/arch/x86/setup.c Mon Feb 28 19:19:20 2011 +0800 > @@ -1203,6 +1203,8 @@ void __init __start_xen(unsigned long mb > > arch_init_memory(); > > + do_presmp_initcalls(); > + > identify_cpu(&boot_cpu_data); > if ( cpu_has_fxsr ) > set_in_cr4(X86_CR4_OSFXSR); > @@ -1235,8 +1237,6 @@ void __init __start_xen(unsigned long mb > initialize_keytable(); > > console_init_postirq(); > - > - do_presmp_initcalls(); > > for_each_present_cpu ( i ) > -----------------------------------------------This one I don''t like at all - pre-SMP init calls ought to be allowed to assume identify_cpu() was run. Further, I wouldn''t really like to see anything sufficiently generic being pushed ahead of (the final step of) console initialization.> How do you think? it don''t need to add bsp para to mcheck_int() as > -void mcheck_init(struct cpuinfo_x86 *c) > +void mcheck_init(struct cpuinfo_x86 *c, bool_t bsp) > > BTW, it can go further to unify cpu0 and cpux, like: > ---------------------------------------------- > diff -r 682880e909db xen/arch/x86/setup.c > --- a/xen/arch/x86/setup.c Mon Feb 28 09:17:40 2011 +0800 > +++ b/xen/arch/x86/setup.c Mon Feb 28 09:53:54 2011 +0800 > @@ -1205,7 +1205,8 @@ void __init __start_xen(unsigned long mb > > do_presmp_initcalls(); > > - identify_cpu(&boot_cpu_data); > + smp_prepare_cpus(max_cpus); > + boot_cpu_data = cpu_data[0]; > if ( cpu_has_fxsr ) > set_in_cr4(X86_CR4_OSFXSR); > if ( cpu_has_xmm ) > @@ -1221,8 +1222,6 @@ void __init __start_xen(unsigned long mb > max_cpus = 0; > > iommu_setup(); /* setup iommu if available */ > - > - smp_prepare_cpus(max_cpus); > > spin_debug_enable(); >Here as well I''m not sure this wouldn''t have any bad side effects. Overall, trying to also answer Keir''s subsequent question, I don''t think this gets us any closer to Linux - I think it''d be more of the opposite. Jan _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Liu, Jinsong
2011-Mar-21 13:18 UTC
RE: [Xen-devel] [PATCH] x86/mce: CPU notifiers must not be registered a second time during resume
Jan Beulich wrote:>>>> On 19.03.11 at 16:53, "Liu, Jinsong" <jinsong.liu@intel.com> wrote: >> Thanks Jan and Keir! >> Sorry for late check email at weekend. >> >> I think a while, how about following solution (draft scheme): >> ----------------------------------------------- >> 1. at mce_intel.c, keep old intel_mce_initcall() func (it has been >> removed at c/s 22964), and do >> >> --- a/xen/arch/x86/cpu/mcheck/mce_intel.c Fri Feb 25 01:26:01 2011 >> +0800 +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c Mon Feb 28 19:19:20 >> 2011 +0800 static int __init intel_mce_initcall(void) >> { >> + void *hcpu = (void *)(long)smp_processor_id(); >> + cpu_callback(&cpu_nfb, CPU_UP_PREPARE, hcpu); >> register_cpu_notifier(&cpu_nfb); >> return 0; >> } > > This one may be an option, though it then is unclear to me why > you removed it in 22694.It would alloc redundant mcabanks when using AMD platform.> >> ----------------------------------------------- >> 2. at setup.c, do_presmp_initcalls() at little bit earlier >> >> diff -r 1a364b17d66a xen/arch/x86/setup.c >> --- a/xen/arch/x86/setup.c Fri Feb 25 01:26:01 2011 +0800 >> +++ b/xen/arch/x86/setup.c Mon Feb 28 19:19:20 2011 +0800 >> @@ -1203,6 +1203,8 @@ void __init __start_xen(unsigned long mb >> >> arch_init_memory(); >> >> + do_presmp_initcalls(); >> + >> identify_cpu(&boot_cpu_data); >> if ( cpu_has_fxsr ) >> set_in_cr4(X86_CR4_OSFXSR); >> @@ -1235,8 +1237,6 @@ void __init __start_xen(unsigned long mb >> initialize_keytable(); >> >> console_init_postirq(); >> - >> - do_presmp_initcalls(); >> >> for_each_present_cpu ( i ) >> ----------------------------------------------- > > This one I don''t like at all - pre-SMP init calls ought to be allowed > to assume identify_cpu() was run. > > Further, I wouldn''t really like to see anything sufficiently generic > being pushed ahead of (the final step of) console initialization.Agree.> >> How do you think? it don''t need to add bsp para to mcheck_int() as >> -void mcheck_init(struct cpuinfo_x86 *c) >> +void mcheck_init(struct cpuinfo_x86 *c, bool_t bsp) >> >> BTW, it can go further to unify cpu0 and cpux, like: >> ---------------------------------------------- >> diff -r 682880e909db xen/arch/x86/setup.c >> --- a/xen/arch/x86/setup.c Mon Feb 28 09:17:40 2011 +0800 >> +++ b/xen/arch/x86/setup.c Mon Feb 28 09:53:54 2011 +0800 >> @@ -1205,7 +1205,8 @@ void __init __start_xen(unsigned long mb >> >> do_presmp_initcalls(); >> >> - identify_cpu(&boot_cpu_data); >> + smp_prepare_cpus(max_cpus); >> + boot_cpu_data = cpu_data[0]; >> if ( cpu_has_fxsr ) >> set_in_cr4(X86_CR4_OSFXSR); >> if ( cpu_has_xmm ) >> @@ -1221,8 +1222,6 @@ void __init __start_xen(unsigned long mb >> max_cpus = 0; >> >> iommu_setup(); /* setup iommu if available */ - >> - smp_prepare_cpus(max_cpus); >> >> spin_debug_enable(); >> > > Here as well I''m not sure this wouldn''t have any bad side effects. > > Overall, trying to also answer Keir''s subsequent question, I don''t > think this gets us any closer to Linux - I think it''d be more of the > opposite. > > JanReasonable to me, move do_presmp_initcall aheah is of some risk. Let''s keep current way. Thanks, Jinsong _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel