diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/therm_throt.c | 74 |
1 files changed, 39 insertions, 35 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c index d5ae2243f0b9..a2b5d7ddb19f 100644 --- a/arch/x86/kernel/cpu/mcheck/therm_throt.c +++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * | ||
3 | * Thermal throttle event support code (such as syslog messaging and rate | 2 | * Thermal throttle event support code (such as syslog messaging and rate |
4 | * limiting) that was factored out from x86_64 (mce_intel.c) and i386 (p4.c). | 3 | * limiting) that was factored out from x86_64 (mce_intel.c) and i386 (p4.c). |
4 | * | ||
5 | * This allows consistent reporting of CPU thermal throttle events. | 5 | * This allows consistent reporting of CPU thermal throttle events. |
6 | * | 6 | * |
7 | * Maintains a counter in /sys that keeps track of the number of thermal | 7 | * Maintains a counter in /sys that keeps track of the number of thermal |
@@ -13,43 +13,44 @@ | |||
13 | * Credits: Adapted from Zwane Mwaikambo's original code in mce_intel.c. | 13 | * Credits: Adapted from Zwane Mwaikambo's original code in mce_intel.c. |
14 | * Inspired by Ross Biro's and Al Borchers' counter code. | 14 | * Inspired by Ross Biro's and Al Borchers' counter code. |
15 | */ | 15 | */ |
16 | 16 | #include <linux/notifier.h> | |
17 | #include <linux/jiffies.h> | ||
17 | #include <linux/percpu.h> | 18 | #include <linux/percpu.h> |
18 | #include <linux/sysdev.h> | 19 | #include <linux/sysdev.h> |
19 | #include <linux/cpu.h> | 20 | #include <linux/cpu.h> |
20 | #include <asm/cpu.h> | 21 | |
21 | #include <linux/notifier.h> | ||
22 | #include <linux/jiffies.h> | ||
23 | #include <asm/therm_throt.h> | 22 | #include <asm/therm_throt.h> |
23 | #include <asm/cpu.h> | ||
24 | 24 | ||
25 | /* How long to wait between reporting thermal events */ | 25 | /* How long to wait between reporting thermal events */ |
26 | #define CHECK_INTERVAL (300 * HZ) | 26 | #define CHECK_INTERVAL (300 * HZ) |
27 | 27 | ||
28 | static DEFINE_PER_CPU(__u64, next_check) = INITIAL_JIFFIES; | 28 | static DEFINE_PER_CPU(__u64, next_check) = INITIAL_JIFFIES; |
29 | static DEFINE_PER_CPU(unsigned long, thermal_throttle_count); | 29 | static DEFINE_PER_CPU(unsigned long, thermal_throttle_count); |
30 | atomic_t therm_throt_en = ATOMIC_INIT(0); | 30 | |
31 | atomic_t therm_throt_en = ATOMIC_INIT(0); | ||
31 | 32 | ||
32 | #ifdef CONFIG_SYSFS | 33 | #ifdef CONFIG_SYSFS |
33 | #define define_therm_throt_sysdev_one_ro(_name) \ | 34 | #define define_therm_throt_sysdev_one_ro(_name) \ |
34 | static SYSDEV_ATTR(_name, 0444, therm_throt_sysdev_show_##_name, NULL) | 35 | static SYSDEV_ATTR(_name, 0444, therm_throt_sysdev_show_##_name, NULL) |
35 | 36 | ||
36 | #define define_therm_throt_sysdev_show_func(name) \ | 37 | #define define_therm_throt_sysdev_show_func(name) \ |
37 | static ssize_t therm_throt_sysdev_show_##name(struct sys_device *dev, \ | 38 | static ssize_t therm_throt_sysdev_show_##name(struct sys_device *dev, \ |
38 | struct sysdev_attribute *attr, \ | 39 | struct sysdev_attribute *attr, \ |
39 | char *buf) \ | 40 | char *buf) \ |
40 | { \ | 41 | { \ |
41 | unsigned int cpu = dev->id; \ | 42 | unsigned int cpu = dev->id; \ |
42 | ssize_t ret; \ | 43 | ssize_t ret; \ |
43 | \ | 44 | \ |
44 | preempt_disable(); /* CPU hotplug */ \ | 45 | preempt_disable(); /* CPU hotplug */ \ |
45 | if (cpu_online(cpu)) \ | 46 | if (cpu_online(cpu)) \ |
46 | ret = sprintf(buf, "%lu\n", \ | 47 | ret = sprintf(buf, "%lu\n", \ |
47 | per_cpu(thermal_throttle_##name, cpu)); \ | 48 | per_cpu(thermal_throttle_##name, cpu)); \ |
48 | else \ | 49 | else \ |
49 | ret = 0; \ | 50 | ret = 0; \ |
50 | preempt_enable(); \ | 51 | preempt_enable(); \ |
51 | \ | 52 | \ |
52 | return ret; \ | 53 | return ret; \ |
53 | } | 54 | } |
54 | 55 | ||
55 | define_therm_throt_sysdev_show_func(count); | 56 | define_therm_throt_sysdev_show_func(count); |
@@ -61,8 +62,8 @@ static struct attribute *thermal_throttle_attrs[] = { | |||
61 | }; | 62 | }; |
62 | 63 | ||
63 | static struct attribute_group thermal_throttle_attr_group = { | 64 | static struct attribute_group thermal_throttle_attr_group = { |
64 | .attrs = thermal_throttle_attrs, | 65 | .attrs = thermal_throttle_attrs, |
65 | .name = "thermal_throttle" | 66 | .name = "thermal_throttle" |
66 | }; | 67 | }; |
67 | #endif /* CONFIG_SYSFS */ | 68 | #endif /* CONFIG_SYSFS */ |
68 | 69 | ||
@@ -110,10 +111,11 @@ int therm_throt_process(int curr) | |||
110 | } | 111 | } |
111 | 112 | ||
112 | #ifdef CONFIG_SYSFS | 113 | #ifdef CONFIG_SYSFS |
113 | /* Add/Remove thermal_throttle interface for CPU device */ | 114 | /* Add/Remove thermal_throttle interface for CPU device: */ |
114 | static __cpuinit int thermal_throttle_add_dev(struct sys_device *sys_dev) | 115 | static __cpuinit int thermal_throttle_add_dev(struct sys_device *sys_dev) |
115 | { | 116 | { |
116 | return sysfs_create_group(&sys_dev->kobj, &thermal_throttle_attr_group); | 117 | return sysfs_create_group(&sys_dev->kobj, |
118 | &thermal_throttle_attr_group); | ||
117 | } | 119 | } |
118 | 120 | ||
119 | static __cpuinit void thermal_throttle_remove_dev(struct sys_device *sys_dev) | 121 | static __cpuinit void thermal_throttle_remove_dev(struct sys_device *sys_dev) |
@@ -121,19 +123,21 @@ static __cpuinit void thermal_throttle_remove_dev(struct sys_device *sys_dev) | |||
121 | sysfs_remove_group(&sys_dev->kobj, &thermal_throttle_attr_group); | 123 | sysfs_remove_group(&sys_dev->kobj, &thermal_throttle_attr_group); |
122 | } | 124 | } |
123 | 125 | ||
124 | /* Mutex protecting device creation against CPU hotplug */ | 126 | /* Mutex protecting device creation against CPU hotplug: */ |
125 | static DEFINE_MUTEX(therm_cpu_lock); | 127 | static DEFINE_MUTEX(therm_cpu_lock); |
126 | 128 | ||
127 | /* Get notified when a cpu comes on/off. Be hotplug friendly. */ | 129 | /* Get notified when a cpu comes on/off. Be hotplug friendly. */ |
128 | static __cpuinit int thermal_throttle_cpu_callback(struct notifier_block *nfb, | 130 | static __cpuinit int |
129 | unsigned long action, | 131 | thermal_throttle_cpu_callback(struct notifier_block *nfb, |
130 | void *hcpu) | 132 | unsigned long action, |
133 | void *hcpu) | ||
131 | { | 134 | { |
132 | unsigned int cpu = (unsigned long)hcpu; | 135 | unsigned int cpu = (unsigned long)hcpu; |
133 | struct sys_device *sys_dev; | 136 | struct sys_device *sys_dev; |
134 | int err = 0; | 137 | int err = 0; |
135 | 138 | ||
136 | sys_dev = get_cpu_sysdev(cpu); | 139 | sys_dev = get_cpu_sysdev(cpu); |
140 | |||
137 | switch (action) { | 141 | switch (action) { |
138 | case CPU_UP_PREPARE: | 142 | case CPU_UP_PREPARE: |
139 | case CPU_UP_PREPARE_FROZEN: | 143 | case CPU_UP_PREPARE_FROZEN: |