Commit 14cc571b authored by Arthur Jones's avatar Arthur Jones Committed by Linus Torvalds

edac: core fix to use dynamic kobject

Static kobjects are not supported in linux kernel.  Convert the
edac_pci_top_main_kobj from static to dynamic.  This avoids the double
free of the edac_pci_top_main_kobj.name that we see on module reload of
the e752x edac driver (and probably others as well).

In addition Greg KH <greg@kroah.com> has pointed out that this code may be
cleaned up significantly.  I will look at that as a follow-on patch, for
now, I just want the minimum fix to get this double-free oops bug
squashed...

Many thanks to Greg KH for his patience in showing me what the
Documentation/kobject.txt already said (oops)...
Signed-off-by: default avatarArthur Jones <ajones@riverbed.com>
Signed-off-by: default avatarDoug Thompson <dougthompson@xmission.com>
Acked-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent b238e577
...@@ -28,7 +28,7 @@ static int edac_pci_poll_msec = 1000; /* one second workq period */ ...@@ -28,7 +28,7 @@ static int edac_pci_poll_msec = 1000; /* one second workq period */
static atomic_t pci_parity_count = ATOMIC_INIT(0); static atomic_t pci_parity_count = ATOMIC_INIT(0);
static atomic_t pci_nonparity_count = ATOMIC_INIT(0); static atomic_t pci_nonparity_count = ATOMIC_INIT(0);
static struct kobject edac_pci_top_main_kobj; static struct kobject *edac_pci_top_main_kobj;
static atomic_t edac_pci_sysfs_refcount = ATOMIC_INIT(0); static atomic_t edac_pci_sysfs_refcount = ATOMIC_INIT(0);
/* getter functions for the data variables */ /* getter functions for the data variables */
...@@ -83,7 +83,7 @@ static void edac_pci_instance_release(struct kobject *kobj) ...@@ -83,7 +83,7 @@ static void edac_pci_instance_release(struct kobject *kobj)
pci = to_instance(kobj); pci = to_instance(kobj);
/* decrement reference count on top main kobj */ /* decrement reference count on top main kobj */
kobject_put(&edac_pci_top_main_kobj); kobject_put(edac_pci_top_main_kobj);
kfree(pci); /* Free the control struct */ kfree(pci); /* Free the control struct */
} }
...@@ -166,7 +166,7 @@ static int edac_pci_create_instance_kobj(struct edac_pci_ctl_info *pci, int idx) ...@@ -166,7 +166,7 @@ static int edac_pci_create_instance_kobj(struct edac_pci_ctl_info *pci, int idx)
* track the number of PCI instances we have, and thus nest * track the number of PCI instances we have, and thus nest
* properly on keeping the module loaded * properly on keeping the module loaded
*/ */
main_kobj = kobject_get(&edac_pci_top_main_kobj); main_kobj = kobject_get(edac_pci_top_main_kobj);
if (!main_kobj) { if (!main_kobj) {
err = -ENODEV; err = -ENODEV;
goto error_out; goto error_out;
...@@ -174,11 +174,11 @@ static int edac_pci_create_instance_kobj(struct edac_pci_ctl_info *pci, int idx) ...@@ -174,11 +174,11 @@ static int edac_pci_create_instance_kobj(struct edac_pci_ctl_info *pci, int idx)
/* And now register this new kobject under the main kobj */ /* And now register this new kobject under the main kobj */
err = kobject_init_and_add(&pci->kobj, &ktype_pci_instance, err = kobject_init_and_add(&pci->kobj, &ktype_pci_instance,
&edac_pci_top_main_kobj, "pci%d", idx); edac_pci_top_main_kobj, "pci%d", idx);
if (err != 0) { if (err != 0) {
debugf2("%s() failed to register instance pci%d\n", debugf2("%s() failed to register instance pci%d\n",
__func__, idx); __func__, idx);
kobject_put(&edac_pci_top_main_kobj); kobject_put(edac_pci_top_main_kobj);
goto error_out; goto error_out;
} }
...@@ -316,9 +316,10 @@ static struct edac_pci_dev_attribute *edac_pci_attr[] = { ...@@ -316,9 +316,10 @@ static struct edac_pci_dev_attribute *edac_pci_attr[] = {
*/ */
static void edac_pci_release_main_kobj(struct kobject *kobj) static void edac_pci_release_main_kobj(struct kobject *kobj)
{ {
debugf0("%s() here to module_put(THIS_MODULE)\n", __func__); debugf0("%s() here to module_put(THIS_MODULE)\n", __func__);
kfree(kobj);
/* last reference to top EDAC PCI kobject has been removed, /* last reference to top EDAC PCI kobject has been removed,
* NOW release our ref count on the core module * NOW release our ref count on the core module
*/ */
...@@ -369,8 +370,16 @@ static int edac_pci_main_kobj_setup(void) ...@@ -369,8 +370,16 @@ static int edac_pci_main_kobj_setup(void)
goto decrement_count_fail; goto decrement_count_fail;
} }
edac_pci_top_main_kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL);
if (!edac_pci_top_main_kobj) {
debugf1("Failed to allocate\n");
err = -ENOMEM;
goto kzalloc_fail;
}
/* Instanstiate the pci object */ /* Instanstiate the pci object */
err = kobject_init_and_add(&edac_pci_top_main_kobj, &ktype_edac_pci_main_kobj, err = kobject_init_and_add(edac_pci_top_main_kobj,
&ktype_edac_pci_main_kobj,
&edac_class->kset.kobj, "pci"); &edac_class->kset.kobj, "pci");
if (err) { if (err) {
debugf1("Failed to register '.../edac/pci'\n"); debugf1("Failed to register '.../edac/pci'\n");
...@@ -381,13 +390,16 @@ static int edac_pci_main_kobj_setup(void) ...@@ -381,13 +390,16 @@ static int edac_pci_main_kobj_setup(void)
* for EDAC PCI, then edac_pci_main_kobj_teardown() * for EDAC PCI, then edac_pci_main_kobj_teardown()
* must be used, for resources to be cleaned up properly * must be used, for resources to be cleaned up properly
*/ */
kobject_uevent(&edac_pci_top_main_kobj, KOBJ_ADD); kobject_uevent(edac_pci_top_main_kobj, KOBJ_ADD);
debugf1("Registered '.../edac/pci' kobject\n"); debugf1("Registered '.../edac/pci' kobject\n");
return 0; return 0;
/* Error unwind statck */ /* Error unwind statck */
kobject_init_and_add_fail: kobject_init_and_add_fail:
kfree(edac_pci_top_main_kobj);
kzalloc_fail:
module_put(THIS_MODULE); module_put(THIS_MODULE);
decrement_count_fail: decrement_count_fail:
...@@ -414,7 +426,7 @@ static void edac_pci_main_kobj_teardown(void) ...@@ -414,7 +426,7 @@ static void edac_pci_main_kobj_teardown(void)
if (atomic_dec_return(&edac_pci_sysfs_refcount) == 0) { if (atomic_dec_return(&edac_pci_sysfs_refcount) == 0) {
debugf0("%s() called kobject_put on main kobj\n", debugf0("%s() called kobject_put on main kobj\n",
__func__); __func__);
kobject_put(&edac_pci_top_main_kobj); kobject_put(edac_pci_top_main_kobj);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment