diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2012-01-16 17:40:28 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-16 20:08:42 -0500 |
commit | e032d80774315869aa2285b217fdbbfed86c0b49 (patch) | |
tree | c23bcaaa2217a68fd142aaa4dbf9c471f6eb9569 | |
parent | 5b3fcfed35735af507be36a4c3f3bbeb9bc7bbf6 (diff) |
mce: fix warning messages about static struct mce_device
When suspending, there was a large list of warnings going something like:
Device 'machinecheck1' does not have a release() function, it is broken and must be fixed
This patch turns the static mce_devices into dynamically allocated, and
properly frees them when they are removed from the system. It solves
the warning messages on my laptop here.
Reported-by: "Srivatsa S. Bhat" <srivatsa.bhat@linux.vnet.ibm.com>
Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
Tested-by: Djalal Harouni <tixxdz@opendz.org>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Borislav Petkov <bp@amd64.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | arch/x86/include/asm/mce.h | 2 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 18 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce_amd.c | 18 |
3 files changed, 26 insertions, 12 deletions
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index f35ce43c1a77..6aefb14cbbc5 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h | |||
@@ -151,7 +151,7 @@ static inline void enable_p5_mce(void) {} | |||
151 | 151 | ||
152 | void mce_setup(struct mce *m); | 152 | void mce_setup(struct mce *m); |
153 | void mce_log(struct mce *m); | 153 | void mce_log(struct mce *m); |
154 | DECLARE_PER_CPU(struct device, mce_device); | 154 | extern struct device *mce_device[CONFIG_NR_CPUS]; |
155 | 155 | ||
156 | /* | 156 | /* |
157 | * Maximum banks number. | 157 | * Maximum banks number. |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 29ba3297e480..5a11ae2e9e91 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
@@ -1859,7 +1859,7 @@ static struct bus_type mce_subsys = { | |||
1859 | .dev_name = "machinecheck", | 1859 | .dev_name = "machinecheck", |
1860 | }; | 1860 | }; |
1861 | 1861 | ||
1862 | DEFINE_PER_CPU(struct device, mce_device); | 1862 | struct device *mce_device[CONFIG_NR_CPUS]; |
1863 | 1863 | ||
1864 | __cpuinitdata | 1864 | __cpuinitdata |
1865 | void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu); | 1865 | void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu); |
@@ -2001,19 +2001,27 @@ static struct device_attribute *mce_device_attrs[] = { | |||
2001 | 2001 | ||
2002 | static cpumask_var_t mce_device_initialized; | 2002 | static cpumask_var_t mce_device_initialized; |
2003 | 2003 | ||
2004 | static void mce_device_release(struct device *dev) | ||
2005 | { | ||
2006 | kfree(dev); | ||
2007 | } | ||
2008 | |||
2004 | /* Per cpu device init. All of the cpus still share the same ctrl bank: */ | 2009 | /* Per cpu device init. All of the cpus still share the same ctrl bank: */ |
2005 | static __cpuinit int mce_device_create(unsigned int cpu) | 2010 | static __cpuinit int mce_device_create(unsigned int cpu) |
2006 | { | 2011 | { |
2007 | struct device *dev = &per_cpu(mce_device, cpu); | 2012 | struct device *dev; |
2008 | int err; | 2013 | int err; |
2009 | int i, j; | 2014 | int i, j; |
2010 | 2015 | ||
2011 | if (!mce_available(&boot_cpu_data)) | 2016 | if (!mce_available(&boot_cpu_data)) |
2012 | return -EIO; | 2017 | return -EIO; |
2013 | 2018 | ||
2014 | memset(dev, 0, sizeof(struct device)); | 2019 | dev = kzalloc(sizeof *dev, GFP_KERNEL); |
2020 | if (!dev) | ||
2021 | return -ENOMEM; | ||
2015 | dev->id = cpu; | 2022 | dev->id = cpu; |
2016 | dev->bus = &mce_subsys; | 2023 | dev->bus = &mce_subsys; |
2024 | dev->release = &mce_device_release; | ||
2017 | 2025 | ||
2018 | err = device_register(dev); | 2026 | err = device_register(dev); |
2019 | if (err) | 2027 | if (err) |
@@ -2030,6 +2038,7 @@ static __cpuinit int mce_device_create(unsigned int cpu) | |||
2030 | goto error2; | 2038 | goto error2; |
2031 | } | 2039 | } |
2032 | cpumask_set_cpu(cpu, mce_device_initialized); | 2040 | cpumask_set_cpu(cpu, mce_device_initialized); |
2041 | mce_device[cpu] = dev; | ||
2033 | 2042 | ||
2034 | return 0; | 2043 | return 0; |
2035 | error2: | 2044 | error2: |
@@ -2046,7 +2055,7 @@ error: | |||
2046 | 2055 | ||
2047 | static __cpuinit void mce_device_remove(unsigned int cpu) | 2056 | static __cpuinit void mce_device_remove(unsigned int cpu) |
2048 | { | 2057 | { |
2049 | struct device *dev = &per_cpu(mce_device, cpu); | 2058 | struct device *dev = mce_device[cpu]; |
2050 | int i; | 2059 | int i; |
2051 | 2060 | ||
2052 | if (!cpumask_test_cpu(cpu, mce_device_initialized)) | 2061 | if (!cpumask_test_cpu(cpu, mce_device_initialized)) |
@@ -2060,6 +2069,7 @@ static __cpuinit void mce_device_remove(unsigned int cpu) | |||
2060 | 2069 | ||
2061 | device_unregister(dev); | 2070 | device_unregister(dev); |
2062 | cpumask_clear_cpu(cpu, mce_device_initialized); | 2071 | cpumask_clear_cpu(cpu, mce_device_initialized); |
2072 | mce_device[cpu] = NULL; | ||
2063 | } | 2073 | } |
2064 | 2074 | ||
2065 | /* Make sure there are no machine checks on offlined CPUs. */ | 2075 | /* Make sure there are no machine checks on offlined CPUs. */ |
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index ba0b94a7e204..786e76a86322 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c | |||
@@ -523,6 +523,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) | |||
523 | { | 523 | { |
524 | int i, err = 0; | 524 | int i, err = 0; |
525 | struct threshold_bank *b = NULL; | 525 | struct threshold_bank *b = NULL; |
526 | struct device *dev = mce_device[cpu]; | ||
526 | char name[32]; | 527 | char name[32]; |
527 | 528 | ||
528 | sprintf(name, "threshold_bank%i", bank); | 529 | sprintf(name, "threshold_bank%i", bank); |
@@ -543,8 +544,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) | |||
543 | if (!b) | 544 | if (!b) |
544 | goto out; | 545 | goto out; |
545 | 546 | ||
546 | err = sysfs_create_link(&per_cpu(mce_device, cpu).kobj, | 547 | err = sysfs_create_link(&dev->kobj, b->kobj, name); |
547 | b->kobj, name); | ||
548 | if (err) | 548 | if (err) |
549 | goto out; | 549 | goto out; |
550 | 550 | ||
@@ -565,7 +565,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) | |||
565 | goto out; | 565 | goto out; |
566 | } | 566 | } |
567 | 567 | ||
568 | b->kobj = kobject_create_and_add(name, &per_cpu(mce_device, cpu).kobj); | 568 | b->kobj = kobject_create_and_add(name, &dev->kobj); |
569 | if (!b->kobj) | 569 | if (!b->kobj) |
570 | goto out_free; | 570 | goto out_free; |
571 | 571 | ||
@@ -585,8 +585,9 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) | |||
585 | if (i == cpu) | 585 | if (i == cpu) |
586 | continue; | 586 | continue; |
587 | 587 | ||
588 | err = sysfs_create_link(&per_cpu(mce_device, i).kobj, | 588 | dev = mce_device[i]; |
589 | b->kobj, name); | 589 | if (dev) |
590 | err = sysfs_create_link(&dev->kobj,b->kobj, name); | ||
590 | if (err) | 591 | if (err) |
591 | goto out; | 592 | goto out; |
592 | 593 | ||
@@ -649,6 +650,7 @@ static void deallocate_threshold_block(unsigned int cpu, | |||
649 | static void threshold_remove_bank(unsigned int cpu, int bank) | 650 | static void threshold_remove_bank(unsigned int cpu, int bank) |
650 | { | 651 | { |
651 | struct threshold_bank *b; | 652 | struct threshold_bank *b; |
653 | struct device *dev; | ||
652 | char name[32]; | 654 | char name[32]; |
653 | int i = 0; | 655 | int i = 0; |
654 | 656 | ||
@@ -663,7 +665,7 @@ static void threshold_remove_bank(unsigned int cpu, int bank) | |||
663 | #ifdef CONFIG_SMP | 665 | #ifdef CONFIG_SMP |
664 | /* sibling symlink */ | 666 | /* sibling symlink */ |
665 | if (shared_bank[bank] && b->blocks->cpu != cpu) { | 667 | if (shared_bank[bank] && b->blocks->cpu != cpu) { |
666 | sysfs_remove_link(&per_cpu(mce_device, cpu).kobj, name); | 668 | sysfs_remove_link(&mce_device[cpu]->kobj, name); |
667 | per_cpu(threshold_banks, cpu)[bank] = NULL; | 669 | per_cpu(threshold_banks, cpu)[bank] = NULL; |
668 | 670 | ||
669 | return; | 671 | return; |
@@ -675,7 +677,9 @@ static void threshold_remove_bank(unsigned int cpu, int bank) | |||
675 | if (i == cpu) | 677 | if (i == cpu) |
676 | continue; | 678 | continue; |
677 | 679 | ||
678 | sysfs_remove_link(&per_cpu(mce_device, i).kobj, name); | 680 | dev = mce_device[i]; |
681 | if (dev) | ||
682 | sysfs_remove_link(&dev->kobj, name); | ||
679 | per_cpu(threshold_banks, i)[bank] = NULL; | 683 | per_cpu(threshold_banks, i)[bank] = NULL; |
680 | } | 684 | } |
681 | 685 | ||