aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBorislav Petkov <bp@suse.de>2015-11-27 05:40:43 -0500
committerBorislav Petkov <bp@suse.de>2015-12-11 10:56:39 -0500
commit733476cf207faf574b132523ff2aee78b488ed6b (patch)
treef0d455a00d75370ae2bfef8572ade0c73e748f9c
parentfcd5c4dd8201595d4c598c9cca5e54760277d687 (diff)
EDAC: Rip out the edac_subsys reference counting
This was really dumb - reference counting for the main EDAC sysfs object. While we could've simply registered it as the first thing in the module init path and then hand it around to what needs it. Do that and rip out all the code around it, thus simplifying the whole handling significantly. Move the edac_subsys node back to edac_module.c. Signed-off-by: Borislav Petkov <bp@suse.de>
-rw-r--r--drivers/edac/edac_device_sysfs.c6
-rw-r--r--drivers/edac/edac_mc_sysfs.c5
-rw-r--r--drivers/edac/edac_module.c40
-rw-r--r--drivers/edac/edac_pci_sysfs.c6
-rw-r--r--drivers/edac/edac_stub.c41
-rw-r--r--include/linux/edac.h1
6 files changed, 43 insertions, 56 deletions
diff --git a/drivers/edac/edac_device_sysfs.c b/drivers/edac/edac_device_sysfs.c
index fb68a06ad683..170527165374 100644
--- a/drivers/edac/edac_device_sysfs.c
+++ b/drivers/edac/edac_device_sysfs.c
@@ -256,7 +256,7 @@ int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev)
256 256
257 if (!try_module_get(edac_dev->owner)) { 257 if (!try_module_get(edac_dev->owner)) {
258 err = -ENODEV; 258 err = -ENODEV;
259 goto err_mod_get; 259 goto err_out;
260 } 260 }
261 261
262 /* register */ 262 /* register */
@@ -282,9 +282,6 @@ int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev)
282err_kobj_reg: 282err_kobj_reg:
283 module_put(edac_dev->owner); 283 module_put(edac_dev->owner);
284 284
285err_mod_get:
286 edac_put_sysfs_subsys();
287
288err_out: 285err_out:
289 return err; 286 return err;
290} 287}
@@ -306,7 +303,6 @@ void edac_device_unregister_sysfs_main_kobj(struct edac_device_ctl_info *dev)
306 * b) 'kfree' the memory 303 * b) 'kfree' the memory
307 */ 304 */
308 kobject_put(&dev->kobj); 305 kobject_put(&dev->kobj);
309 edac_put_sysfs_subsys();
310} 306}
311 307
312/* edac_dev -> instance information */ 308/* edac_dev -> instance information */
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
index 58aed67b7eba..1c79ae3e083a 100644
--- a/drivers/edac/edac_mc_sysfs.c
+++ b/drivers/edac/edac_mc_sysfs.c
@@ -1039,7 +1039,7 @@ int __init edac_mc_sysfs_init(void)
1039 mci_pdev = kzalloc(sizeof(*mci_pdev), GFP_KERNEL); 1039 mci_pdev = kzalloc(sizeof(*mci_pdev), GFP_KERNEL);
1040 if (!mci_pdev) { 1040 if (!mci_pdev) {
1041 err = -ENOMEM; 1041 err = -ENOMEM;
1042 goto out_put_sysfs; 1042 goto out;
1043 } 1043 }
1044 1044
1045 mci_pdev->bus = edac_subsys; 1045 mci_pdev->bus = edac_subsys;
@@ -1057,8 +1057,6 @@ int __init edac_mc_sysfs_init(void)
1057 1057
1058 out_dev_free: 1058 out_dev_free:
1059 kfree(mci_pdev); 1059 kfree(mci_pdev);
1060 out_put_sysfs:
1061 edac_put_sysfs_subsys();
1062 out: 1060 out:
1063 return err; 1061 return err;
1064} 1062}
@@ -1066,5 +1064,4 @@ int __init edac_mc_sysfs_init(void)
1066void edac_mc_sysfs_exit(void) 1064void edac_mc_sysfs_exit(void)
1067{ 1065{
1068 device_unregister(mci_pdev); 1066 device_unregister(mci_pdev);
1069 edac_put_sysfs_subsys();
1070} 1067}
diff --git a/drivers/edac/edac_module.c b/drivers/edac/edac_module.c
index 9cb082a19d8a..059b5924988b 100644
--- a/drivers/edac/edac_module.c
+++ b/drivers/edac/edac_module.c
@@ -92,6 +92,39 @@ static void edac_workqueue_teardown(void)
92} 92}
93 93
94/* 94/*
95 * sysfs object: /sys/devices/system/edac
96 * need to export to other files
97 */
98struct bus_type edac_subsys = {
99 .name = "edac",
100 .dev_name = "edac",
101};
102EXPORT_SYMBOL_GPL(edac_subsys);
103
104static int edac_subsys_init(void)
105{
106 int err;
107
108 /* create the /sys/devices/system/edac directory */
109 err = subsys_system_register(&edac_subsys, NULL);
110 if (err)
111 printk(KERN_ERR "Error registering toplevel EDAC sysfs dir\n");
112
113 return err;
114}
115
116static void edac_subsys_exit(void)
117{
118 bus_unregister(&edac_subsys);
119}
120
121/* return pointer to the 'edac' node in sysfs */
122struct bus_type *edac_get_sysfs_subsys(void)
123{
124 return &edac_subsys;
125}
126EXPORT_SYMBOL_GPL(edac_get_sysfs_subsys);
127/*
95 * edac_init 128 * edac_init
96 * module initialization entry point 129 * module initialization entry point
97 */ 130 */
@@ -101,6 +134,10 @@ static int __init edac_init(void)
101 134
102 edac_printk(KERN_INFO, EDAC_MC, EDAC_VERSION "\n"); 135 edac_printk(KERN_INFO, EDAC_MC, EDAC_VERSION "\n");
103 136
137 err = edac_subsys_init();
138 if (err)
139 return err;
140
104 /* 141 /*
105 * Harvest and clear any boot/initialization PCI parity errors 142 * Harvest and clear any boot/initialization PCI parity errors
106 * 143 *
@@ -129,6 +166,8 @@ err_wq:
129 edac_mc_sysfs_exit(); 166 edac_mc_sysfs_exit();
130 167
131err_sysfs: 168err_sysfs:
169 edac_subsys_exit();
170
132 return err; 171 return err;
133} 172}
134 173
@@ -144,6 +183,7 @@ static void __exit edac_exit(void)
144 edac_workqueue_teardown(); 183 edac_workqueue_teardown();
145 edac_mc_sysfs_exit(); 184 edac_mc_sysfs_exit();
146 edac_debugfs_exit(); 185 edac_debugfs_exit();
186 edac_subsys_exit();
147} 187}
148 188
149/* 189/*
diff --git a/drivers/edac/edac_pci_sysfs.c b/drivers/edac/edac_pci_sysfs.c
index 24d877f6e577..262f56cca9ff 100644
--- a/drivers/edac/edac_pci_sysfs.c
+++ b/drivers/edac/edac_pci_sysfs.c
@@ -364,7 +364,7 @@ static int edac_pci_main_kobj_setup(void)
364 if (!try_module_get(THIS_MODULE)) { 364 if (!try_module_get(THIS_MODULE)) {
365 edac_dbg(1, "try_module_get() failed\n"); 365 edac_dbg(1, "try_module_get() failed\n");
366 err = -ENODEV; 366 err = -ENODEV;
367 goto mod_get_fail; 367 goto decrement_count_fail;
368 } 368 }
369 369
370 edac_pci_top_main_kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL); 370 edac_pci_top_main_kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL);
@@ -399,9 +399,6 @@ kobject_init_and_add_fail:
399kzalloc_fail: 399kzalloc_fail:
400 module_put(THIS_MODULE); 400 module_put(THIS_MODULE);
401 401
402mod_get_fail:
403 edac_put_sysfs_subsys();
404
405decrement_count_fail: 402decrement_count_fail:
406 /* if are on this error exit, nothing to tear down */ 403 /* if are on this error exit, nothing to tear down */
407 atomic_dec(&edac_pci_sysfs_refcount); 404 atomic_dec(&edac_pci_sysfs_refcount);
@@ -426,7 +423,6 @@ static void edac_pci_main_kobj_teardown(void)
426 if (atomic_dec_return(&edac_pci_sysfs_refcount) == 0) { 423 if (atomic_dec_return(&edac_pci_sysfs_refcount) == 0) {
427 edac_dbg(0, "called kobject_put on main kobj\n"); 424 edac_dbg(0, "called kobject_put on main kobj\n");
428 kobject_put(edac_pci_top_main_kobj); 425 kobject_put(edac_pci_top_main_kobj);
429 edac_put_sysfs_subsys();
430 } 426 }
431} 427}
432 428
diff --git a/drivers/edac/edac_stub.c b/drivers/edac/edac_stub.c
index ff07aae5b7fb..952e411f01f2 100644
--- a/drivers/edac/edac_stub.c
+++ b/drivers/edac/edac_stub.c
@@ -26,8 +26,6 @@ EXPORT_SYMBOL_GPL(edac_handlers);
26int edac_err_assert = 0; 26int edac_err_assert = 0;
27EXPORT_SYMBOL_GPL(edac_err_assert); 27EXPORT_SYMBOL_GPL(edac_err_assert);
28 28
29static atomic_t edac_subsys_valid = ATOMIC_INIT(0);
30
31int edac_report_status = EDAC_REPORTING_ENABLED; 29int edac_report_status = EDAC_REPORTING_ENABLED;
32EXPORT_SYMBOL_GPL(edac_report_status); 30EXPORT_SYMBOL_GPL(edac_report_status);
33 31
@@ -68,42 +66,3 @@ void edac_atomic_assert_error(void)
68 edac_err_assert++; 66 edac_err_assert++;
69} 67}
70EXPORT_SYMBOL_GPL(edac_atomic_assert_error); 68EXPORT_SYMBOL_GPL(edac_atomic_assert_error);
71
72/*
73 * sysfs object: /sys/devices/system/edac
74 * need to export to other files
75 */
76struct bus_type edac_subsys = {
77 .name = "edac",
78 .dev_name = "edac",
79};
80EXPORT_SYMBOL_GPL(edac_subsys);
81
82/* return pointer to the 'edac' node in sysfs */
83struct bus_type *edac_get_sysfs_subsys(void)
84{
85 int err = 0;
86
87 if (atomic_read(&edac_subsys_valid))
88 goto out;
89
90 /* create the /sys/devices/system/edac directory */
91 err = subsys_system_register(&edac_subsys, NULL);
92 if (err) {
93 printk(KERN_ERR "Error registering toplevel EDAC sysfs dir\n");
94 return NULL;
95 }
96
97out:
98 atomic_inc(&edac_subsys_valid);
99 return &edac_subsys;
100}
101EXPORT_SYMBOL_GPL(edac_get_sysfs_subsys);
102
103void edac_put_sysfs_subsys(void)
104{
105 /* last user unregisters it */
106 if (atomic_dec_and_test(&edac_subsys_valid))
107 bus_unregister(&edac_subsys);
108}
109EXPORT_SYMBOL_GPL(edac_put_sysfs_subsys);
diff --git a/include/linux/edac.h b/include/linux/edac.h
index da6964873dcf..98f915dfeeac 100644
--- a/include/linux/edac.h
+++ b/include/linux/edac.h
@@ -33,7 +33,6 @@ extern struct bus_type edac_subsys;
33extern int edac_handler_set(void); 33extern int edac_handler_set(void);
34extern void edac_atomic_assert_error(void); 34extern void edac_atomic_assert_error(void);
35extern struct bus_type *edac_get_sysfs_subsys(void); 35extern struct bus_type *edac_get_sysfs_subsys(void);
36extern void edac_put_sysfs_subsys(void);
37 36
38enum { 37enum {
39 EDAC_REPORTING_ENABLED, 38 EDAC_REPORTING_ENABLED,