Commit e032d80774315869aa2285b217fdbbfed86c0b49
Committed by
Linus Torvalds
1 parent
5b3fcfed35
Exists in
master
and in
6 other branches
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>
Showing 3 changed files with 26 additions and 12 deletions Side-by-side Diff
arch/x86/include/asm/mce.h
arch/x86/kernel/cpu/mcheck/mce.c
... | ... | @@ -1859,7 +1859,7 @@ |
1859 | 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 | 1864 | __cpuinitdata |
1865 | 1865 | void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu); |
1866 | 1866 | |
1867 | 1867 | |
1868 | 1868 | |
... | ... | @@ -2001,19 +2001,27 @@ |
2001 | 2001 | |
2002 | 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 | 2009 | /* Per cpu device init. All of the cpus still share the same ctrl bank: */ |
2005 | 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 | 2013 | int err; |
2009 | 2014 | int i, j; |
2010 | 2015 | |
2011 | 2016 | if (!mce_available(&boot_cpu_data)) |
2012 | 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 | 2022 | dev->id = cpu; |
2016 | 2023 | dev->bus = &mce_subsys; |
2024 | + dev->release = &mce_device_release; | |
2017 | 2025 | |
2018 | 2026 | err = device_register(dev); |
2019 | 2027 | if (err) |
... | ... | @@ -2030,6 +2038,7 @@ |
2030 | 2038 | goto error2; |
2031 | 2039 | } |
2032 | 2040 | cpumask_set_cpu(cpu, mce_device_initialized); |
2041 | + mce_device[cpu] = dev; | |
2033 | 2042 | |
2034 | 2043 | return 0; |
2035 | 2044 | error2: |
... | ... | @@ -2046,7 +2055,7 @@ |
2046 | 2055 | |
2047 | 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 | 2059 | int i; |
2051 | 2060 | |
2052 | 2061 | if (!cpumask_test_cpu(cpu, mce_device_initialized)) |
... | ... | @@ -2060,6 +2069,7 @@ |
2060 | 2069 | |
2061 | 2070 | device_unregister(dev); |
2062 | 2071 | cpumask_clear_cpu(cpu, mce_device_initialized); |
2072 | + mce_device[cpu] = NULL; | |
2063 | 2073 | } |
2064 | 2074 | |
2065 | 2075 | /* Make sure there are no machine checks on offlined CPUs. */ |
arch/x86/kernel/cpu/mcheck/mce_amd.c
... | ... | @@ -523,6 +523,7 @@ |
523 | 523 | { |
524 | 524 | int i, err = 0; |
525 | 525 | struct threshold_bank *b = NULL; |
526 | + struct device *dev = mce_device[cpu]; | |
526 | 527 | char name[32]; |
527 | 528 | |
528 | 529 | sprintf(name, "threshold_bank%i", bank); |
... | ... | @@ -543,8 +544,7 @@ |
543 | 544 | if (!b) |
544 | 545 | goto out; |
545 | 546 | |
546 | - err = sysfs_create_link(&per_cpu(mce_device, cpu).kobj, | |
547 | - b->kobj, name); | |
547 | + err = sysfs_create_link(&dev->kobj, b->kobj, name); | |
548 | 548 | if (err) |
549 | 549 | goto out; |
550 | 550 | |
... | ... | @@ -565,7 +565,7 @@ |
565 | 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 | 569 | if (!b->kobj) |
570 | 570 | goto out_free; |
571 | 571 | |
... | ... | @@ -585,8 +585,9 @@ |
585 | 585 | if (i == cpu) |
586 | 586 | continue; |
587 | 587 | |
588 | - err = sysfs_create_link(&per_cpu(mce_device, i).kobj, | |
589 | - b->kobj, name); | |
588 | + dev = mce_device[i]; | |
589 | + if (dev) | |
590 | + err = sysfs_create_link(&dev->kobj,b->kobj, name); | |
590 | 591 | if (err) |
591 | 592 | goto out; |
592 | 593 | |
... | ... | @@ -649,6 +650,7 @@ |
649 | 650 | static void threshold_remove_bank(unsigned int cpu, int bank) |
650 | 651 | { |
651 | 652 | struct threshold_bank *b; |
653 | + struct device *dev; | |
652 | 654 | char name[32]; |
653 | 655 | int i = 0; |
654 | 656 | |
... | ... | @@ -663,7 +665,7 @@ |
663 | 665 | #ifdef CONFIG_SMP |
664 | 666 | /* sibling symlink */ |
665 | 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 | 669 | per_cpu(threshold_banks, cpu)[bank] = NULL; |
668 | 670 | |
669 | 671 | return; |
... | ... | @@ -675,7 +677,9 @@ |
675 | 677 | if (i == cpu) |
676 | 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 | 683 | per_cpu(threshold_banks, i)[bank] = NULL; |
680 | 684 | } |
681 | 685 |