aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
authorBorislav Petkov <bp@suse.de>2013-07-19 06:28:25 -0400
committerTony Luck <tony.luck@intel.com>2013-07-23 19:01:28 -0400
commit88d84ac97378c2f1d5fec9af1e8b7d9a662d6b00 (patch)
tree71870a8997a772762a12a9e8f80bec224e9e10c5 /drivers/edac
parentad81f0545ef01ea651886dddac4bef6cec930092 (diff)
EDAC: Fix lockdep splat
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>
Diffstat (limited to 'drivers/edac')
-rw-r--r--drivers/edac/edac_mc.c9
-rw-r--r--drivers/edac/edac_mc_sysfs.c28
-rw-r--r--drivers/edac/i5100_edac.c2
3 files changed, 25 insertions, 14 deletions
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 27e86d938262..89e109022d78 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -48,6 +48,8 @@ static LIST_HEAD(mc_devices);
48 */ 48 */
49static void const *edac_mc_owner; 49static void const *edac_mc_owner;
50 50
51static struct bus_type mc_bus[EDAC_MAX_MCS];
52
51unsigned edac_dimm_info_location(struct dimm_info *dimm, char *buf, 53unsigned edac_dimm_info_location(struct dimm_info *dimm, char *buf,
52 unsigned len) 54 unsigned len)
53{ 55{
@@ -723,6 +725,11 @@ int edac_mc_add_mc(struct mem_ctl_info *mci)
723 int ret = -EINVAL; 725 int ret = -EINVAL;
724 edac_dbg(0, "\n"); 726 edac_dbg(0, "\n");
725 727
728 if (mci->mc_idx >= EDAC_MAX_MCS) {
729 pr_warn_once("Too many memory controllers: %d\n", mci->mc_idx);
730 return -ENODEV;
731 }
732
726#ifdef CONFIG_EDAC_DEBUG 733#ifdef CONFIG_EDAC_DEBUG
727 if (edac_debug_level >= 3) 734 if (edac_debug_level >= 3)
728 edac_mc_dump_mci(mci); 735 edac_mc_dump_mci(mci);
@@ -762,6 +769,8 @@ int edac_mc_add_mc(struct mem_ctl_info *mci)
762 /* set load time so that error rate can be tracked */ 769 /* set load time so that error rate can be tracked */
763 mci->start_time = jiffies; 770 mci->start_time = jiffies;
764 771
772 mci->bus = &mc_bus[mci->mc_idx];
773
765 if (edac_create_sysfs_mci_device(mci)) { 774 if (edac_create_sysfs_mci_device(mci)) {
766 edac_mc_printk(mci, KERN_WARNING, 775 edac_mc_printk(mci, KERN_WARNING,
767 "failed to create sysfs device\n"); 776 "failed to create sysfs device\n");
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
index ef15a7e613bc..e7c32c4f7837 100644
--- a/drivers/edac/edac_mc_sysfs.c
+++ b/drivers/edac/edac_mc_sysfs.c
@@ -370,7 +370,7 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci,
370 return -ENODEV; 370 return -ENODEV;
371 371
372 csrow->dev.type = &csrow_attr_type; 372 csrow->dev.type = &csrow_attr_type;
373 csrow->dev.bus = &mci->bus; 373 csrow->dev.bus = mci->bus;
374 device_initialize(&csrow->dev); 374 device_initialize(&csrow->dev);
375 csrow->dev.parent = &mci->dev; 375 csrow->dev.parent = &mci->dev;
376 csrow->mci = mci; 376 csrow->mci = mci;
@@ -605,7 +605,7 @@ static int edac_create_dimm_object(struct mem_ctl_info *mci,
605 dimm->mci = mci; 605 dimm->mci = mci;
606 606
607 dimm->dev.type = &dimm_attr_type; 607 dimm->dev.type = &dimm_attr_type;
608 dimm->dev.bus = &mci->bus; 608 dimm->dev.bus = mci->bus;
609 device_initialize(&dimm->dev); 609 device_initialize(&dimm->dev);
610 610
611 dimm->dev.parent = &mci->dev; 611 dimm->dev.parent = &mci->dev;
@@ -975,11 +975,13 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
975 * The memory controller needs its own bus, in order to avoid 975 * The memory controller needs its own bus, in order to avoid
976 * namespace conflicts at /sys/bus/edac. 976 * namespace conflicts at /sys/bus/edac.
977 */ 977 */
978 mci->bus.name = kasprintf(GFP_KERNEL, "mc%d", mci->mc_idx); 978 mci->bus->name = kasprintf(GFP_KERNEL, "mc%d", mci->mc_idx);
979 if (!mci->bus.name) 979 if (!mci->bus->name)
980 return -ENOMEM; 980 return -ENOMEM;
981 edac_dbg(0, "creating bus %s\n", mci->bus.name); 981
982 err = bus_register(&mci->bus); 982 edac_dbg(0, "creating bus %s\n", mci->bus->name);
983
984 err = bus_register(mci->bus);
983 if (err < 0) 985 if (err < 0)
984 return err; 986 return err;
985 987
@@ -988,7 +990,7 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
988 device_initialize(&mci->dev); 990 device_initialize(&mci->dev);
989 991
990 mci->dev.parent = mci_pdev; 992 mci->dev.parent = mci_pdev;
991 mci->dev.bus = &mci->bus; 993 mci->dev.bus = mci->bus;
992 dev_set_name(&mci->dev, "mc%d", mci->mc_idx); 994 dev_set_name(&mci->dev, "mc%d", mci->mc_idx);
993 dev_set_drvdata(&mci->dev, mci); 995 dev_set_drvdata(&mci->dev, mci);
994 pm_runtime_forbid(&mci->dev); 996 pm_runtime_forbid(&mci->dev);
@@ -997,8 +999,8 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
997 err = device_add(&mci->dev); 999 err = device_add(&mci->dev);
998 if (err < 0) { 1000 if (err < 0) {
999 edac_dbg(1, "failure: create device %s\n", dev_name(&mci->dev)); 1001 edac_dbg(1, "failure: create device %s\n", dev_name(&mci->dev));
1000 bus_unregister(&mci->bus); 1002 bus_unregister(mci->bus);
1001 kfree(mci->bus.name); 1003 kfree(mci->bus->name);
1002 return err; 1004 return err;
1003 } 1005 }
1004 1006
@@ -1064,8 +1066,8 @@ fail:
1064 } 1066 }
1065fail2: 1067fail2:
1066 device_unregister(&mci->dev); 1068 device_unregister(&mci->dev);
1067 bus_unregister(&mci->bus); 1069 bus_unregister(mci->bus);
1068 kfree(mci->bus.name); 1070 kfree(mci->bus->name);
1069 return err; 1071 return err;
1070} 1072}
1071 1073
@@ -1098,8 +1100,8 @@ void edac_unregister_sysfs(struct mem_ctl_info *mci)
1098{ 1100{
1099 edac_dbg(1, "Unregistering device %s\n", dev_name(&mci->dev)); 1101 edac_dbg(1, "Unregistering device %s\n", dev_name(&mci->dev));
1100 device_unregister(&mci->dev); 1102 device_unregister(&mci->dev);
1101 bus_unregister(&mci->bus); 1103 bus_unregister(mci->bus);
1102 kfree(mci->bus.name); 1104 kfree(mci->bus->name);
1103} 1105}
1104 1106
1105static void mc_attr_release(struct device *dev) 1107static void mc_attr_release(struct device *dev)
diff --git a/drivers/edac/i5100_edac.c b/drivers/edac/i5100_edac.c
index 1b635178cc44..157b934e8ce3 100644
--- a/drivers/edac/i5100_edac.c
+++ b/drivers/edac/i5100_edac.c
@@ -974,7 +974,7 @@ static int i5100_setup_debugfs(struct mem_ctl_info *mci)
974 if (!i5100_debugfs) 974 if (!i5100_debugfs)
975 return -ENODEV; 975 return -ENODEV;
976 976
977 priv->debugfs = debugfs_create_dir(mci->bus.name, i5100_debugfs); 977 priv->debugfs = debugfs_create_dir(mci->bus->name, i5100_debugfs);
978 978
979 if (!priv->debugfs) 979 if (!priv->debugfs)
980 return -ENOMEM; 980 return -ENOMEM;