aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
authorDave Peterson <dsp@llnl.gov>2006-03-26 04:38:49 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-26 11:57:07 -0500
commit472678ebd30d87cbe8d97562dcc0e46d1076040f (patch)
tree216f22045fb3b786f513f000b184e5fd449b58d1 /drivers/edac
parent6e5a8748507dea83386d1d76c58aeaed1ff5a1ec (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')
-rw-r--r--drivers/edac/edac_mc.c76
-rw-r--r--drivers/edac/edac_mc.h9
2 files changed, 42 insertions, 43 deletions
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index e6ecc7da38a5..7ee9419234aa 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -139,6 +139,12 @@ static struct sysdev_class edac_class = {
139static struct kobject edac_memctrl_kobj; 139static struct kobject edac_memctrl_kobj;
140static struct kobject edac_pci_kobj; 140static struct kobject edac_pci_kobj;
141 141
142/* We use these to wait for the reference counts on edac_memctrl_kobj and
143 * edac_pci_kobj to reach 0.
144 */
145static struct completion edac_memctrl_kobj_complete;
146static struct completion edac_pci_kobj_complete;
147
142/* 148/*
143 * /sys/devices/system/edac/mc; 149 * /sys/devices/system/edac/mc;
144 * data structures and methods 150 * data structures and methods
@@ -244,6 +250,7 @@ static struct memctrl_dev_attribute *memctrl_attr[] = {
244static void edac_memctrl_master_release(struct kobject *kobj) 250static void edac_memctrl_master_release(struct kobject *kobj)
245{ 251{
246 debugf1("%s()\n", __func__); 252 debugf1("%s()\n", __func__);
253 complete(&edac_memctrl_kobj_complete);
247} 254}
248 255
249static struct kobj_type ktype_memctrl = { 256static struct kobj_type ktype_memctrl = {
@@ -309,8 +316,12 @@ static void edac_sysfs_memctrl_teardown(void)
309#ifndef DISABLE_EDAC_SYSFS 316#ifndef DISABLE_EDAC_SYSFS
310 debugf0("MC: " __FILE__ ": %s()\n", __func__); 317 debugf0("MC: " __FILE__ ": %s()\n", __func__);
311 318
312 /* Unregister the MC's kobject */ 319 /* Unregister the MC's kobject and wait for reference count to reach
320 * 0.
321 */
322 init_completion(&edac_memctrl_kobj_complete);
313 kobject_unregister(&edac_memctrl_kobj); 323 kobject_unregister(&edac_memctrl_kobj);
324 wait_for_completion(&edac_memctrl_kobj_complete);
314 325
315 /* Unregister the 'edac' object */ 326 /* Unregister the 'edac' object */
316 sysdev_class_unregister(&edac_class); 327 sysdev_class_unregister(&edac_class);
@@ -563,6 +574,7 @@ static struct edac_pci_dev_attribute *edac_pci_attr[] = {
563static void edac_pci_release(struct kobject *kobj) 574static void edac_pci_release(struct kobject *kobj)
564{ 575{
565 debugf1("%s()\n", __func__); 576 debugf1("%s()\n", __func__);
577 complete(&edac_pci_kobj_complete);
566} 578}
567 579
568static struct kobj_type ktype_edac_pci = { 580static struct kobj_type ktype_edac_pci = {
@@ -610,8 +622,9 @@ static void edac_sysfs_pci_teardown(void)
610{ 622{
611#ifndef DISABLE_EDAC_SYSFS 623#ifndef DISABLE_EDAC_SYSFS
612 debugf0("%s()\n", __func__); 624 debugf0("%s()\n", __func__);
613 625 init_completion(&edac_pci_kobj_complete);
614 kobject_unregister(&edac_pci_kobj); 626 kobject_unregister(&edac_pci_kobj);
627 wait_for_completion(&edac_pci_kobj_complete);
615#endif 628#endif
616} 629}
617 630
@@ -800,7 +813,11 @@ static struct csrowdev_attribute *csrow_attr[] = {
800/* No memory to release */ 813/* No memory to release */
801static void edac_csrow_instance_release(struct kobject *kobj) 814static void edac_csrow_instance_release(struct kobject *kobj)
802{ 815{
816 struct csrow_info *cs;
817
803 debugf1("%s()\n", __func__); 818 debugf1("%s()\n", __func__);
819 cs = container_of(kobj, struct csrow_info, kobj);
820 complete(&cs->kobj_complete);
804} 821}
805 822
806static struct kobj_type ktype_csrow = { 823static struct kobj_type ktype_csrow = {
@@ -1055,11 +1072,10 @@ static struct mcidev_attribute *mci_attr[] = {
1055static void edac_mci_instance_release(struct kobject *kobj) 1072static void edac_mci_instance_release(struct kobject *kobj)
1056{ 1073{
1057 struct mem_ctl_info *mci; 1074 struct mem_ctl_info *mci;
1058 mci = container_of(kobj,struct mem_ctl_info,edac_mci_kobj);
1059 1075
1060 debugf0("%s() idx=%d calling kfree\n", __func__, mci->mc_idx); 1076 mci = to_mci(kobj);
1061 1077 debugf0("%s() idx=%d\n", __func__, mci->mc_idx);
1062 kfree(mci); 1078 complete(&mci->kobj_complete);
1063} 1079}
1064 1080
1065static struct kobj_type ktype_mci = { 1081static struct kobj_type ktype_mci = {
@@ -1131,21 +1147,23 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
1131 } 1147 }
1132 } 1148 }
1133 1149
1134 /* Mark this MCI instance as having sysfs entries */
1135 mci->sysfs_active = MCI_SYSFS_ACTIVE;
1136
1137 return 0; 1150 return 0;
1138 1151
1139 1152
1140 /* CSROW error: backout what has already been registered, */ 1153 /* CSROW error: backout what has already been registered, */
1141fail1: 1154fail1:
1142 for ( i--; i >= 0; i--) { 1155 for ( i--; i >= 0; i--) {
1143 if (csrow->nr_pages > 0) 1156 if (csrow->nr_pages > 0) {
1157 init_completion(&csrow->kobj_complete);
1144 kobject_unregister(&mci->csrows[i].kobj); 1158 kobject_unregister(&mci->csrows[i].kobj);
1159 wait_for_completion(&csrow->kobj_complete);
1160 }
1145 } 1161 }
1146 1162
1147fail0: 1163fail0:
1164 init_completion(&mci->kobj_complete);
1148 kobject_unregister(edac_mci_kobj); 1165 kobject_unregister(edac_mci_kobj);
1166 wait_for_completion(&mci->kobj_complete);
1149 1167
1150 return err; 1168 return err;
1151} 1169}
@@ -1163,13 +1181,17 @@ static void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
1163 1181
1164 /* remove all csrow kobjects */ 1182 /* remove all csrow kobjects */
1165 for (i = 0; i < mci->nr_csrows; i++) { 1183 for (i = 0; i < mci->nr_csrows; i++) {
1166 if (mci->csrows[i].nr_pages > 0) 1184 if (mci->csrows[i].nr_pages > 0) {
1185 init_completion(&mci->csrows[i].kobj_complete);
1167 kobject_unregister(&mci->csrows[i].kobj); 1186 kobject_unregister(&mci->csrows[i].kobj);
1187 wait_for_completion(&mci->csrows[i].kobj_complete);
1188 }
1168 } 1189 }
1169 1190
1170 sysfs_remove_link(&mci->edac_mci_kobj, EDAC_DEVICE_SYMLINK); 1191 sysfs_remove_link(&mci->edac_mci_kobj, EDAC_DEVICE_SYMLINK);
1171 1192 init_completion(&mci->kobj_complete);
1172 kobject_unregister(&mci->edac_mci_kobj); 1193 kobject_unregister(&mci->edac_mci_kobj);
1194 wait_for_completion(&mci->kobj_complete);
1173#endif /* DISABLE_EDAC_SYSFS */ 1195#endif /* DISABLE_EDAC_SYSFS */
1174} 1196}
1175 1197
@@ -1342,31 +1364,10 @@ EXPORT_SYMBOL(edac_mc_free);
1342/** 1364/**
1343 * edac_mc_free: Free a previously allocated 'mci' structure 1365 * edac_mc_free: Free a previously allocated 'mci' structure
1344 * @mci: pointer to a struct mem_ctl_info structure 1366 * @mci: pointer to a struct mem_ctl_info structure
1345 *
1346 * Free up a previously allocated mci structure
1347 * A MCI structure can be in 2 states after being allocated
1348 * by edac_mc_alloc().
1349 * 1) Allocated in a MC driver's probe, but not yet committed
1350 * 2) Allocated and committed, by a call to edac_mc_add_mc()
1351 * edac_mc_add_mc() is the function that adds the sysfs entries
1352 * thus, this free function must determine which state the 'mci'
1353 * structure is in, then either free it directly or
1354 * perform kobject cleanup by calling edac_remove_sysfs_mci_device().
1355 *
1356 * VOID Return
1357 */ 1367 */
1358void edac_mc_free(struct mem_ctl_info *mci) 1368void edac_mc_free(struct mem_ctl_info *mci)
1359{ 1369{
1360 /* only if sysfs entries for this mci instance exist 1370 kfree(mci);
1361 * do we remove them and defer the actual kfree via
1362 * the kobject 'release()' callback.
1363 *
1364 * Otherwise, do a straight kfree now.
1365 */
1366 if (mci->sysfs_active == MCI_SYSFS_ACTIVE)
1367 edac_remove_sysfs_mci_device(mci);
1368 else
1369 kfree(mci);
1370} 1371}
1371 1372
1372 1373
@@ -1456,7 +1457,8 @@ static void del_mc_from_global_list (struct mem_ctl_info *mci)
1456EXPORT_SYMBOL(edac_mc_add_mc); 1457EXPORT_SYMBOL(edac_mc_add_mc);
1457 1458
1458/** 1459/**
1459 * edac_mc_add_mc: Insert the 'mci' structure into the mci global list 1460 * edac_mc_add_mc: Insert the 'mci' structure into the mci global list and
1461 * create sysfs entries associated with mci structure
1460 * @mci: pointer to the mci structure to be added to the list 1462 * @mci: pointer to the mci structure to be added to the list
1461 * 1463 *
1462 * Return: 1464 * Return:
@@ -1516,7 +1518,8 @@ fail0:
1516EXPORT_SYMBOL(edac_mc_del_mc); 1518EXPORT_SYMBOL(edac_mc_del_mc);
1517 1519
1518/** 1520/**
1519 * edac_mc_del_mc: Remove the specified mci structure from global list 1521 * edac_mc_del_mc: Remove sysfs entries for specified mci structure and
1522 * remove mci structure from global list
1520 * @mci: Pointer to struct mem_ctl_info structure 1523 * @mci: Pointer to struct mem_ctl_info structure
1521 * 1524 *
1522 * Returns: 1525 * Returns:
@@ -1528,6 +1531,7 @@ int edac_mc_del_mc(struct mem_ctl_info *mci)
1528 int rc = 1; 1531 int rc = 1;
1529 1532
1530 debugf0("MC%d: %s()\n", mci->mc_idx, __func__); 1533 debugf0("MC%d: %s()\n", mci->mc_idx, __func__);
1534 edac_remove_sysfs_mci_device(mci);
1531 down(&mem_ctls_mutex); 1535 down(&mem_ctls_mutex);
1532 del_mc_from_global_list(mci); 1536 del_mc_from_global_list(mci);
1533 edac_printk(KERN_INFO, EDAC_MC, 1537 edac_printk(KERN_INFO, EDAC_MC,
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
188enum 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