diff options
Diffstat (limited to 'arch/x86/kernel/cpu/mcheck')
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 19 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/therm_throt.c | 23 |
2 files changed, 31 insertions, 11 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 1cfb623ce11c..01213048f62f 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
| @@ -1226,8 +1226,13 @@ static void mce_init(void) | |||
| 1226 | } | 1226 | } |
| 1227 | 1227 | ||
| 1228 | /* Add per CPU specific workarounds here */ | 1228 | /* Add per CPU specific workarounds here */ |
| 1229 | static void mce_cpu_quirks(struct cpuinfo_x86 *c) | 1229 | static int mce_cpu_quirks(struct cpuinfo_x86 *c) |
| 1230 | { | 1230 | { |
| 1231 | if (c->x86_vendor == X86_VENDOR_UNKNOWN) { | ||
| 1232 | pr_info("MCE: unknown CPU type - not enabling MCE support.\n"); | ||
| 1233 | return -EOPNOTSUPP; | ||
| 1234 | } | ||
| 1235 | |||
| 1231 | /* This should be disabled by the BIOS, but isn't always */ | 1236 | /* This should be disabled by the BIOS, but isn't always */ |
| 1232 | if (c->x86_vendor == X86_VENDOR_AMD) { | 1237 | if (c->x86_vendor == X86_VENDOR_AMD) { |
| 1233 | if (c->x86 == 15 && banks > 4) { | 1238 | if (c->x86 == 15 && banks > 4) { |
| @@ -1273,11 +1278,20 @@ static void mce_cpu_quirks(struct cpuinfo_x86 *c) | |||
| 1273 | if ((c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xe)) && | 1278 | if ((c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xe)) && |
| 1274 | monarch_timeout < 0) | 1279 | monarch_timeout < 0) |
| 1275 | monarch_timeout = USEC_PER_SEC; | 1280 | monarch_timeout = USEC_PER_SEC; |
| 1281 | |||
| 1282 | /* | ||
| 1283 | * There are also broken BIOSes on some Pentium M and | ||
| 1284 | * earlier systems: | ||
| 1285 | */ | ||
| 1286 | if (c->x86 == 6 && c->x86_model <= 13 && mce_bootlog < 0) | ||
| 1287 | mce_bootlog = 0; | ||
| 1276 | } | 1288 | } |
| 1277 | if (monarch_timeout < 0) | 1289 | if (monarch_timeout < 0) |
| 1278 | monarch_timeout = 0; | 1290 | monarch_timeout = 0; |
| 1279 | if (mce_bootlog != 0) | 1291 | if (mce_bootlog != 0) |
| 1280 | mce_panic_timeout = 30; | 1292 | mce_panic_timeout = 30; |
| 1293 | |||
| 1294 | return 0; | ||
| 1281 | } | 1295 | } |
| 1282 | 1296 | ||
| 1283 | static void __cpuinit mce_ancient_init(struct cpuinfo_x86 *c) | 1297 | static void __cpuinit mce_ancient_init(struct cpuinfo_x86 *c) |
| @@ -1338,11 +1352,10 @@ void __cpuinit mcheck_init(struct cpuinfo_x86 *c) | |||
| 1338 | if (!mce_available(c)) | 1352 | if (!mce_available(c)) |
| 1339 | return; | 1353 | return; |
| 1340 | 1354 | ||
| 1341 | if (mce_cap_init() < 0) { | 1355 | if (mce_cap_init() < 0 || mce_cpu_quirks(c) < 0) { |
| 1342 | mce_disabled = 1; | 1356 | mce_disabled = 1; |
| 1343 | return; | 1357 | return; |
| 1344 | } | 1358 | } |
| 1345 | mce_cpu_quirks(c); | ||
| 1346 | 1359 | ||
| 1347 | machine_check_vector = do_machine_check; | 1360 | machine_check_vector = do_machine_check; |
| 1348 | 1361 | ||
diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c index bff8dd191dd5..5957a93e5173 100644 --- a/arch/x86/kernel/cpu/mcheck/therm_throt.c +++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | 36 | ||
| 37 | static DEFINE_PER_CPU(__u64, next_check) = INITIAL_JIFFIES; | 37 | static DEFINE_PER_CPU(__u64, next_check) = INITIAL_JIFFIES; |
| 38 | static DEFINE_PER_CPU(unsigned long, thermal_throttle_count); | 38 | static DEFINE_PER_CPU(unsigned long, thermal_throttle_count); |
| 39 | static DEFINE_PER_CPU(bool, thermal_throttle_active); | ||
| 39 | 40 | ||
| 40 | static atomic_t therm_throt_en = ATOMIC_INIT(0); | 41 | static atomic_t therm_throt_en = ATOMIC_INIT(0); |
| 41 | 42 | ||
| @@ -96,27 +97,33 @@ static int therm_throt_process(int curr) | |||
| 96 | { | 97 | { |
| 97 | unsigned int cpu = smp_processor_id(); | 98 | unsigned int cpu = smp_processor_id(); |
| 98 | __u64 tmp_jiffs = get_jiffies_64(); | 99 | __u64 tmp_jiffs = get_jiffies_64(); |
| 100 | bool was_throttled = __get_cpu_var(thermal_throttle_active); | ||
| 101 | bool is_throttled = __get_cpu_var(thermal_throttle_active) = curr; | ||
| 99 | 102 | ||
| 100 | if (curr) | 103 | if (is_throttled) |
| 101 | __get_cpu_var(thermal_throttle_count)++; | 104 | __get_cpu_var(thermal_throttle_count)++; |
| 102 | 105 | ||
| 103 | if (time_before64(tmp_jiffs, __get_cpu_var(next_check))) | 106 | if (!(was_throttled ^ is_throttled) && |
| 107 | time_before64(tmp_jiffs, __get_cpu_var(next_check))) | ||
| 104 | return 0; | 108 | return 0; |
| 105 | 109 | ||
| 106 | __get_cpu_var(next_check) = tmp_jiffs + CHECK_INTERVAL; | 110 | __get_cpu_var(next_check) = tmp_jiffs + CHECK_INTERVAL; |
| 107 | 111 | ||
| 108 | /* if we just entered the thermal event */ | 112 | /* if we just entered the thermal event */ |
| 109 | if (curr) { | 113 | if (is_throttled) { |
| 110 | printk(KERN_CRIT "CPU%d: Temperature above threshold, " | 114 | printk(KERN_CRIT "CPU%d: Temperature above threshold, " |
| 111 | "cpu clock throttled (total events = %lu)\n", cpu, | 115 | "cpu clock throttled (total events = %lu)\n", |
| 112 | __get_cpu_var(thermal_throttle_count)); | 116 | cpu, __get_cpu_var(thermal_throttle_count)); |
| 113 | 117 | ||
| 114 | add_taint(TAINT_MACHINE_CHECK); | 118 | add_taint(TAINT_MACHINE_CHECK); |
| 115 | } else { | 119 | return 1; |
| 116 | printk(KERN_CRIT "CPU%d: Temperature/speed normal\n", cpu); | 120 | } |
| 121 | if (was_throttled) { | ||
| 122 | printk(KERN_INFO "CPU%d: Temperature/speed normal\n", cpu); | ||
| 123 | return 1; | ||
| 117 | } | 124 | } |
| 118 | 125 | ||
| 119 | return 1; | 126 | return 0; |
| 120 | } | 127 | } |
| 121 | 128 | ||
| 122 | #ifdef CONFIG_SYSFS | 129 | #ifdef CONFIG_SYSFS |
