提交 9223d0dc 编写于 作者: B Borislav Petkov

thermal: Move therm_throt there from x86/mce

This functionality has nothing to do with MCE, move it to the thermal
framework and untangle it from MCE.
Requested-by: NPeter Zijlstra <peterz@infradead.org>
Signed-off-by: NBorislav Petkov <bp@suse.de>
Reviewed-by: NSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Tested-by: NSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Link: https://lkml.kernel.org/r/20210202121003.GD18075@zn.tnic
上级 4f432e8b
...@@ -1157,10 +1157,6 @@ config X86_MCE_INJECT ...@@ -1157,10 +1157,6 @@ config X86_MCE_INJECT
If you don't know what a machine check is and you don't do kernel If you don't know what a machine check is and you don't do kernel
QA it is safe to say n. QA it is safe to say n.
config X86_THERMAL_VECTOR
def_bool y
depends on X86_MCE_INTEL
source "arch/x86/events/Kconfig" source "arch/x86/events/Kconfig"
config X86_LEGACY_VM86 config X86_LEGACY_VM86
......
...@@ -288,22 +288,6 @@ extern void (*mce_threshold_vector)(void); ...@@ -288,22 +288,6 @@ extern void (*mce_threshold_vector)(void);
/* Deferred error interrupt handler */ /* Deferred error interrupt handler */
extern void (*deferred_error_int_vector)(void); extern void (*deferred_error_int_vector)(void);
/*
* Thermal handler
*/
void intel_init_thermal(struct cpuinfo_x86 *c);
/* Interrupt Handler for core thermal thresholds */
extern int (*platform_thermal_notify)(__u64 msr_val);
/* Interrupt Handler for package thermal thresholds */
extern int (*platform_thermal_package_notify)(__u64 msr_val);
/* Callback support of rate control, return true, if
* callback has rate control */
extern bool (*platform_thermal_package_rate_control)(void);
/* /*
* Used by APEI to report memory error via /dev/mcelog * Used by APEI to report memory error via /dev/mcelog
*/ */
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_X86_THERMAL_H
#define _ASM_X86_THERMAL_H
#ifdef CONFIG_X86_THERMAL_VECTOR
void intel_init_thermal(struct cpuinfo_x86 *c);
bool x86_thermal_enabled(void);
void intel_thermal_interrupt(void);
#else
static inline void intel_init_thermal(struct cpuinfo_x86 *c) { }
#endif
#endif /* _ASM_X86_THERMAL_H */
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <asm/traps.h> #include <asm/traps.h>
#include <asm/resctrl.h> #include <asm/resctrl.h>
#include <asm/numa.h> #include <asm/numa.h>
#include <asm/thermal.h>
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
#include <linux/topology.h> #include <linux/topology.h>
...@@ -719,6 +720,8 @@ static void init_intel(struct cpuinfo_x86 *c) ...@@ -719,6 +720,8 @@ static void init_intel(struct cpuinfo_x86 *c)
tsx_disable(); tsx_disable();
split_lock_init(); split_lock_init();
intel_init_thermal(c);
} }
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
......
...@@ -9,8 +9,6 @@ obj-$(CONFIG_X86_MCE_THRESHOLD) += threshold.o ...@@ -9,8 +9,6 @@ obj-$(CONFIG_X86_MCE_THRESHOLD) += threshold.o
mce-inject-y := inject.o mce-inject-y := inject.o
obj-$(CONFIG_X86_MCE_INJECT) += mce-inject.o obj-$(CONFIG_X86_MCE_INJECT) += mce-inject.o
obj-$(CONFIG_X86_THERMAL_VECTOR) += therm_throt.o
obj-$(CONFIG_ACPI_APEI) += apei.o obj-$(CONFIG_ACPI_APEI) += apei.o
obj-$(CONFIG_X86_MCELOG_LEGACY) += dev-mcelog.o obj-$(CONFIG_X86_MCELOG_LEGACY) += dev-mcelog.o
...@@ -531,7 +531,6 @@ static void intel_imc_init(struct cpuinfo_x86 *c) ...@@ -531,7 +531,6 @@ static void intel_imc_init(struct cpuinfo_x86 *c)
void mce_intel_feature_init(struct cpuinfo_x86 *c) void mce_intel_feature_init(struct cpuinfo_x86 *c)
{ {
intel_init_thermal(c);
intel_init_cmci(); intel_init_cmci();
intel_init_lmce(); intel_init_lmce();
intel_ppin_init(c); intel_ppin_init(c);
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <asm/hw_irq.h> #include <asm/hw_irq.h>
#include <asm/desc.h> #include <asm/desc.h>
#include <asm/traps.h> #include <asm/traps.h>
#include <asm/thermal.h>
#define CREATE_TRACE_POINTS #define CREATE_TRACE_POINTS
#include <asm/trace/irq_vectors.h> #include <asm/trace/irq_vectors.h>
...@@ -374,3 +375,23 @@ void fixup_irqs(void) ...@@ -374,3 +375,23 @@ void fixup_irqs(void)
} }
} }
#endif #endif
#ifdef CONFIG_X86_THERMAL_VECTOR
static void smp_thermal_vector(void)
{
if (x86_thermal_enabled())
intel_thermal_interrupt();
else
pr_err("CPU%d: Unexpected LVT thermal interrupt!\n",
smp_processor_id());
}
DEFINE_IDTENTRY_SYSVEC(sysvec_thermal)
{
trace_thermal_apic_entry(THERMAL_APIC_VECTOR);
inc_irq_stat(irq_thermal_count);
smp_thermal_vector();
trace_thermal_apic_exit(THERMAL_APIC_VECTOR);
ack_APIC_irq();
}
#endif
...@@ -8,6 +8,10 @@ config INTEL_POWERCLAMP ...@@ -8,6 +8,10 @@ config INTEL_POWERCLAMP
enforce idle time which results in more package C-state residency. The enforce idle time which results in more package C-state residency. The
user interface is exposed via generic thermal framework. user interface is exposed via generic thermal framework.
config X86_THERMAL_VECTOR
def_bool y
depends on X86 && CPU_SUP_INTEL && X86_LOCAL_APIC
config X86_PKG_TEMP_THERMAL config X86_PKG_TEMP_THERMAL
tristate "X86 package temperature thermal driver" tristate "X86 package temperature thermal driver"
depends on X86_THERMAL_VECTOR depends on X86_THERMAL_VECTOR
......
...@@ -10,3 +10,4 @@ obj-$(CONFIG_INTEL_QUARK_DTS_THERMAL) += intel_quark_dts_thermal.o ...@@ -10,3 +10,4 @@ obj-$(CONFIG_INTEL_QUARK_DTS_THERMAL) += intel_quark_dts_thermal.o
obj-$(CONFIG_INT340X_THERMAL) += int340x_thermal/ obj-$(CONFIG_INT340X_THERMAL) += int340x_thermal/
obj-$(CONFIG_INTEL_BXT_PMIC_THERMAL) += intel_bxt_pmic_thermal.o obj-$(CONFIG_INTEL_BXT_PMIC_THERMAL) += intel_bxt_pmic_thermal.o
obj-$(CONFIG_INTEL_PCH_THERMAL) += intel_pch_thermal.o obj-$(CONFIG_INTEL_PCH_THERMAL) += intel_pch_thermal.o
obj-$(CONFIG_X86_THERMAL_VECTOR) += therm_throt.o
...@@ -26,13 +26,13 @@ ...@@ -26,13 +26,13 @@
#include <linux/cpu.h> #include <linux/cpu.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/thermal.h>
#include <asm/traps.h> #include <asm/traps.h>
#include <asm/apic.h> #include <asm/apic.h>
#include <asm/mce.h> #include <asm/irq.h>
#include <asm/msr.h> #include <asm/msr.h>
#include <asm/trace/irq_vectors.h>
#include "internal.h" #include "thermal_interrupt.h"
/* How long to wait between reporting thermal events */ /* How long to wait between reporting thermal events */
#define CHECK_INTERVAL (300 * HZ) #define CHECK_INTERVAL (300 * HZ)
...@@ -570,7 +570,7 @@ static void notify_thresholds(__u64 msr_val) ...@@ -570,7 +570,7 @@ static void notify_thresholds(__u64 msr_val)
} }
/* Thermal transition interrupt handler */ /* Thermal transition interrupt handler */
static void intel_thermal_interrupt(void) void intel_thermal_interrupt(void)
{ {
__u64 msr_val; __u64 msr_val;
...@@ -606,23 +606,6 @@ static void intel_thermal_interrupt(void) ...@@ -606,23 +606,6 @@ static void intel_thermal_interrupt(void)
} }
} }
static void unexpected_thermal_interrupt(void)
{
pr_err("CPU%d: Unexpected LVT thermal interrupt!\n",
smp_processor_id());
}
static void (*smp_thermal_vector)(void) = unexpected_thermal_interrupt;
DEFINE_IDTENTRY_SYSVEC(sysvec_thermal)
{
trace_thermal_apic_entry(THERMAL_APIC_VECTOR);
inc_irq_stat(irq_thermal_count);
smp_thermal_vector();
trace_thermal_apic_exit(THERMAL_APIC_VECTOR);
ack_APIC_irq();
}
/* Thermal monitoring depends on APIC, ACPI and clock modulation */ /* Thermal monitoring depends on APIC, ACPI and clock modulation */
static int intel_thermal_supported(struct cpuinfo_x86 *c) static int intel_thermal_supported(struct cpuinfo_x86 *c)
{ {
...@@ -633,6 +616,11 @@ static int intel_thermal_supported(struct cpuinfo_x86 *c) ...@@ -633,6 +616,11 @@ static int intel_thermal_supported(struct cpuinfo_x86 *c)
return 1; return 1;
} }
bool x86_thermal_enabled(void)
{
return atomic_read(&therm_throt_en);
}
void intel_init_thermal(struct cpuinfo_x86 *c) void intel_init_thermal(struct cpuinfo_x86 *c)
{ {
unsigned int cpu = smp_processor_id(); unsigned int cpu = smp_processor_id();
...@@ -719,8 +707,6 @@ void intel_init_thermal(struct cpuinfo_x86 *c) ...@@ -719,8 +707,6 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
| PACKAGE_THERM_INT_HIGH_ENABLE), h); | PACKAGE_THERM_INT_HIGH_ENABLE), h);
} }
smp_thermal_vector = intel_thermal_interrupt;
rdmsr(MSR_IA32_MISC_ENABLE, l, h); rdmsr(MSR_IA32_MISC_ENABLE, l, h);
wrmsr(MSR_IA32_MISC_ENABLE, l | MSR_IA32_MISC_ENABLE_TM1, h); wrmsr(MSR_IA32_MISC_ENABLE, l | MSR_IA32_MISC_ENABLE_TM1, h);
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _INTEL_THERMAL_INTERRUPT_H
#define _INTEL_THERMAL_INTERRUPT_H
/* Interrupt Handler for package thermal thresholds */
extern int (*platform_thermal_package_notify)(__u64 msr_val);
/* Interrupt Handler for core thermal thresholds */
extern int (*platform_thermal_notify)(__u64 msr_val);
/* Callback support of rate control, return true, if
* callback has rate control */
extern bool (*platform_thermal_package_rate_control)(void);
#endif /* _INTEL_THERMAL_INTERRUPT_H */
...@@ -17,8 +17,10 @@ ...@@ -17,8 +17,10 @@
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/thermal.h> #include <linux/thermal.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <asm/cpu_device_id.h> #include <asm/cpu_device_id.h>
#include <asm/mce.h>
#include "thermal_interrupt.h"
/* /*
* Rate control delay: Idea is to introduce denounce effect * Rate control delay: Idea is to introduce denounce effect
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册