[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Fix up the way we initialise and set the NMI heartbeat
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 026e5ef0aa3c8e1af5d70ab01ca4cbeb9c72a64d # Parent 903420e4d449433c30d9b623847b29b0c2c765bc Fix up the way we initialise and set the NMI heartbeat timers. Also, compund updates to APIC ICR and ICR2 registers must be done with interrupts disabled to ensure local atomicity. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> diff -r 903420e4d449 -r 026e5ef0aa3c xen/arch/x86/apic.c --- a/xen/arch/x86/apic.c Fri Jan 13 14:59:40 2006 +++ b/xen/arch/x86/apic.c Fri Jan 13 15:09:45 2006 @@ -451,7 +451,8 @@ printk("No ESR for 82489DX.\n"); } - setup_apic_nmi_watchdog(); + if (nmi_watchdog == NMI_LOCAL_APIC) + setup_apic_nmi_watchdog(); } /* diff -r 903420e4d449 -r 026e5ef0aa3c xen/arch/x86/nmi.c --- a/xen/arch/x86/nmi.c Fri Jan 13 14:59:40 2006 +++ b/xen/arch/x86/nmi.c Fri Jan 13 15:09:45 2006 @@ -33,10 +33,6 @@ #include <asm/apic.h> unsigned int nmi_watchdog = NMI_NONE; -static spinlock_t watchdog_lock = SPIN_LOCK_UNLOCKED; -static unsigned int watchdog_disable_count = 1; -static unsigned int watchdog_on; - static unsigned int nmi_hz = HZ; static unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */ static unsigned int nmi_p4_cccr_val; @@ -314,18 +310,8 @@ void __pminit setup_apic_nmi_watchdog(void) { - int cpu = smp_processor_id(); - - if ( nmi_active < 0 ) - return; - - if ( !nmi_watchdog ) - { - /* Force the watchdog to always be disabled. */ - watchdog_disable_count++; - nmi_active = -1; - return; - } + if (!nmi_watchdog) + return; switch (boot_cpu_data.x86_vendor) { case X86_VENDOR_AMD: @@ -358,45 +344,37 @@ lapic_nmi_owner = LAPIC_NMI_WATCHDOG; nmi_active = 1; - - init_timer(&nmi_timer[cpu], nmi_timer_fn, NULL, cpu); } static unsigned int last_irq_sums [NR_CPUS], alert_counter [NR_CPUS]; +static atomic_t watchdog_disable_count = ATOMIC_INIT(1); + void watchdog_disable(void) { - unsigned long flags; - - spin_lock_irqsave(&watchdog_lock, flags); - - if ( watchdog_disable_count++ == 0 ) - watchdog_on = 0; - - spin_unlock_irqrestore(&watchdog_lock, flags); + atomic_inc(&watchdog_disable_count); } void watchdog_enable(void) { - unsigned int cpu; - unsigned long flags; - - spin_lock_irqsave(&watchdog_lock, flags); - - if ( --watchdog_disable_count == 0 ) + static unsigned long heartbeat_initialised; + unsigned int cpu; + + if ( !atomic_dec_and_test(&watchdog_disable_count) || + test_and_set_bit(0, &heartbeat_initialised) ) + return; + + /* + * Activate periodic heartbeats. We cannot do this earlier during + * setup because the timer infrastructure is not available. + */ + for_each_online_cpu ( cpu ) { - watchdog_on = 1; - /* - * Ensure periodic heartbeats are active. We cannot do this earlier - * during setup because the timer infrastructure is not available. - */ - for_each_online_cpu ( cpu ) - set_timer(&nmi_timer[cpu], NOW()); - } - - spin_unlock_irqrestore(&watchdog_lock, flags); + init_timer(&nmi_timer[cpu], nmi_timer_fn, NULL, cpu); + set_timer(&nmi_timer[cpu], NOW()); + } } void nmi_watchdog_tick(struct cpu_user_regs * regs) @@ -405,7 +383,7 @@ sum = nmi_timer_ticks[cpu]; - if ( (last_irq_sums[cpu] == sum) && watchdog_on ) + if ( (last_irq_sums[cpu] == sum) && !atomic_read(&watchdog_disable_count) ) { /* * Ayiee, looks like this CPU is stuck ... wait a few IRQs (5 seconds) @@ -457,14 +435,17 @@ * 8-3 and 8-4 in IA32 Reference Manual Volume 3. We send the IPI to * our own APIC ID explicitly which is valid. */ -static void do_nmi_trigger(unsigned char key) { +static void do_nmi_trigger(unsigned char key) +{ u32 id = apic_read(APIC_ID); - printk("triggering NMI on APIC ID %x\n", id); - + printk("Triggering NMI on APIC ID %x\n", id); + + local_irq_disable(); apic_wait_icr_idle(); apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(id)); apic_write_around(APIC_ICR, APIC_DM_NMI | APIC_INT_ASSERT); + local_irq_enable(); } static __init int register_nmi_trigger(void) diff -r 903420e4d449 -r 026e5ef0aa3c xen/arch/x86/setup.c --- a/xen/arch/x86/setup.c Fri Jan 13 14:59:40 2006 +++ b/xen/arch/x86/setup.c Fri Jan 13 15:09:45 2006 @@ -478,7 +478,8 @@ schedulers_start(); - watchdog_enable(); + if ( opt_watchdog ) + watchdog_enable(); shadow_mode_init(); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |