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>
This commit is contained in:
parent
fcd5c4dd82
commit
733476cf20
|
@ -256,7 +256,7 @@ int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev)
|
||||||
|
|
||||||
if (!try_module_get(edac_dev->owner)) {
|
if (!try_module_get(edac_dev->owner)) {
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
goto err_mod_get;
|
goto err_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* register */
|
/* register */
|
||||||
|
@ -282,9 +282,6 @@ int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev)
|
||||||
err_kobj_reg:
|
err_kobj_reg:
|
||||||
module_put(edac_dev->owner);
|
module_put(edac_dev->owner);
|
||||||
|
|
||||||
err_mod_get:
|
|
||||||
edac_put_sysfs_subsys();
|
|
||||||
|
|
||||||
err_out:
|
err_out:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -306,7 +303,6 @@ void edac_device_unregister_sysfs_main_kobj(struct edac_device_ctl_info *dev)
|
||||||
* b) 'kfree' the memory
|
* b) 'kfree' the memory
|
||||||
*/
|
*/
|
||||||
kobject_put(&dev->kobj);
|
kobject_put(&dev->kobj);
|
||||||
edac_put_sysfs_subsys();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* edac_dev -> instance information */
|
/* edac_dev -> instance information */
|
||||||
|
|
|
@ -1039,7 +1039,7 @@ int __init edac_mc_sysfs_init(void)
|
||||||
mci_pdev = kzalloc(sizeof(*mci_pdev), GFP_KERNEL);
|
mci_pdev = kzalloc(sizeof(*mci_pdev), GFP_KERNEL);
|
||||||
if (!mci_pdev) {
|
if (!mci_pdev) {
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto out_put_sysfs;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
mci_pdev->bus = edac_subsys;
|
mci_pdev->bus = edac_subsys;
|
||||||
|
@ -1057,8 +1057,6 @@ int __init edac_mc_sysfs_init(void)
|
||||||
|
|
||||||
out_dev_free:
|
out_dev_free:
|
||||||
kfree(mci_pdev);
|
kfree(mci_pdev);
|
||||||
out_put_sysfs:
|
|
||||||
edac_put_sysfs_subsys();
|
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -1066,5 +1064,4 @@ int __init edac_mc_sysfs_init(void)
|
||||||
void edac_mc_sysfs_exit(void)
|
void edac_mc_sysfs_exit(void)
|
||||||
{
|
{
|
||||||
device_unregister(mci_pdev);
|
device_unregister(mci_pdev);
|
||||||
edac_put_sysfs_subsys();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,39 @@ static void edac_workqueue_teardown(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sysfs object: /sys/devices/system/edac
|
||||||
|
* need to export to other files
|
||||||
|
*/
|
||||||
|
struct bus_type edac_subsys = {
|
||||||
|
.name = "edac",
|
||||||
|
.dev_name = "edac",
|
||||||
|
};
|
||||||
|
EXPORT_SYMBOL_GPL(edac_subsys);
|
||||||
|
|
||||||
|
static int edac_subsys_init(void)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
/* create the /sys/devices/system/edac directory */
|
||||||
|
err = subsys_system_register(&edac_subsys, NULL);
|
||||||
|
if (err)
|
||||||
|
printk(KERN_ERR "Error registering toplevel EDAC sysfs dir\n");
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void edac_subsys_exit(void)
|
||||||
|
{
|
||||||
|
bus_unregister(&edac_subsys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return pointer to the 'edac' node in sysfs */
|
||||||
|
struct bus_type *edac_get_sysfs_subsys(void)
|
||||||
|
{
|
||||||
|
return &edac_subsys;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(edac_get_sysfs_subsys);
|
||||||
/*
|
/*
|
||||||
* edac_init
|
* edac_init
|
||||||
* module initialization entry point
|
* module initialization entry point
|
||||||
|
@ -101,6 +134,10 @@ static int __init edac_init(void)
|
||||||
|
|
||||||
edac_printk(KERN_INFO, EDAC_MC, EDAC_VERSION "\n");
|
edac_printk(KERN_INFO, EDAC_MC, EDAC_VERSION "\n");
|
||||||
|
|
||||||
|
err = edac_subsys_init();
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Harvest and clear any boot/initialization PCI parity errors
|
* Harvest and clear any boot/initialization PCI parity errors
|
||||||
*
|
*
|
||||||
|
@ -129,6 +166,8 @@ err_wq:
|
||||||
edac_mc_sysfs_exit();
|
edac_mc_sysfs_exit();
|
||||||
|
|
||||||
err_sysfs:
|
err_sysfs:
|
||||||
|
edac_subsys_exit();
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,6 +183,7 @@ static void __exit edac_exit(void)
|
||||||
edac_workqueue_teardown();
|
edac_workqueue_teardown();
|
||||||
edac_mc_sysfs_exit();
|
edac_mc_sysfs_exit();
|
||||||
edac_debugfs_exit();
|
edac_debugfs_exit();
|
||||||
|
edac_subsys_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -364,7 +364,7 @@ static int edac_pci_main_kobj_setup(void)
|
||||||
if (!try_module_get(THIS_MODULE)) {
|
if (!try_module_get(THIS_MODULE)) {
|
||||||
edac_dbg(1, "try_module_get() failed\n");
|
edac_dbg(1, "try_module_get() failed\n");
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
goto mod_get_fail;
|
goto decrement_count_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
edac_pci_top_main_kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL);
|
edac_pci_top_main_kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL);
|
||||||
|
@ -399,9 +399,6 @@ kobject_init_and_add_fail:
|
||||||
kzalloc_fail:
|
kzalloc_fail:
|
||||||
module_put(THIS_MODULE);
|
module_put(THIS_MODULE);
|
||||||
|
|
||||||
mod_get_fail:
|
|
||||||
edac_put_sysfs_subsys();
|
|
||||||
|
|
||||||
decrement_count_fail:
|
decrement_count_fail:
|
||||||
/* if are on this error exit, nothing to tear down */
|
/* if are on this error exit, nothing to tear down */
|
||||||
atomic_dec(&edac_pci_sysfs_refcount);
|
atomic_dec(&edac_pci_sysfs_refcount);
|
||||||
|
@ -426,7 +423,6 @@ static void edac_pci_main_kobj_teardown(void)
|
||||||
if (atomic_dec_return(&edac_pci_sysfs_refcount) == 0) {
|
if (atomic_dec_return(&edac_pci_sysfs_refcount) == 0) {
|
||||||
edac_dbg(0, "called kobject_put on main kobj\n");
|
edac_dbg(0, "called kobject_put on main kobj\n");
|
||||||
kobject_put(edac_pci_top_main_kobj);
|
kobject_put(edac_pci_top_main_kobj);
|
||||||
edac_put_sysfs_subsys();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,6 @@ EXPORT_SYMBOL_GPL(edac_handlers);
|
||||||
int edac_err_assert = 0;
|
int edac_err_assert = 0;
|
||||||
EXPORT_SYMBOL_GPL(edac_err_assert);
|
EXPORT_SYMBOL_GPL(edac_err_assert);
|
||||||
|
|
||||||
static atomic_t edac_subsys_valid = ATOMIC_INIT(0);
|
|
||||||
|
|
||||||
int edac_report_status = EDAC_REPORTING_ENABLED;
|
int edac_report_status = EDAC_REPORTING_ENABLED;
|
||||||
EXPORT_SYMBOL_GPL(edac_report_status);
|
EXPORT_SYMBOL_GPL(edac_report_status);
|
||||||
|
|
||||||
|
@ -68,42 +66,3 @@ void edac_atomic_assert_error(void)
|
||||||
edac_err_assert++;
|
edac_err_assert++;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(edac_atomic_assert_error);
|
EXPORT_SYMBOL_GPL(edac_atomic_assert_error);
|
||||||
|
|
||||||
/*
|
|
||||||
* sysfs object: /sys/devices/system/edac
|
|
||||||
* need to export to other files
|
|
||||||
*/
|
|
||||||
struct bus_type edac_subsys = {
|
|
||||||
.name = "edac",
|
|
||||||
.dev_name = "edac",
|
|
||||||
};
|
|
||||||
EXPORT_SYMBOL_GPL(edac_subsys);
|
|
||||||
|
|
||||||
/* return pointer to the 'edac' node in sysfs */
|
|
||||||
struct bus_type *edac_get_sysfs_subsys(void)
|
|
||||||
{
|
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
if (atomic_read(&edac_subsys_valid))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* create the /sys/devices/system/edac directory */
|
|
||||||
err = subsys_system_register(&edac_subsys, NULL);
|
|
||||||
if (err) {
|
|
||||||
printk(KERN_ERR "Error registering toplevel EDAC sysfs dir\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
atomic_inc(&edac_subsys_valid);
|
|
||||||
return &edac_subsys;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(edac_get_sysfs_subsys);
|
|
||||||
|
|
||||||
void edac_put_sysfs_subsys(void)
|
|
||||||
{
|
|
||||||
/* last user unregisters it */
|
|
||||||
if (atomic_dec_and_test(&edac_subsys_valid))
|
|
||||||
bus_unregister(&edac_subsys);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(edac_put_sysfs_subsys);
|
|
||||||
|
|
|
@ -33,7 +33,6 @@ extern struct bus_type edac_subsys;
|
||||||
extern int edac_handler_set(void);
|
extern int edac_handler_set(void);
|
||||||
extern void edac_atomic_assert_error(void);
|
extern void edac_atomic_assert_error(void);
|
||||||
extern struct bus_type *edac_get_sysfs_subsys(void);
|
extern struct bus_type *edac_get_sysfs_subsys(void);
|
||||||
extern void edac_put_sysfs_subsys(void);
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
EDAC_REPORTING_ENABLED,
|
EDAC_REPORTING_ENABLED,
|
||||||
|
|
Loading…
Reference in New Issue