Messages in this thread Patch in this message | | | From | Borislav Petkov <> | Subject | [PATCH 2/2] x86, mce: Add persistent MCE event | Date | Wed, 21 Mar 2012 15:34:56 +0100 |
| |
From: Borislav Petkov <borislav.petkov@amd.com>
Add the necessary glue to enable the mce_record tracepoint on boot, turning it into a persistent event. This exports the MCE buffer through a debugfs per-CPU file which a userspace daemon can read and then process the received error data further.
Signed-off-by: Borislav Petkov <borislav.petkov@amd.com> --- arch/x86/kernel/cpu/mcheck/mce.c | 53 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 5a11ae2e9e91..791c4633d771 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -95,6 +95,13 @@ static DECLARE_WAIT_QUEUE_HEAD(mce_chrdev_wait); static DEFINE_PER_CPU(struct mce, mces_seen); static int cpu_missing; +static struct perf_event_attr pattr = { + .type = PERF_TYPE_TRACEPOINT, + .size = sizeof(pattr), + .sample_type = PERF_SAMPLE_RAW, + .persistent = 1, +}; + /* MCA banks polled by the period polling timer for corrected events */ DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = { [0 ... BITS_TO_LONGS(MAX_NR_BANKS)-1] = ~0UL @@ -102,6 +109,8 @@ DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = { static DEFINE_PER_CPU(struct work_struct, mce_work); +static DEFINE_PER_CPU(struct pers_event_desc, mce_ev); + /* * CPU/chipset specific EDAC code can register a notifier call here to print * MCE errors in a human-readable form. @@ -2109,6 +2118,50 @@ static void __cpuinit mce_reenable_cpu(void *h) } } +static __init int mcheck_init_persistent_event(void) +{ + +#define MCE_RECORD_FNAME_SZ 14 +#define MCE_BUF_PAGES 4 + + int cpu, err = 0; + char buf[MCE_RECORD_FNAME_SZ]; + + pattr.config = event_mce_record.event.type; + pattr.sample_period = 1; + pattr.wakeup_events = 1; + + get_online_cpus(); + + for_each_online_cpu(cpu) { + struct pers_event_desc *d = &per_cpu(mce_ev, cpu); + + snprintf(buf, MCE_RECORD_FNAME_SZ, "mce_record%d", cpu); + d->dfs_name = buf; + d->pattr = &pattr; + + if (perf_add_persistent_on_cpu(cpu, d, mce_get_debugfs_dir(), + MCE_BUF_PAGES)) + goto err_unwind; + } + goto unlock; + +err_unwind: + err = -EINVAL; + for (--cpu; cpu >= 0; cpu--) + perf_rm_persistent_on_cpu(cpu, &per_cpu(mce_ev, cpu)); + +unlock: + put_online_cpus(); + + return err; +} + +/* + * This has to run after event_trace_init() + */ +device_initcall(mcheck_init_persistent_event); + /* Get notified when a cpu comes on/off. Be hotplug friendly. */ static int __cpuinit mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) -- 1.7.9.3.362.g71319
| |