aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-09-22 09:50:24 -0400
committerIngo Molnar <mingo@elte.hu>2009-09-22 11:30:41 -0400
commit3967684006f30c253bc6d4a6604d1bad4a7fc672 (patch)
tree762eff17c78cb4399b39d5d754fc0540f3042483 /arch/x86
parentb8c7f1dc5ca4e0d10709182233cdab932cef593d (diff)
x86: mce: Clean up thermal throttling state tracking code
Instead of a mess of three separate percpu variables, consolidate the state into a single structure. Also clean up therm_throt_process(), use cleaner and more understandable variable names and a clearer logic. This, without changing the logic, makes the code more streamlined, more readable and smaller as well: text data bss dec hex filename 1487 169 4 1660 67c therm_throt.o.before 1432 176 4 1612 64c therm_throt.o.after Cc: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com> Cc: Huang Ying <ying.huang@intel.com> Cc: Andi Kleen <ak@linux.intel.com> LKML-Reference: <new-submission> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kernel/cpu/mcheck/therm_throt.c63
1 files changed, 39 insertions, 24 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c
index 63a56d147e4a..db80b577f601 100644
--- a/arch/x86/kernel/cpu/mcheck/therm_throt.c
+++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c
@@ -34,20 +34,30 @@
34/* How long to wait between reporting thermal events */ 34/* How long to wait between reporting thermal events */
35#define CHECK_INTERVAL (300 * HZ) 35#define CHECK_INTERVAL (300 * HZ)
36 36
37static DEFINE_PER_CPU(__u64, next_check) = INITIAL_JIFFIES; 37/*
38static DEFINE_PER_CPU(unsigned long, thermal_throttle_count); 38 * Current thermal throttling state:
39static DEFINE_PER_CPU(bool, thermal_throttle_active); 39 */
40struct thermal_state {
41 bool is_throttled;
42
43 u64 next_check;
44 unsigned long throttle_count;
45};
46
47static DEFINE_PER_CPU(struct thermal_state, thermal_state);
40 48
41static atomic_t therm_throt_en = ATOMIC_INIT(0); 49static atomic_t therm_throt_en = ATOMIC_INIT(0);
42 50
43#ifdef CONFIG_SYSFS 51#ifdef CONFIG_SYSFS
44#define define_therm_throt_sysdev_one_ro(_name) \ 52#define define_therm_throt_sysdev_one_ro(_name) \
45 static SYSDEV_ATTR(_name, 0444, therm_throt_sysdev_show_##_name, NULL) 53 static SYSDEV_ATTR(_name, 0444, therm_throt_sysdev_show_##_name, NULL)
46 54
47#define define_therm_throt_sysdev_show_func(name) \ 55#define define_therm_throt_sysdev_show_func(name) \
48static ssize_t therm_throt_sysdev_show_##name(struct sys_device *dev, \ 56 \
49 struct sysdev_attribute *attr, \ 57static ssize_t therm_throt_sysdev_show_##name( \
50 char *buf) \ 58 struct sys_device *dev, \
59 struct sysdev_attribute *attr, \
60 char *buf) \
51{ \ 61{ \
52 unsigned int cpu = dev->id; \ 62 unsigned int cpu = dev->id; \
53 ssize_t ret; \ 63 ssize_t ret; \
@@ -55,7 +65,7 @@ static ssize_t therm_throt_sysdev_show_##name(struct sys_device *dev, \
55 preempt_disable(); /* CPU hotplug */ \ 65 preempt_disable(); /* CPU hotplug */ \
56 if (cpu_online(cpu)) \ 66 if (cpu_online(cpu)) \
57 ret = sprintf(buf, "%lu\n", \ 67 ret = sprintf(buf, "%lu\n", \
58 per_cpu(thermal_throttle_##name, cpu)); \ 68 per_cpu(thermal_state, cpu).name); \
59 else \ 69 else \
60 ret = 0; \ 70 ret = 0; \
61 preempt_enable(); \ 71 preempt_enable(); \
@@ -63,11 +73,11 @@ static ssize_t therm_throt_sysdev_show_##name(struct sys_device *dev, \
63 return ret; \ 73 return ret; \
64} 74}
65 75
66define_therm_throt_sysdev_show_func(count); 76define_therm_throt_sysdev_show_func(throttle_count);
67define_therm_throt_sysdev_one_ro(count); 77define_therm_throt_sysdev_one_ro(throttle_count);
68 78
69static struct attribute *thermal_throttle_attrs[] = { 79static struct attribute *thermal_throttle_attrs[] = {
70 &attr_count.attr, 80 &attr_throttle_count.attr,
71 NULL 81 NULL
72}; 82};
73 83
@@ -93,33 +103,38 @@ static struct attribute_group thermal_throttle_attr_group = {
93 * 1 : Event should be logged further, and a message has been 103 * 1 : Event should be logged further, and a message has been
94 * printed to the syslog. 104 * printed to the syslog.
95 */ 105 */
96static int therm_throt_process(int curr) 106static int therm_throt_process(bool is_throttled)
97{ 107{
98 unsigned int cpu = smp_processor_id(); 108 struct thermal_state *state;
99 __u64 tmp_jiffs = get_jiffies_64(); 109 unsigned int this_cpu;
100 bool was_throttled = __get_cpu_var(thermal_throttle_active); 110 bool was_throttled;
101 bool is_throttled = __get_cpu_var(thermal_throttle_active) = curr; 111 u64 now;
112
113 this_cpu = smp_processor_id();
114 now = get_jiffies_64();
115 state = &per_cpu(thermal_state, this_cpu);
116
117 was_throttled = state->is_throttled;
118 state->is_throttled = is_throttled;
102 119
103 if (is_throttled) 120 if (is_throttled)
104 __get_cpu_var(thermal_throttle_count)++; 121 state->throttle_count++;
105 122
106 if (!(was_throttled ^ is_throttled) && 123 if (!(was_throttled ^ is_throttled) &&
107 time_before64(tmp_jiffs, __get_cpu_var(next_check))) 124 time_before64(now, state->next_check))
108 return 0; 125 return 0;
109 126
110 __get_cpu_var(next_check) = tmp_jiffs + CHECK_INTERVAL; 127 state->next_check = now + CHECK_INTERVAL;
111 128
112 /* if we just entered the thermal event */ 129 /* if we just entered the thermal event */
113 if (is_throttled) { 130 if (is_throttled) {
114 printk(KERN_CRIT "CPU%d: Temperature above threshold, " 131 printk(KERN_CRIT "CPU%d: Temperature above threshold, cpu clock throttled (total events = %lu)\n", this_cpu, state->throttle_count);
115 "cpu clock throttled (total events = %lu)\n",
116 cpu, __get_cpu_var(thermal_throttle_count));
117 132
118 add_taint(TAINT_MACHINE_CHECK); 133 add_taint(TAINT_MACHINE_CHECK);
119 return 1; 134 return 1;
120 } 135 }
121 if (was_throttled) { 136 if (was_throttled) {
122 printk(KERN_INFO "CPU%d: Temperature/speed normal\n", cpu); 137 printk(KERN_INFO "CPU%d: Temperature/speed normal\n", this_cpu);
123 return 1; 138 return 1;
124 } 139 }
125 140
@@ -213,7 +228,7 @@ static void intel_thermal_interrupt(void)
213 __u64 msr_val; 228 __u64 msr_val;
214 229
215 rdmsrl(MSR_IA32_THERM_STATUS, msr_val); 230 rdmsrl(MSR_IA32_THERM_STATUS, msr_val);
216 if (therm_throt_process(msr_val & THERM_STATUS_PROCHOT)) 231 if (therm_throt_process((msr_val & THERM_STATUS_PROCHOT) != 0))
217 mce_log_therm_throt_event(msr_val); 232 mce_log_therm_throt_event(msr_val);
218} 233}
219 234