From: Philippe Elie With nmi_watchdog=2 and a P4 ht box the nmi is occurring only on logical processor 0, it's better to get it on both. With this patch, on x86 SMP and nmi_watchdog=2, nmi interupts occur at 1000 hz (if the cpu is loaded) not at the intended 1 hz rate but that's a distinct problem. --- 25-akpm/arch/i386/kernel/nmi.c | 17 ++++++++++++----- 1 files changed, 12 insertions(+), 5 deletions(-) diff -puN arch/i386/kernel/nmi.c~nmi_watchdog-local-apic-fix arch/i386/kernel/nmi.c --- 25/arch/i386/kernel/nmi.c~nmi_watchdog-local-apic-fix Fri Mar 5 13:57:28 2004 +++ 25-akpm/arch/i386/kernel/nmi.c Fri Mar 5 13:57:28 2004 @@ -42,7 +42,8 @@ unsigned int nmi_watchdog = NMI_LOCAL_AP unsigned int nmi_watchdog = NMI_NONE; #endif static unsigned int nmi_hz = HZ; -unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */ +static unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */ +static unsigned int nmi_p4_cccr_val; extern void show_registers(struct pt_regs *regs); /* nmi_active: @@ -75,7 +76,8 @@ int nmi_active; #define P4_ESCR_EVENT_SELECT(N) ((N)<<25) #define P4_ESCR_OS (1<<3) #define P4_ESCR_USR (1<<2) -#define P4_CCCR_OVF_PMI (1<<26) +#define P4_CCCR_OVF_PMI0 (1<<26) +#define P4_CCCR_OVF_PMI1 (1<<27) #define P4_CCCR_THRESHOLD(N) ((N)<<20) #define P4_CCCR_COMPLEMENT (1<<19) #define P4_CCCR_COMPARE (1<<18) @@ -88,7 +90,7 @@ int nmi_active; #define MSR_P4_IQ_COUNTER0 0x30C #define P4_NMI_CRU_ESCR0 (P4_ESCR_EVENT_SELECT(0x3F)|P4_ESCR_OS|P4_ESCR_USR) #define P4_NMI_IQ_CCCR0 \ - (P4_CCCR_OVF_PMI|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \ + (P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \ P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE) int __init check_nmi_watchdog (void) @@ -331,6 +333,11 @@ static int setup_p4_watchdog(void) return 0; nmi_perfctr_msr = MSR_P4_IQ_COUNTER0; + nmi_p4_cccr_val = P4_NMI_IQ_CCCR0; +#ifdef CONFIG_SMP + if (smp_num_siblings == 2) + nmi_p4_cccr_val |= P4_CCCR_OVF_PMI1; +#endif if (!(misc_enable & MSR_P4_MISC_ENABLE_PEBS_UNAVAIL)) clear_msr_range(0x3F1, 2); @@ -348,7 +355,7 @@ static int setup_p4_watchdog(void) Dprintk("setting P4_IQ_COUNTER0 to 0x%08lx\n", -(cpu_khz/nmi_hz*1000)); wrmsr(MSR_P4_IQ_COUNTER0, -(cpu_khz/nmi_hz*1000), -1); apic_write(APIC_LVTPC, APIC_DM_NMI); - wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0, 0); + wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); return 1; } @@ -479,7 +486,7 @@ void nmi_watchdog_tick (struct pt_regs * * - LVTPC is masked on interrupt and must be * unmasked by the LVTPC handler. */ - wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0, 0); + wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); apic_write(APIC_LVTPC, APIC_DM_NMI); } wrmsr(nmi_perfctr_msr, -(cpu_khz/nmi_hz*1000), -1); _