diff options
author | Roland Dreier <rolandd@cisco.com> | 2008-02-13 01:38:27 +0300 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2008-02-13 01:38:27 +0300 |
commit | 7c7a9bccd2ba9f17e4b588461f140578a0a7b073 (patch) | |
tree | 97a8a5e88339a5defa770c19466190b8a20c0943 /drivers/infiniband | |
parent | ab64b960673250518e748f8b4f1545447136b68b (diff) | |
download | linux-7c7a9bccd2ba9f17e4b588461f140578a0a7b073.tar.xz |
IB/cm: Fix infiniband_cm class kobject ref counting
Commit 9af57b7a ("IB/cm: Add basic performance counters") introduced a
bug in how the reference count for cm_class.subsys.kobj was handled:
the path that released a device did a kobject_put() on that kobject, but
there was no kobject_get() in the path the handles adding a device. So
the reference count ended up too low, which leads to bad things. Fix up
and simplify the reference counting to avoid this.
(Actually, I introduced the bug when fixing the patch up to match some
of Greg's kobject changes, but who's counting)
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/core/cm.c | 22 |
1 files changed, 8 insertions, 14 deletions
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 435e2767a183..b10ade92efed 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -3612,18 +3612,12 @@ struct class cm_class = { }; EXPORT_SYMBOL(cm_class); -static void cm_remove_fs_obj(struct kobject *obj) -{ - kobject_put(obj->parent); - kobject_put(obj); -} - static int cm_create_port_fs(struct cm_port *port) { int i, ret; ret = kobject_init_and_add(&port->port_obj, &cm_port_obj_type, - kobject_get(&port->cm_dev->dev_obj), + &port->cm_dev->dev_obj, "%d", port->port_num); if (ret) { kfree(port); @@ -3633,7 +3627,7 @@ static int cm_create_port_fs(struct cm_port *port) for (i = 0; i < CM_COUNTER_GROUPS; i++) { ret = kobject_init_and_add(&port->counter_group[i].obj, &cm_counter_obj_type, - kobject_get(&port->port_obj), + &port->port_obj, "%s", counter_group_names[i]); if (ret) goto error; @@ -3643,8 +3637,8 @@ static int cm_create_port_fs(struct cm_port *port) error: while (i--) - cm_remove_fs_obj(&port->counter_group[i].obj); - cm_remove_fs_obj(&port->port_obj); + kobject_put(&port->counter_group[i].obj); + kobject_put(&port->port_obj); return ret; } @@ -3654,9 +3648,9 @@ static void cm_remove_port_fs(struct cm_port *port) int i; for (i = 0; i < CM_COUNTER_GROUPS; i++) - cm_remove_fs_obj(&port->counter_group[i].obj); + kobject_put(&port->counter_group[i].obj); - cm_remove_fs_obj(&port->port_obj); + kobject_put(&port->port_obj); } static void cm_add_one(struct ib_device *device) @@ -3740,7 +3734,7 @@ error1: ib_unregister_mad_agent(port->mad_agent); cm_remove_port_fs(port); } - cm_remove_fs_obj(&cm_dev->dev_obj); + kobject_put(&cm_dev->dev_obj); } static void cm_remove_one(struct ib_device *device) @@ -3767,7 +3761,7 @@ static void cm_remove_one(struct ib_device *device) ib_unregister_mad_agent(port->mad_agent); cm_remove_port_fs(port); } - cm_remove_fs_obj(&cm_dev->dev_obj); + kobject_put(&cm_dev->dev_obj); } static int __init ib_cm_init(void) |