x86/mce: Convert the CEC to use the MCE notifier
authorTony Luck <tony.luck@intel.com>
Fri, 14 Feb 2020 22:27:15 +0000 (14:27 -0800)
committerBorislav Petkov <bp@suse.de>
Tue, 14 Apr 2020 13:58:08 +0000 (15:58 +0200)
The CEC code has its claws in a couple of routines in mce/core.c.
Convert it to just register itself on the normal MCE notifier chain.

 [ bp: Make cec_add_elem() and cec_init() static. ]

Signed-off-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Tested-by: Tony Luck <tony.luck@intel.com>
Link: https://lkml.kernel.org/r/20200214222720.13168-3-tony.luck@intel.com
arch/x86/kernel/cpu/mce/core.c
drivers/ras/cec.c
include/linux/ras.h

index 43b1519..b033b35 100644 (file)
@@ -544,21 +544,6 @@ bool mce_is_correctable(struct mce *m)
 }
 EXPORT_SYMBOL_GPL(mce_is_correctable);
 
-static bool cec_add_mce(struct mce *m)
-{
-       if (!m)
-               return false;
-
-       /* We eat only correctable DRAM errors with usable addresses. */
-       if (mce_is_memory_error(m) &&
-           mce_is_correctable(m)  &&
-           mce_usable_address(m))
-               if (!cec_add_elem(m->addr >> PAGE_SHIFT))
-                       return true;
-
-       return false;
-}
-
 static int mce_early_notifier(struct notifier_block *nb, unsigned long val,
                              void *data)
 {
@@ -567,9 +552,6 @@ static int mce_early_notifier(struct notifier_block *nb, unsigned long val,
        if (!m)
                return NOTIFY_DONE;
 
-       if (cec_add_mce(m))
-               return NOTIFY_STOP;
-
        /* Emit the trace record: */
        trace_mce_record(m);
 
@@ -2612,7 +2594,6 @@ static int __init mcheck_late_init(void)
                static_branch_inc(&mcsafe_key);
 
        mcheck_debugfs_init();
-       cec_init();
 
        /*
         * Flush out everything that has been logged during early boot, now that
index c09cf55..6b42040 100644 (file)
@@ -309,7 +309,7 @@ static bool sanity_check(struct ce_array *ca)
        return ret;
 }
 
-int cec_add_elem(u64 pfn)
+static int cec_add_elem(u64 pfn)
 {
        struct ce_array *ca = &ce_arr;
        unsigned int to = 0;
@@ -527,7 +527,30 @@ err:
        return 1;
 }
 
-void __init cec_init(void)
+static int cec_notifier(struct notifier_block *nb, unsigned long val,
+                       void *data)
+{
+       struct mce *m = (struct mce *)data;
+
+       if (!m)
+               return NOTIFY_DONE;
+
+       /* We eat only correctable DRAM errors with usable addresses. */
+       if (mce_is_memory_error(m) &&
+           mce_is_correctable(m)  &&
+           mce_usable_address(m))
+               if (!cec_add_elem(m->addr >> PAGE_SHIFT))
+                       return NOTIFY_STOP;
+
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block cec_nb = {
+       .notifier_call  = cec_notifier,
+       .priority       = MCE_PRIO_CEC,
+};
+
+static void __init cec_init(void)
 {
        if (ce_arr.disabled)
                return;
@@ -546,8 +569,11 @@ void __init cec_init(void)
        INIT_DELAYED_WORK(&cec_work, cec_work_fn);
        schedule_delayed_work(&cec_work, CEC_DECAY_DEFAULT_INTERVAL);
 
+       mce_register_decode_chain(&cec_nb);
+
        pr_info("Correctable Errors collector initialized.\n");
 }
+late_initcall(cec_init);
 
 int __init parse_cec_param(char *str)
 {
index 7c3debb..1f4048b 100644 (file)
@@ -17,12 +17,7 @@ static inline int ras_add_daemon_trace(void) { return 0; }
 #endif
 
 #ifdef CONFIG_RAS_CEC
-void __init cec_init(void);
 int __init parse_cec_param(char *str);
-int cec_add_elem(u64 pfn);
-#else
-static inline void __init cec_init(void)       { }
-static inline int cec_add_elem(u64 pfn)                { return -ENODEV; }
 #endif
 
 #ifdef CONFIG_RAS