EDAC: Fix lockdep splat
authorBorislav Petkov <bp@suse.de>
Fri, 19 Jul 2013 10:28:25 +0000 (12:28 +0200)
committerTony Luck <tony.luck@intel.com>
Tue, 23 Jul 2013 23:01:28 +0000 (16:01 -0700)
Fix the following:

BUG: key ffff88043bdd0330 not in .data!
------------[ cut here ]------------
WARNING: at kernel/lockdep.c:2987 lockdep_init_map+0x565/0x5a0()
DEBUG_LOCKS_WARN_ON(1)
Modules linked in: glue_helper sb_edac(+) edac_core snd acpi_cpufreq lrw gf128mul ablk_helper iTCO_wdt evdev i2c_i801 dcdbas button cryptd pcspkr iTCO_vendor_support usb_common lpc_ich mfd_core soundcore mperf processor microcode
CPU: 2 PID: 599 Comm: modprobe Not tainted 3.10.0 #1
Hardware name: Dell Inc. Precision T3600/0PTTT9, BIOS A08 01/24/2013
 0000000000000009 ffff880439a1d920 ffffffff8160a9a9 ffff880439a1d958
 ffffffff8103d9e0 ffff88043af4a510 ffffffff81a16e11 0000000000000000
 ffff88043bdd0330 0000000000000000 ffff880439a1d9b8 ffffffff8103dacc
Call Trace:
  dump_stack
  warn_slowpath_common
  warn_slowpath_fmt
  lockdep_init_map
  ? trace_hardirqs_on_caller
  ? trace_hardirqs_on
  debug_mutex_init
  __mutex_init
  bus_register
  edac_create_sysfs_mci_device
  edac_mc_add_mc
  sbridge_probe
  pci_device_probe
  driver_probe_device
  __driver_attach
  ? driver_probe_device
  bus_for_each_dev
  driver_attach
  bus_add_driver
  driver_register
  __pci_register_driver
  ? 0xffffffffa0010fff
  sbridge_init
  ? 0xffffffffa0010fff
  do_one_initcall
  load_module
  ? unset_module_init_ro_nx
  SyS_init_module
  tracesys
---[ end trace d24a70b0d3ddf733 ]---
EDAC MC0: Giving out device to 'sbridge_edac.c' 'Sandy Bridge Socket#0': DEV 0000:3f:0e.0
EDAC sbridge: Driver loaded.

What happens is that bus_register needs a statically allocated lock_key
because the last is handed in to lockdep. However, struct mem_ctl_info
embeds struct bus_type (the whole struct, not a pointer to it) and the
whole thing gets dynamically allocated.

Fix this by using a statically allocated struct bus_type for the MC bus.

Signed-off-by: Borislav Petkov <bp@suse.de>
Acked-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Cc: Markus Trippelsdorf <markus@trippelsdorf.de>
Cc: stable@kernel.org # v3.10
Signed-off-by: Tony Luck <tony.luck@intel.com>
drivers/edac/edac_mc.c
drivers/edac/edac_mc_sysfs.c
drivers/edac/i5100_edac.c
include/linux/edac.h

index 27e86d93826280a62744a559332bf0cd9bc03b3b..89e109022d78a27cf506d995c1c16de2feffea0f 100644 (file)
@@ -48,6 +48,8 @@ static LIST_HEAD(mc_devices);
  */
 static void const *edac_mc_owner;
 
