diff options
author | Borislav Petkov <bp@suse.de> | 2013-07-19 06:28:25 -0400 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2013-07-23 19:01:28 -0400 |
commit | 88d84ac97378c2f1d5fec9af1e8b7d9a662d6b00 (patch) | |
tree | 71870a8997a772762a12a9e8f80bec224e9e10c5 /drivers/edac | |
parent | ad81f0545ef01ea651886dddac4bef6cec930092 (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.c | 9 | ||||
-rw-r--r-- | drivers/edac/edac_mc_sysfs.c | 28 | ||||
-rw-r--r-- | drivers/edac/i5100_edac.c | 2 |
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 | */ |
49 | static void const *edac_mc_owner; | 49 | static void const *edac_mc_owner; |
50 | 50 | ||
51 | static struct bus_type mc_bus[EDAC_MAX_MCS]; | ||
52 | |||
51 | unsigned edac_dimm_info_location(struct dimm_info *dimm, char *buf, | 53 | unsigned 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 | } |
1065 | fail2: | 1067 | fail2: |
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 | ||
1105 | static void mc_attr_release(struct device *dev) | 1107 | static 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; |