diff options
author | Dmitriy Zavin <dmitriyz@google.com> | 2006-09-26 04:52:42 -0400 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2006-09-26 04:52:42 -0400 |
commit | 15d5f8398311f565682959daaca30e3ca7aea600 (patch) | |
tree | ba38e77782832191dd38e182e99525870f83c085 /arch/x86_64/kernel | |
parent | 3b171672831b9633c2ed8fa94805255cd4d5af19 (diff) |
[PATCH] x86: Refactor thermal throttle processing
Refactor the event processing (syslog messaging and rate limiting)
into separate file therm_throt.c. This allows consistent reporting
of CPU thermal throttle events.
After ACK'ing the interrupt, if the event is current, the user
(p4.c/mce_intel.c) calls therm_throt_process to log (and rate limit)
the event. If that function returns 1, the user has the option to log
things further (such as to mce_log in x86_64).
AK: minor cleanup
Signed-off-by: Dmitriy Zavin <dmitriyz@google.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch/x86_64/kernel')
-rw-r--r-- | arch/x86_64/kernel/Makefile | 4 | ||||
-rw-r--r-- | arch/x86_64/kernel/mce.c | 27 | ||||
-rw-r--r-- | arch/x86_64/kernel/mce_intel.c | 27 |
3 files changed, 35 insertions, 23 deletions
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile index 2466fbd035ee..3c7cbff04d3d 100644 --- a/arch/x86_64/kernel/Makefile +++ b/arch/x86_64/kernel/Makefile | |||
@@ -11,7 +11,7 @@ obj-y := process.o signal.o entry.o traps.o irq.o \ | |||
11 | pci-dma.o pci-nommu.o alternative.o | 11 | pci-dma.o pci-nommu.o alternative.o |
12 | 12 | ||
13 | obj-$(CONFIG_STACKTRACE) += stacktrace.o | 13 | obj-$(CONFIG_STACKTRACE) += stacktrace.o |
14 | obj-$(CONFIG_X86_MCE) += mce.o | 14 | obj-$(CONFIG_X86_MCE) += mce.o therm_throt.o |
15 | obj-$(CONFIG_X86_MCE_INTEL) += mce_intel.o | 15 | obj-$(CONFIG_X86_MCE_INTEL) += mce_intel.o |
16 | obj-$(CONFIG_X86_MCE_AMD) += mce_amd.o | 16 | obj-$(CONFIG_X86_MCE_AMD) += mce_amd.o |
17 | obj-$(CONFIG_MTRR) += ../../i386/kernel/cpu/mtrr/ | 17 | obj-$(CONFIG_MTRR) += ../../i386/kernel/cpu/mtrr/ |
@@ -46,6 +46,7 @@ obj-y += intel_cacheinfo.o | |||
46 | 46 | ||
47 | CFLAGS_vsyscall.o := $(PROFILING) -g0 | 47 | CFLAGS_vsyscall.o := $(PROFILING) -g0 |
48 | 48 | ||
49 | therm_throt-y += ../../i386/kernel/cpu/mcheck/therm_throt.o | ||
49 | bootflag-y += ../../i386/kernel/bootflag.o | 50 | bootflag-y += ../../i386/kernel/bootflag.o |
50 | cpuid-$(subst m,y,$(CONFIG_X86_CPUID)) += ../../i386/kernel/cpuid.o | 51 | cpuid-$(subst m,y,$(CONFIG_X86_CPUID)) += ../../i386/kernel/cpuid.o |
51 | topology-y += ../../i386/kernel/topology.o | 52 | topology-y += ../../i386/kernel/topology.o |
@@ -55,4 +56,3 @@ quirks-y += ../../i386/kernel/quirks.o | |||
55 | i8237-y += ../../i386/kernel/i8237.o | 56 | i8237-y += ../../i386/kernel/i8237.o |
56 | msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o | 57 | msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o |
57 | alternative-y += ../../i386/kernel/alternative.o | 58 | alternative-y += ../../i386/kernel/alternative.o |
58 | |||
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c index 1a93c3738404..bbea88801d88 100644 --- a/arch/x86_64/kernel/mce.c +++ b/arch/x86_64/kernel/mce.c | |||
@@ -274,6 +274,33 @@ void do_machine_check(struct pt_regs * regs, long error_code) | |||
274 | atomic_dec(&mce_entry); | 274 | atomic_dec(&mce_entry); |
275 | } | 275 | } |
276 | 276 | ||
277 | #ifdef CONFIG_X86_MCE_INTEL | ||
278 | /*** | ||
279 | * mce_log_therm_throt_event - Logs the thermal throttling event to mcelog | ||
280 | * @cpu: The CPU on which the event occured. | ||
281 | * @status: Event status information | ||
282 | * | ||
283 | * This function should be called by the thermal interrupt after the | ||
284 | * event has been processed and the decision was made to log the event | ||
285 | * further. | ||
286 | * | ||
287 | * The status parameter will be saved to the 'status' field of 'struct mce' | ||
288 | * and historically has been the register value of the | ||
289 | * MSR_IA32_THERMAL_STATUS (Intel) msr. | ||
290 | */ | ||
291 | void mce_log_therm_throt_event(unsigned int cpu, __u64 status) | ||
292 | { | ||
293 | struct mce m; | ||
294 | |||
295 | memset(&m, 0, sizeof(m)); | ||
296 | m.cpu = cpu; | ||
297 | m.bank = MCE_THERMAL_BANK; | ||
298 | m.status = status; | ||
299 | rdtscll(m.tsc); | ||
300 | mce_log(&m); | ||
301 | } | ||
302 | #endif /* CONFIG_X86_MCE_INTEL */ | ||
303 | |||
277 | /* | 304 | /* |
278 | * Periodic polling timer for "silent" machine check errors. | 305 | * Periodic polling timer for "silent" machine check errors. |
279 | */ | 306 | */ |
diff --git a/arch/x86_64/kernel/mce_intel.c b/arch/x86_64/kernel/mce_intel.c index 8f533d2c40cb..dec11219e278 100644 --- a/arch/x86_64/kernel/mce_intel.c +++ b/arch/x86_64/kernel/mce_intel.c | |||
@@ -11,36 +11,21 @@ | |||
11 | #include <asm/mce.h> | 11 | #include <asm/mce.h> |
12 | #include <asm/hw_irq.h> | 12 | #include <asm/hw_irq.h> |
13 | #include <asm/idle.h> | 13 | #include <asm/idle.h> |
14 | 14 | #include <asm/therm_throt.h> | |
15 | static DEFINE_PER_CPU(unsigned long, next_check); | ||
16 | 15 | ||
17 | asmlinkage void smp_thermal_interrupt(void) | 16 | asmlinkage void smp_thermal_interrupt(void) |
18 | { | 17 | { |
19 | struct mce m; | 18 | __u64 msr_val; |
20 | 19 | ||
21 | ack_APIC_irq(); | 20 | ack_APIC_irq(); |
22 | 21 | ||
23 | exit_idle(); | 22 | exit_idle(); |
24 | irq_enter(); | 23 | irq_enter(); |
25 | if (time_before(jiffies, __get_cpu_var(next_check))) | ||
26 | goto done; | ||
27 | |||
28 | __get_cpu_var(next_check) = jiffies + HZ*300; | ||
29 | memset(&m, 0, sizeof(m)); | ||
30 | m.cpu = smp_processor_id(); | ||
31 | m.bank = MCE_THERMAL_BANK; | ||
32 | rdtscll(m.tsc); | ||
33 | rdmsrl(MSR_IA32_THERM_STATUS, m.status); | ||
34 | if (m.status & 0x1) { | ||
35 | printk(KERN_EMERG | ||
36 | "CPU%d: Temperature above threshold, cpu clock throttled\n", m.cpu); | ||
37 | add_taint(TAINT_MACHINE_CHECK); | ||
38 | } else { | ||
39 | printk(KERN_EMERG "CPU%d: Temperature/speed normal\n", m.cpu); | ||
40 | } | ||
41 | 24 | ||
42 | mce_log(&m); | 25 | rdmsrl(MSR_IA32_THERM_STATUS, msr_val); |
43 | done: | 26 | if (therm_throt_process(msr_val & 1)) |
27 | mce_log_therm_throt_event(smp_processor_id(), msr_val); | ||
28 | |||
44 | irq_exit(); | 29 | irq_exit(); |
45 | } | 30 | } |
46 | 31 | ||