mirror of
https://github.com/torvalds/linux.git
synced 2024-12-15 07:33:56 +00:00
x86/mcheck: Split threshold_cpu_callback into two callbacks
The threshold_cpu_callback callbacks looks like one of the notifier and its arguments are almost the same. Split this out and have one ONLINE and one DEAD callback. This will come handy later once the main code gets changed to use the callback mechanism. Also, handle threshold_cpu_callback_online() return value so we don't continue if the function fails. Boris Petkov removed the callback pointer and replaced it with proper functions. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Acked-by: Borislav Petkov <bp@alien8.de> Cc: Tony Luck <tony.luck@intel.com> Cc: rt@linutronix.de Cc: linux-edac@vger.kernel.org Link: http://lkml.kernel.org/r/20161110174447.11848-5-bigeasy@linutronix.de Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
parent
7f34b935e8
commit
4d7b02d58c
@ -293,9 +293,7 @@ void do_machine_check(struct pt_regs *, long);
|
|||||||
/*
|
/*
|
||||||
* Threshold handler
|
* Threshold handler
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern void (*mce_threshold_vector)(void);
|
extern void (*mce_threshold_vector)(void);
|
||||||
extern void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu);
|
|
||||||
|
|
||||||
/* Deferred error interrupt handler */
|
/* Deferred error interrupt handler */
|
||||||
extern void (*deferred_error_int_vector)(void);
|
extern void (*deferred_error_int_vector)(void);
|
||||||
@ -377,7 +375,12 @@ struct smca_bank_info {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern struct smca_bank_info smca_banks[MAX_NR_BANKS];
|
extern struct smca_bank_info smca_banks[MAX_NR_BANKS];
|
||||||
|
extern int mce_threshold_create_device(unsigned int cpu);
|
||||||
|
extern int mce_threshold_remove_device(unsigned int cpu);
|
||||||
|
#else
|
||||||
|
|
||||||
|
static inline int mce_threshold_create_device(unsigned int cpu) { return 0; };
|
||||||
|
static inline int mce_threshold_remove_device(unsigned int cpu) { return 0; };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _ASM_X86_MCE_H */
|
#endif /* _ASM_X86_MCE_H */
|
||||||
|
@ -2255,8 +2255,6 @@ static struct bus_type mce_subsys = {
|
|||||||
|
|
||||||
DEFINE_PER_CPU(struct device *, mce_device);
|
DEFINE_PER_CPU(struct device *, mce_device);
|
||||||
|
|
||||||
void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu);
|
|
||||||
|
|
||||||
static inline struct mce_bank *attr_to_bank(struct device_attribute *attr)
|
static inline struct mce_bank *attr_to_bank(struct device_attribute *attr)
|
||||||
{
|
{
|
||||||
return container_of(attr, struct mce_bank, attr);
|
return container_of(attr, struct mce_bank, attr);
|
||||||
@ -2512,13 +2510,17 @@ mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
|
|||||||
|
|
||||||
switch (action & ~CPU_TASKS_FROZEN) {
|
switch (action & ~CPU_TASKS_FROZEN) {
|
||||||
case CPU_ONLINE:
|
case CPU_ONLINE:
|
||||||
|
|
||||||
mce_device_create(cpu);
|
mce_device_create(cpu);
|
||||||
if (threshold_cpu_callback)
|
|
||||||
threshold_cpu_callback(action, cpu);
|
if (mce_threshold_create_device(cpu)) {
|
||||||
|
mce_device_remove(cpu);
|
||||||
|
return NOTIFY_BAD;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case CPU_DEAD:
|
case CPU_DEAD:
|
||||||
if (threshold_cpu_callback)
|
mce_threshold_remove_device(cpu);
|
||||||
threshold_cpu_callback(action, cpu);
|
|
||||||
mce_device_remove(cpu);
|
mce_device_remove(cpu);
|
||||||
mce_intel_hcpu_update(cpu);
|
mce_intel_hcpu_update(cpu);
|
||||||
|
|
||||||
|
@ -55,6 +55,8 @@
|
|||||||
/* Threshold LVT offset is at MSR0xC0000410[15:12] */
|
/* Threshold LVT offset is at MSR0xC0000410[15:12] */
|
||||||
#define SMCA_THR_LVT_OFF 0xF000
|
#define SMCA_THR_LVT_OFF 0xF000
|
||||||
|
|
||||||
|
static bool thresholding_en;
|
||||||
|
|
||||||
static const char * const th_names[] = {
|
static const char * const th_names[] = {
|
||||||
"load_store",
|
"load_store",
|
||||||
"insn_fetch",
|
"insn_fetch",
|
||||||
@ -1077,10 +1079,13 @@ free_out:
|
|||||||
per_cpu(threshold_banks, cpu)[bank] = NULL;
|
per_cpu(threshold_banks, cpu)[bank] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void threshold_remove_device(unsigned int cpu)
|
int mce_threshold_remove_device(unsigned int cpu)
|
||||||
{
|
{
|
||||||
unsigned int bank;
|
unsigned int bank;
|
||||||
|
|
||||||
|
if (!thresholding_en)
|
||||||
|
return 0;
|
||||||
|
|
||||||
for (bank = 0; bank < mca_cfg.banks; ++bank) {
|
for (bank = 0; bank < mca_cfg.banks; ++bank) {
|
||||||
if (!(per_cpu(bank_map, cpu) & (1 << bank)))
|
if (!(per_cpu(bank_map, cpu) & (1 << bank)))
|
||||||
continue;
|
continue;
|
||||||
@ -1088,15 +1093,19 @@ static void threshold_remove_device(unsigned int cpu)
|
|||||||
}
|
}
|
||||||
kfree(per_cpu(threshold_banks, cpu));
|
kfree(per_cpu(threshold_banks, cpu));
|
||||||
per_cpu(threshold_banks, cpu) = NULL;
|
per_cpu(threshold_banks, cpu) = NULL;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create dir/files for all valid threshold banks */
|
/* create dir/files for all valid threshold banks */
|
||||||
static int threshold_create_device(unsigned int cpu)
|
int mce_threshold_create_device(unsigned int cpu)
|
||||||
{
|
{
|
||||||
unsigned int bank;
|
unsigned int bank;
|
||||||
struct threshold_bank **bp;
|
struct threshold_bank **bp;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
|
if (!thresholding_en)
|
||||||
|
return 0;
|
||||||
|
|
||||||
bp = per_cpu(threshold_banks, cpu);
|
bp = per_cpu(threshold_banks, cpu);
|
||||||
if (bp)
|
if (bp)
|
||||||
return 0;
|
return 0;
|
||||||
@ -1117,40 +1126,23 @@ static int threshold_create_device(unsigned int cpu)
|
|||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
err:
|
err:
|
||||||
threshold_remove_device(cpu);
|
mce_threshold_remove_device(cpu);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get notified when a cpu comes on/off */
|
|
||||||
static void
|
|
||||||
amd_64_threshold_cpu_callback(unsigned long action, unsigned int cpu)
|
|
||||||
{
|
|
||||||
switch (action) {
|
|
||||||
case CPU_ONLINE:
|
|
||||||
case CPU_ONLINE_FROZEN:
|
|
||||||
threshold_create_device(cpu);
|
|
||||||
break;
|
|
||||||
case CPU_DEAD:
|
|
||||||
case CPU_DEAD_FROZEN:
|
|
||||||
threshold_remove_device(cpu);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static __init int threshold_init_device(void)
|
static __init int threshold_init_device(void)
|
||||||
{
|
{
|
||||||
unsigned lcpu = 0;
|
unsigned lcpu = 0;
|
||||||
|
|
||||||
/* to hit CPUs online before the notifier is up */
|
/* to hit CPUs online before the notifier is up */
|
||||||
for_each_online_cpu(lcpu) {
|
for_each_online_cpu(lcpu) {
|
||||||
int err = threshold_create_device(lcpu);
|
int err = mce_threshold_create_device(lcpu);
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
threshold_cpu_callback = amd_64_threshold_cpu_callback;
|
|
||||||
|
thresholding_en = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user