diff options
author | Dave Peterson <dsp@llnl.gov> | 2006-03-26 04:38:49 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-26 11:57:07 -0500 |
commit | 472678ebd30d87cbe8d97562dcc0e46d1076040f (patch) | |
tree | 216f22045fb3b786f513f000b184e5fd449b58d1 /drivers/edac/edac_mc.h | |
parent | 6e5a8748507dea83386d1d76c58aeaed1ff5a1ec (diff) |
[PATCH] EDAC: kobject/sysfs fixes
- After we unregister a kobject, wait for our kobject release method
to call complete(). This causes us to wait until the kobject
reference count reaches 0. Otherwise, a task accessing the EDAC
sysfs interface can hold the reference count above 0 until after the
EDAC module has been unloaded. When the reference count finally
drops to 0, this will result in an attempt to call our release
method inside the EDAC module after the module has already been
unloaded.
This isn't the best fix, since a process can get stuck sleeping forever
uninterruptibly if the user does the following:
rmmod my_module < /sys/my_sysfs/file
I'll go back and implement a better fix later. However this should
be ok for now.
- Call edac_remove_sysfs_mci_device() from edac_mc_del_mc() rather
than from edac_mc_free(). Since edac_mc_add_mc() calls
edac_create_sysfs_mci_device(), edac_mc_del_mc() should call
edac_remove_sysfs_mci_device().
Signed-off-by: David S. Peterson <dsp@llnl.gov>
Cc: Greg KH <greg@kroah.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/edac/edac_mc.h')
-rw-r--r-- | drivers/edac/edac_mc.h | 9 |
1 files changed, 2 insertions, 7 deletions
diff --git a/drivers/edac/edac_mc.h b/drivers/edac/edac_mc.h index 0bcc3797c753..c9c1590db721 100644 --- a/drivers/edac/edac_mc.h +++ b/drivers/edac/edac_mc.h | |||
@@ -185,11 +185,6 @@ enum scrub_type { | |||
185 | #define SCRUB_FLAG_HW_PROG_SRC BIT(SCRUB_HW_PROG_SRC_CORR) | 185 | #define SCRUB_FLAG_HW_PROG_SRC BIT(SCRUB_HW_PROG_SRC_CORR) |
186 | #define SCRUB_FLAG_HW_TUN BIT(SCRUB_HW_TUNABLE) | 186 | #define SCRUB_FLAG_HW_TUN BIT(SCRUB_HW_TUNABLE) |
187 | 187 | ||
188 | enum mci_sysfs_status { | ||
189 | MCI_SYSFS_INACTIVE = 0, /* sysfs entries NOT registered */ | ||
190 | MCI_SYSFS_ACTIVE /* sysfs entries ARE registered */ | ||
191 | }; | ||
192 | |||
193 | /* FIXME - should have notify capabilities: NMI, LOG, PROC, etc */ | 188 | /* FIXME - should have notify capabilities: NMI, LOG, PROC, etc */ |
194 | 189 | ||
195 | /* | 190 | /* |
@@ -299,6 +294,7 @@ struct csrow_info { | |||
299 | struct mem_ctl_info *mci; /* the parent */ | 294 | struct mem_ctl_info *mci; /* the parent */ |
300 | 295 | ||
301 | struct kobject kobj; /* sysfs kobject for this csrow */ | 296 | struct kobject kobj; /* sysfs kobject for this csrow */ |
297 | struct completion kobj_complete; | ||
302 | 298 | ||
303 | /* FIXME the number of CHANNELs might need to become dynamic */ | 299 | /* FIXME the number of CHANNELs might need to become dynamic */ |
304 | u32 nr_channels; | 300 | u32 nr_channels; |
@@ -320,8 +316,6 @@ struct mem_ctl_info { | |||
320 | unsigned long scrub_cap; /* chipset scrub capabilities */ | 316 | unsigned long scrub_cap; /* chipset scrub capabilities */ |
321 | enum scrub_type scrub_mode; /* current scrub mode */ | 317 | enum scrub_type scrub_mode; /* current scrub mode */ |
322 | 318 | ||
323 | enum mci_sysfs_status sysfs_active; /* status of sysfs */ | ||
324 | |||
325 | /* pointer to edac checking routine */ | 319 | /* pointer to edac checking routine */ |
326 | void (*edac_check) (struct mem_ctl_info * mci); | 320 | void (*edac_check) (struct mem_ctl_info * mci); |
327 | /* | 321 | /* |
@@ -359,6 +353,7 @@ struct mem_ctl_info { | |||
359 | 353 | ||
360 | /* edac sysfs device control */ | 354 | /* edac sysfs device control */ |
361 | struct kobject edac_mci_kobj; | 355 | struct kobject edac_mci_kobj; |
356 | struct completion kobj_complete; | ||
362 | }; | 357 | }; |
363 | 358 | ||
364 | 359 | ||