Commit 452a6bf955ee1842361742833e40e046287308f4

Authored by Mauro Carvalho Chehab
1 parent 8ad6c78a69

edac: Add debufs nodes to allow doing fake error inject

Sometimes, it is useful to have a mechanism that generates fake
errors, in order to test the EDAC core code, and the userspace
tools.

Provide such mechanism by adding a few debugfs nodes.

Reviewed-by: Aristeu Rozanski <arozansk@redhat.com>
Cc: Doug Thompson <norsk5@yahoo.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

Showing 2 changed files with 94 additions and 0 deletions Side-by-side Diff

drivers/edac/edac_mc_sysfs.c
... ... @@ -17,6 +17,7 @@
17 17 #include <linux/edac.h>
18 18 #include <linux/bug.h>
19 19 #include <linux/pm_runtime.h>
  20 +#include <linux/uaccess.h>
20 21  
21 22 #include "edac_core.h"
22 23 #include "edac_module.h"
... ... @@ -783,6 +784,47 @@
783 784 return p - data;
784 785 }
785 786  
  787 +#ifdef CONFIG_EDAC_DEBUG
  788 +static ssize_t edac_fake_inject_write(struct file *file,
  789 + const char __user *data,
  790 + size_t count, loff_t *ppos)
  791 +{
  792 + struct device *dev = file->private_data;
  793 + struct mem_ctl_info *mci = to_mci(dev);
  794 + static enum hw_event_mc_err_type type;
  795 +
  796 + type = mci->fake_inject_ue ? HW_EVENT_ERR_UNCORRECTED
  797 + : HW_EVENT_ERR_CORRECTED;
  798 +
  799 + printk(KERN_DEBUG
  800 + "Generating a %s fake error to %d.%d.%d to test core handling. NOTE: this won't test the driver-specific decoding logic.\n",
  801 + (type == HW_EVENT_ERR_UNCORRECTED) ? "UE" : "CE",
  802 + mci->fake_inject_layer[0],
  803 + mci->fake_inject_layer[1],
  804 + mci->fake_inject_layer[2]
  805 + );
  806 + edac_mc_handle_error(type, mci, 0, 0, 0,
  807 + mci->fake_inject_layer[0],
  808 + mci->fake_inject_layer[1],
  809 + mci->fake_inject_layer[2],
  810 + "FAKE ERROR", "for EDAC testing only", NULL);
  811 +
  812 + return count;
  813 +}
  814 +
  815 +static int debugfs_open(struct inode *inode, struct file *file)
  816 +{
  817 + file->private_data = inode->i_private;
  818 + return 0;
  819 +}
  820 +
  821 +static const struct file_operations debug_fake_inject_fops = {
  822 + .open = debugfs_open,
  823 + .write = edac_fake_inject_write,
  824 + .llseek = generic_file_llseek,
  825 +};
  826 +#endif
  827 +
786 828 /* default Control file */
787 829 DEVICE_ATTR(reset_counters, S_IWUSR, NULL, mci_reset_counters_store);
788 830  
... ... @@ -833,6 +875,45 @@
833 875 .release = mci_attr_release,
834 876 };
835 877  
  878 +#ifdef CONFIG_EDAC_DEBUG
  879 +int edac_create_debug_nodes(struct mem_ctl_info *mci)
  880 +{
  881 + struct dentry *d, *parent;
  882 + char name[80];
  883 + int i;
  884 +
  885 + d = debugfs_create_dir(mci->dev.kobj.name, mci->debugfs);
  886 + if (!d)
  887 + return -ENOMEM;
  888 + parent = d;
  889 +
  890 + for (i = 0; i < mci->n_layers; i++) {
  891 + sprintf(name, "fake_inject_%s",
  892 + edac_layer_name[mci->layers[i].type]);
  893 + d = debugfs_create_u8(name, S_IRUGO | S_IWUSR, parent,
  894 + &mci->fake_inject_layer[i]);
  895 + if (!d)
  896 + goto nomem;
  897 + }
  898 +
  899 + d = debugfs_create_bool("fake_inject_ue", S_IRUGO | S_IWUSR, parent,
  900 + &mci->fake_inject_ue);
  901 + if (!d)
  902 + goto nomem;
  903 +
  904 + d = debugfs_create_file("fake_inject", S_IWUSR, parent,
  905 + &mci->dev,
  906 + &debug_fake_inject_fops);
  907 + if (!d)
  908 + goto nomem;
  909 +
  910 + return 0;
  911 +nomem:
  912 + debugfs_remove(mci->debugfs);
  913 + return -ENOMEM;
  914 +}
  915 +#endif
  916 +
836 917 /*
837 918 * Create a new Memory Controller kobject instance,
838 919 * mc<id> under the 'mc' directory
... ... @@ -911,6 +992,9 @@
911 992 goto fail;
912 993 #endif
913 994  
  995 +#ifdef CONFIG_EDAC_DEBUG
  996 + edac_create_debug_nodes(mci);
  997 +#endif
914 998 return 0;
915 999  
916 1000 fail:
... ... @@ -937,6 +1021,9 @@
937 1021  
938 1022 debugf0("%s()\n", __func__);
939 1023  
  1024 +#ifdef CONFIG_EDAC_DEBUG
  1025 + debugfs_remove(mci->debugfs);
  1026 +#endif
940 1027 #ifdef CONFIG_EDAC_LEGACY_SYSFS
941 1028 edac_delete_csrow_objects(mci);
942 1029 #endif
include/linux/edac.h
... ... @@ -17,6 +17,7 @@
17 17 #include <linux/kobject.h>
18 18 #include <linux/completion.h>
19 19 #include <linux/workqueue.h>
  20 +#include <linux/debugfs.h>
20 21  
21 22 struct device;
22 23  
... ... @@ -634,6 +635,12 @@
634 635  
635 636 /* the internal state of this controller instance */
636 637 int op_state;
  638 +
  639 +#ifdef CONFIG_EDAC_DEBUG
  640 + struct dentry *debugfs;
  641 + u8 fake_inject_layer[EDAC_MAX_LAYERS];
  642 + u32 fake_inject_ue;
  643 +#endif
637 644 };
638 645  
639 646 #endif