mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-20 02:34:23 +08:00
38e760a133
Add missing IRQs and IRQ descriptions to /proc/interrupts. /proc/interrupts is most useful when it displays every IRQ vector in use by the system, not just those somebody thought would be interesting. This patch inserts the following vector displays to the i386 and x86_64 platforms, as appropriate: rescheduling interrupts TLB flush interrupts function call interrupts thermal event interrupts threshold interrupts spurious interrupts A threshold interrupt occurs when ECC memory correction is occuring at too high a frequency. Thresholds are used by the ECC hardware as occasional ECC failures are part of normal operation, but long sequences of ECC failures usually indicate a memory chip that is about to fail. Thermal event interrupts occur when a temperature threshold has been exceeded for some CPU chip. IIRC, a thermal interrupt is also generated when the temperature drops back to a normal level. A spurious interrupt is an interrupt that was raised then lowered by the device before it could be fully processed by the APIC. Hence the apic sees the interrupt but does not know what device it came from. For this case the APIC hardware will assume a vector of 0xff. Rescheduling, call, and TLB flush interrupts are sent from one CPU to another per the needs of the OS. Typically, their statistics would be used to discover if an interrupt flood of the given type has been occuring. AK: merged v2 and v4 which had some more tweaks AK: replace Local interrupts with Local timer interrupts AK: Fixed description of interrupt types. [ tglx: arch/x86 adaptation ] [ mingo: small cleanup ] Signed-off-by: Joe Korty <joe.korty@ccur.com> Signed-off-by: Andi Kleen <ak@suse.de> Cc: Tim Hockin <thockin@hockin.org> Cc: Andi Kleen <ak@suse.de> Cc: Ingo Molnar <mingo@elte.hu> Cc: "H. Peter Anvin" <hpa@zytor.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
91 lines
2.1 KiB
C
91 lines
2.1 KiB
C
/*
|
|
* Intel specific MCE features.
|
|
* Copyright 2004 Zwane Mwaikambo <zwane@linuxpower.ca>
|
|
*/
|
|
|
|
#include <linux/init.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/percpu.h>
|
|
#include <asm/processor.h>
|
|
#include <asm/msr.h>
|
|
#include <asm/mce.h>
|
|
#include <asm/hw_irq.h>
|
|
#include <asm/idle.h>
|
|
#include <asm/therm_throt.h>
|
|
|
|
asmlinkage void smp_thermal_interrupt(void)
|
|
{
|
|
__u64 msr_val;
|
|
|
|
ack_APIC_irq();
|
|
|
|
exit_idle();
|
|
irq_enter();
|
|
|
|
rdmsrl(MSR_IA32_THERM_STATUS, msr_val);
|
|
if (therm_throt_process(msr_val & 1))
|
|
mce_log_therm_throt_event(smp_processor_id(), msr_val);
|
|
|
|
add_pda(irq_thermal_count, 1);
|
|
irq_exit();
|
|
}
|
|
|
|
static void __cpuinit intel_init_thermal(struct cpuinfo_x86 *c)
|
|
{
|
|
u32 l, h;
|
|
int tm2 = 0;
|
|
unsigned int cpu = smp_processor_id();
|
|
|
|
if (!cpu_has(c, X86_FEATURE_ACPI))
|
|
return;
|
|
|
|
if (!cpu_has(c, X86_FEATURE_ACC))
|
|
return;
|
|
|
|
/* first check if TM1 is already enabled by the BIOS, in which
|
|
* case there might be some SMM goo which handles it, so we can't even
|
|
* put a handler since it might be delivered via SMI already.
|
|
*/
|
|
rdmsr(MSR_IA32_MISC_ENABLE, l, h);
|
|
h = apic_read(APIC_LVTTHMR);
|
|
if ((l & (1 << 3)) && (h & APIC_DM_SMI)) {
|
|
printk(KERN_DEBUG
|
|
"CPU%d: Thermal monitoring handled by SMI\n", cpu);
|
|
return;
|
|
}
|
|
|
|
if (cpu_has(c, X86_FEATURE_TM2) && (l & (1 << 13)))
|
|
tm2 = 1;
|
|
|
|
if (h & APIC_VECTOR_MASK) {
|
|
printk(KERN_DEBUG
|
|
"CPU%d: Thermal LVT vector (%#x) already "
|
|
"installed\n", cpu, (h & APIC_VECTOR_MASK));
|
|
return;
|
|
}
|
|
|
|
h = THERMAL_APIC_VECTOR;
|
|
h |= (APIC_DM_FIXED | APIC_LVT_MASKED);
|
|
apic_write(APIC_LVTTHMR, h);
|
|
|
|
rdmsr(MSR_IA32_THERM_INTERRUPT, l, h);
|
|
wrmsr(MSR_IA32_THERM_INTERRUPT, l | 0x03, h);
|
|
|
|
rdmsr(MSR_IA32_MISC_ENABLE, l, h);
|
|
wrmsr(MSR_IA32_MISC_ENABLE, l | (1 << 3), h);
|
|
|
|
l = apic_read(APIC_LVTTHMR);
|
|
apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
|
|
printk(KERN_INFO "CPU%d: Thermal monitoring enabled (%s)\n",
|
|
cpu, tm2 ? "TM2" : "TM1");
|
|
|
|
/* enable thermal throttle processing */
|
|
atomic_set(&therm_throt_en, 1);
|
|
return;
|
|
}
|
|
|
|
void __cpuinit mce_intel_feature_init(struct cpuinfo_x86 *c)
|
|
{
|
|
intel_init_thermal(c);
|
|
}
|