+static struct bus_type mc_bus[EDAC_MAX_MCS];
+
 unsigned edac_dimm_info_location(struct dimm_info *dimm, char *buf,
                                 unsigned len)
 {
@@ -723,6 +725,11 @@ int edac_mc_add_mc(struct mem_ctl_info *mci)
        int ret = -EINVAL;
        edac_dbg(0, "\n");
 
+       if (mci->mc_idx >= EDAC_MAX_MCS) {
+               pr_warn_once("Too many memory controllers: %d\n", mci->mc_idx);
+               return -ENODEV;
+       }
+
 #ifdef CONFIG_EDAC_DEBUG
        if (edac_debug_level >= 3)
                edac_mc_dump_mci(mci);
@@ -762,6 +769,8 @@ int edac_mc_add_mc(struct mem_ctl_info *mci)
        /* set load time so that error rate can be tracked */
        mci->start_time = jiffies;
 
+       mci->bus = &mc_bus[mci->mc_idx];
+
        if (edac_create_sysfs_mci_device(mci)) {
                edac_mc_printk(mci, KERN_WARNING,
                        "failed to create sysfs device\n");
index ef15a7e613bc6b1d1feec75733a86e20cb23efa7..e7c32c4f783737962b575a232f03b5ed19d3629b 100644 (file)
@@ -370,7 +370,7 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci,
                return -ENODEV;
 
        csrow->dev.type = &csrow_attr_type;
-       csrow->dev.bus = &mci->bus;
+       csrow->dev.bus = mci->bus;
        device_initialize(&csrow->dev);
        csrow->dev.parent = &mci->dev;
        csrow->mci = mci;
@@ -605,7 +605,7 @@ static int edac_create_dimm_object(struct mem_ctl_info *mci,
        dimm->mci = mci;
 
        dimm->dev.type = &dimm_attr_type;
-       dimm->dev.bus = &mci->bus;
+       dimm->dev.bus = mci->bus;
        device_initialize(&dimm->dev);
 
        dimm->dev.parent = &mci->dev;
@@ -975,11 +975,13 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
         * The memory controller needs its own bus, in order to avoid
         * namespace conflicts at /sys/bus/edac.
         */
-       mci->bus.name = kasprintf(GFP_KERNEL, "mc%d", mci->mc_idx);
-       if (!mci->bus.name)
+       mci->bus->name = kasprintf(GFP_KERNEL, "mc%d", mci->mc_idx);
+       if (!mci->bus->name)
                return -ENOMEM;
-       edac_dbg(0, "creating bus %s\n", mci->bus.name);
-       err = bus_register(&mci->bus);
+
+       edac_dbg(0, "creating bus %s\n", mci->bus->name);
+
+       err = bus_register(mci->bus);
        if (err < 0)
                return err;
 
@@ -988,7 +990,7 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
        device_initialize(&mci->dev);
 
        mci->dev.parent = mci_pdev;
-       mci->dev.bus = &mci->bus;
+       mci->dev.bus = mci->bus;
        dev_set_name(&mci->dev, "mc%d", mci->mc_idx);
        dev_set_drvdata(&mci->dev, mci);
        pm_runtime_forbid(&mci->dev);
@@ -997,8 +999,8 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
        err = device_add(&mci->dev);
        if (err < 0) {
                edac_dbg(1, "failure: create device %s\n", dev_name(&mci->dev));
-               bus_unregister(&mci->bus);
-               kfree(mci->bus.name);
+               bus_unregister(mci->bus);
+               kfree(mci->bus->name);
                return err;
        }
 
@@ -1064,8 +1066,8 @@ fail:
        }
 fail2:
        device_unregister(&mci->dev);
-       bus_unregister(&mci->bus);
-       kfree(mci->bus.name);
+       bus_unregister(mci->bus);
+       kfree(mci->bus->name);
        return err;
 }
 
@@ -1098,8 +1100,8 @@ void edac_unregister_sysfs(struct mem_ctl_info *mci)
 {
        edac_dbg(1, "Unregistering device %s\n", dev_name(&mci->dev));
        device_unregister(&mci->dev);
-       bus_unregister(&mci->bus);
-       kfree(mci->bus.name);
+       bus_unregister(mci->bus);
+       kfree(mci->bus->name);
 }
 
 static void mc_attr_release(struct device *dev)
index 1b635178cc44ff31b8ed224560ebdf86851165f0..157b934e8ce3a528468e45a735ab41dee6043cea 100644 (file)
@@ -974,7 +974,7 @@ static int i5100_setup_debugfs(struct mem_ctl_info *mci)
        if (!i5100_debugfs)
                return -ENODEV;
 
-       priv->debugfs = debugfs_create_dir(mci->bus.name, i5100_debugfs);
+       priv->debugfs = debugfs_create_dir(mci->bus->name, i5100_debugfs);
 
        if (!priv->debugfs)
                return -ENOMEM;
index 0b763276f6199a255d304b572e0c414c90252056..5c6d7fbaf89e00dbed2d9cc418318980f7de3d2b 100644 (file)
@@ -622,7 +622,7 @@ struct edac_raw_error_desc {
  */
 struct mem_ctl_info {
        struct device                   dev;
-       struct bus_type                 bus;
+       struct bus_type                 *bus;
 
        struct list_head link;  /* for global list of mem_ctl_info structs */
 
@@ -742,4 +742,9 @@ struct mem_ctl_info {
 #endif
 };
 
+/*
+ * Maximum number of memory controllers in the coherent fabric.
+ */
+#define EDAC_MAX_MCS   16
+
 #endif