aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Jones <ajones@riverbed.com>2008-07-25 04:49:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-25 13:53:48 -0400
commit14cc571bb1d072d3f4be2875ea520ab03e093471 (patch)
tree831bf0d8d985f132b35c39ad55759d27e1e4d861
parentb238e57723a6fb2c365fc35de5d7c48ccf9300cd (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>
-rw-r--r--drivers/edac/edac_pci_sysfs.c30
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 */
28static atomic_t pci_parity_count = ATOMIC_INIT(0); 28static atomic_t pci_parity_count = ATOMIC_INIT(0);
29static atomic_t pci_nonparity_count = ATOMIC_INIT(0); 29static atomic_t pci_nonparity_count = ATOMIC_INIT(0);
30 30
31static struct kobject edac_pci_top_main_kobj; 31static struct kobject *edac_pci_top_main_kobj;
32static atomic_t edac_pci_sysfs_refcount = ATOMIC_INIT(0); 32static 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 */
317static void edac_pci_release_main_kobj(struct kobject *kobj) 317static 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 */
390kobject_init_and_add_fail: 399kobject_init_and_add_fail:
400 kfree(edac_pci_top_main_kobj);
401
402kzalloc_fail:
391 module_put(THIS_MODULE); 403 module_put(THIS_MODULE);
392 404
393decrement_count_fail: 405decrement_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