mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-11-01 17:08:10 +00:00
software node: Free resources explicitly when swnode_register() fails
Currently we have a slightly twisted logic in swnode_register(). It frees resources that it doesn't allocate on error path and in once case it relies on the ->release() implementation. Untwist the logic by freeing resources explicitly when swnode_register() fails. Currently it happens only in fwnode_create_software_node(). Tested-by: Daniel Scally <djrscally@gmail.com> Reviewed-by: Daniel Scally <djrscally@gmail.com> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Link: https://lore.kernel.org/r/20210329151207.36619-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
c8a9c285f1
commit
3f6b6536a7
1 changed files with 17 additions and 12 deletions
|
@ -767,22 +767,19 @@ swnode_register(const struct software_node *node, struct swnode *parent,
|
|||
int ret;
|
||||
|
||||
swnode = kzalloc(sizeof(*swnode), GFP_KERNEL);
|
||||
if (!swnode) {
|
||||
ret = -ENOMEM;
|
||||
goto out_err;
|
||||
}
|
||||
if (!swnode)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ret = ida_simple_get(parent ? &parent->child_ids : &swnode_root_ids,
|
||||
0, 0, GFP_KERNEL);
|
||||
if (ret < 0) {
|
||||
kfree(swnode);
|
||||
goto out_err;
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
swnode->id = ret;
|
||||
swnode->node = node;
|
||||
swnode->parent = parent;
|
||||
swnode->allocated = allocated;
|
||||
swnode->kobj.kset = swnode_kset;
|
||||
fwnode_init(&swnode->fwnode, &software_node_ops);
|
||||
|
||||
|
@ -803,16 +800,17 @@ swnode_register(const struct software_node *node, struct swnode *parent,
|
|||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Assign the flag only in the successful case, so
|
||||
* the above kobject_put() won't mess up with properties.
|
||||
*/
|
||||
swnode->allocated = allocated;
|
||||
|
||||
if (parent)
|
||||
list_add_tail(&swnode->entry, &parent->children);
|
||||
|
||||
kobject_uevent(&swnode->kobj, KOBJ_ADD);
|
||||
return &swnode->fwnode;
|
||||
|
||||
out_err:
|
||||
if (allocated)
|
||||
property_entries_free(node->properties);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -971,6 +969,7 @@ struct fwnode_handle *
|
|||
fwnode_create_software_node(const struct property_entry *properties,
|
||||
const struct fwnode_handle *parent)
|
||||
{
|
||||
struct fwnode_handle *fwnode;
|
||||
struct software_node *node;
|
||||
struct swnode *p = NULL;
|
||||
int ret;
|
||||
|
@ -995,7 +994,13 @@ fwnode_create_software_node(const struct property_entry *properties,
|
|||
|
||||
node->parent = p ? p->node : NULL;
|
||||
|
||||
return swnode_register(node, p, 1);
|
||||
fwnode = swnode_register(node, p, 1);
|
||||
if (IS_ERR(fwnode)) {
|
||||
property_entries_free(node->properties);
|
||||
kfree(node);
|
||||
}
|
||||
|
||||
return fwnode;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fwnode_create_software_node);
|
||||
|
||||
|
|
Loading…
Reference in a new issue