diff options
author | Arthur Jones <ajones@riverbed.com> | 2008-07-25 04:49:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-25 13:53:48 -0400 |
commit | 14cc571bb1d072d3f4be2875ea520ab03e093471 (patch) | |
tree | 831bf0d8d985f132b35c39ad55759d27e1e4d861 /drivers/edac/edac_pci_sysfs.c | |
parent | b238e57723a6fb2c365fc35de5d7c48ccf9300cd (diff) |
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: Arthur Jones <ajones@riverbed.com>
Signed-off-by: Doug Thompson <dougthompson@xmission.com>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/edac/edac_pci_sysfs.c')
-rw-r--r-- | drivers/edac/edac_pci_sysfs.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/drivers/edac/edac_pci_sysfs.c b/drivers/edac/edac_pci_sysfs.c index 2c1fa1bb6df2..5c153dccc95e 100644 --- a/drivers/edac/edac_pci_sysfs.c +++ b/drivers/edac/edac_pci_sysfs.c | |||
@@ -28,7 +28,7 @@ static int edac_pci_poll_msec = 1000; /* one second workq period */ | |||
28 | static atomic_t pci_parity_count = ATOMIC_INIT(0); | 28 | static atomic_t pci_parity_count = ATOMIC_INIT(0); |
29 | static atomic_t pci_nonparity_count = ATOMIC_INIT(0); | 29 | static atomic_t pci_nonparity_count = ATOMIC_INIT(0); |
30 | 30 | ||
31 | static struct kobject edac_pci_top_main_kobj; | 31 | static struct kobject *edac_pci_top_main_kobj; |
32 | static atomic_t edac_pci_sysfs_refcount = ATOMIC_INIT(0); | 32 | static atomic_t edac_pci_sysfs_refcount = ATOMIC_INIT(0); |
33 | 33 | ||
34 | /* getter functions for the data variables */ | 34 | /* getter functions for the data variables */ |
@@ -83,7 +83,7 @@ static void edac_pci_instance_release(struct kobject *kobj) | |||
83 | pci = to_instance(kobj); | 83 | pci = to_instance(kobj); |
84 | 84 | ||
85 | /* decrement reference count on top main kobj */ | 85 | /* decrement reference count on top main kobj */ |
86 | kobject_put(&edac_pci_top_main_kobj); | 86 | kobject_put(edac_pci_top_main_kobj); |
87 | 87 | ||
88 | kfree(pci); /* Free the control struct */ | 88 | kfree(pci); /* Free the control struct */ |
89 | } | 89 | } |
@@ -166,7 +166,7 @@ static int edac_pci_create_instance_kobj(struct edac_pci_ctl_info *pci, int idx) | |||
166 | * track the number of PCI instances we have, and thus nest | 166 | * track the number of PCI instances we have, and thus nest |
167 | * properly on keeping the module loaded | 167 | * properly on keeping the module loaded |
168 | */ | 168 | */ |
169 | main_kobj = kobject_get(&edac_pci_top_main_kobj); | 169 | main_kobj = kobject_get(edac_pci_top_main_kobj); |
170 | if (!main_kobj) { | 170 | if (!main_kobj) { |
171 | err = -ENODEV; | 171 | err = -ENODEV; |
172 | goto error_out; | 172 | goto error_out; |
@@ -174,11 +174,11 @@ static int edac_pci_create_instance_kobj(struct edac_pci_ctl_info *pci, int idx) | |||
174 | 174 | ||
175 | /* And now register this new kobject under the main kobj */ | 175 | /* And now register this new kobject under the main kobj */ |
176 | err = kobject_init_and_add(&pci->kobj, &ktype_pci_instance, | 176 | err = kobject_init_and_add(&pci->kobj, &ktype_pci_instance, |
177 | &edac_pci_top_main_kobj, "pci%d", idx); | 177 | edac_pci_top_main_kobj, "pci%d", idx); |
178 | if (err != 0) { | 178 | if (err != 0) { |
179 | debugf2("%s() failed to register instance pci%d\n", | 179 | debugf2("%s() failed to register instance pci%d\n", |
180 | __func__, idx); | 180 | __func__, idx); |
181 | kobject_put(&edac_pci_top_main_kobj); | 181 | kobject_put(edac_pci_top_main_kobj); |
182 | goto error_out; | 182 | goto error_out; |
183 | } | 183 | } |
184 | 184 | ||
@@ -316,9 +316,10 @@ static struct edac_pci_dev_attribute *edac_pci_attr[] = { | |||
316 | */ | 316 | */ |
317 | static void edac_pci_release_main_kobj(struct kobject *kobj) | 317 | static void edac_pci_release_main_kobj(struct kobject *kobj) |
318 | { | 318 | { |
319 | |||
320 | debugf0("%s() here to module_put(THIS_MODULE)\n", __func__); | 319 | debugf0("%s() here to module_put(THIS_MODULE)\n", __func__); |
321 | 320 | ||
321 | kfree(kobj); | ||
322 | |||
322 | /* last reference to top EDAC PCI kobject has been removed, | 323 | /* last reference to top EDAC PCI kobject has been removed, |
323 | * NOW release our ref count on the core module | 324 | * NOW release our ref count on the core module |
324 | */ | 325 | */ |
@@ -369,8 +370,16 @@ static int edac_pci_main_kobj_setup(void) | |||
369 | goto decrement_count_fail; | 370 | goto decrement_count_fail; |
370 | } | 371 | } |
371 | 372 | ||
373 | edac_pci_top_main_kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL); | ||
374 | if (!edac_pci_top_main_kobj) { | ||
375 | debugf1("Failed to allocate\n"); | ||
376 | err = -ENOMEM; | ||
377 | goto kzalloc_fail; | ||
378 | } | ||
379 | |||
372 | /* Instanstiate the pci object */ | 380 | /* Instanstiate the pci object */ |
373 | err = kobject_init_and_add(&edac_pci_top_main_kobj, &ktype_edac_pci_main_kobj, | 381 | err = kobject_init_and_add(edac_pci_top_main_kobj, |
382 | &ktype_edac_pci_main_kobj, | ||
374 | &edac_class->kset.kobj, "pci"); | 383 | &edac_class->kset.kobj, "pci"); |
375 | if (err) { | 384 | if (err) { |
376 | debugf1("Failed to register '.../edac/pci'\n"); | 385 | debugf1("Failed to register '.../edac/pci'\n"); |
@@ -381,13 +390,16 @@ static int edac_pci_main_kobj_setup(void) | |||
381 | * for EDAC PCI, then edac_pci_main_kobj_teardown() | 390 | * for EDAC PCI, then edac_pci_main_kobj_teardown() |
382 | * must be used, for resources to be cleaned up properly | 391 | * must be used, for resources to be cleaned up properly |
383 | */ | 392 | */ |
384 | kobject_uevent(&edac_pci_top_main_kobj, KOBJ_ADD); | 393 | kobject_uevent(edac_pci_top_main_kobj, KOBJ_ADD); |
385 | debugf1("Registered '.../edac/pci' kobject\n"); | 394 | debugf1("Registered '.../edac/pci' kobject\n"); |
386 | 395 | ||
387 | return 0; | 396 | return 0; |
388 | 397 | ||
389 | /* Error unwind statck */ | 398 | /* Error unwind statck */ |
390 | kobject_init_and_add_fail: | 399 | kobject_init_and_add_fail: |
400 | kfree(edac_pci_top_main_kobj); | ||
401 | |||
402 | kzalloc_fail: | ||
391 | module_put(THIS_MODULE); | 403 | module_put(THIS_MODULE); |
392 | 404 | ||
393 | decrement_count_fail: | 405 | decrement_count_fail: |
@@ -414,7 +426,7 @@ static void edac_pci_main_kobj_teardown(void) | |||
414 | if (atomic_dec_return(&edac_pci_sysfs_refcount) == 0) { | 426 | if (atomic_dec_return(&edac_pci_sysfs_refcount) == 0) { |
415 | debugf0("%s() called kobject_put on main kobj\n", | 427 | debugf0("%s() called kobject_put on main kobj\n", |
416 | __func__); | 428 | __func__); |
417 | kobject_put(&edac_pci_top_main_kobj); | 429 | kobject_put(edac_pci_top_main_kobj); |
418 | } | 430 | } |
419 | } | 431 | } |
420 | 432 | ||