drivers: cacheinfo: use __free attribute instead of of_node_put()
Introduce the __free attribute for scope-based resource management. Resources allocated with __free are automatically released at the end of the scope. This enhancement aims to mitigate memory management issues associated with forgetting to release resources by utilizing __free instead of of_node_put(). To introduce this feature, some modifications to the code structure were necessary. The original pattern: ``` prev = np; while(...) { [...] np = of_find_next_cache_node(np); of_node_put(prev); prev = np; [...] } ``` has been updated to: ``` while(...) { [...] struct device_node __free(device_node) *prev = np; np = of_find_next_cache_node(np) [...] } ``` With this change, the previous node is automatically cleaned up at the end of each iteration, allowing the elimination of all of_node_put() calls and some goto statements. Suggested-by: Julia Lawall <julia.lawall@inria.fr> Signed-off-by: Vincenzo Mezzela <vincenzo.mezzela@gmail.com> Link: https://lore.kernel.org/r/20240719151335.869145-1-vincenzo.mezzela@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
30b968b002
commit
1b48fbbc03
@ -202,29 +202,24 @@ static void cache_of_set_props(struct cacheinfo *this_leaf,
|
||||
|
||||
static int cache_setup_of_node(unsigned int cpu)
|
||||
{
|
||||
struct device_node *np, *prev;
|
||||
struct cacheinfo *this_leaf;
|
||||
unsigned int index = 0;
|
||||
|
||||
np = of_cpu_device_node_get(cpu);
|
||||
struct device_node *np __free(device_node) = of_cpu_device_node_get(cpu);
|
||||
if (!np) {
|
||||
pr_err("Failed to find cpu%d device node\n", cpu);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (!of_check_cache_nodes(np)) {
|
||||
of_node_put(np);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
prev = np;
|
||||
|
||||
while (index < cache_leaves(cpu)) {
|
||||
this_leaf = per_cpu_cacheinfo_idx(cpu, index);
|
||||
if (this_leaf->level != 1) {
|
||||
struct device_node *prev __free(device_node) = np;
|
||||
np = of_find_next_cache_node(np);
|
||||
of_node_put(prev);
|
||||
prev = np;
|
||||
if (!np)
|
||||
break;
|
||||
}
|
||||
@ -233,8 +228,6 @@ static int cache_setup_of_node(unsigned int cpu)
|
||||
index++;
|
||||
}
|
||||
|
||||
of_node_put(np);
|
||||
|
||||
if (index != cache_leaves(cpu)) /* not all OF nodes populated */
|
||||
return -ENOENT;
|
||||
|
||||
@ -243,17 +236,14 @@ static int cache_setup_of_node(unsigned int cpu)
|
||||
|
||||
static bool of_check_cache_nodes(struct device_node *np)
|
||||
{
|
||||
struct device_node *next;
|
||||
|
||||
if (of_property_present(np, "cache-size") ||
|
||||
of_property_present(np, "i-cache-size") ||
|
||||
of_property_present(np, "d-cache-size") ||
|
||||
of_property_present(np, "cache-unified"))
|
||||
return true;
|
||||
|
||||
next = of_find_next_cache_node(np);
|
||||
struct device_node *next __free(device_node) = of_find_next_cache_node(np);
|
||||
if (next) {
|
||||
of_node_put(next);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -287,12 +277,10 @@ static int of_count_cache_leaves(struct device_node *np)
|
||||
int init_of_cache_level(unsigned int cpu)
|
||||
{
|
||||
struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
|
||||
struct device_node *np = of_cpu_device_node_get(cpu);
|
||||
struct device_node *prev = NULL;
|
||||
struct device_node *np __free(device_node) = of_cpu_device_node_get(cpu);
|
||||
unsigned int levels = 0, leaves, level;
|
||||
|
||||
if (!of_check_cache_nodes(np)) {
|
||||
of_node_put(np);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
@ -300,30 +288,27 @@ int init_of_cache_level(unsigned int cpu)
|
||||
if (leaves > 0)
|
||||
levels = 1;
|
||||
|
||||
prev = np;
|
||||
while ((np = of_find_next_cache_node(np))) {
|
||||
of_node_put(prev);
|
||||
prev = np;
|
||||
while (1) {
|
||||
struct device_node *prev __free(device_node) = np;
|
||||
np = of_find_next_cache_node(np);
|
||||
if (!np)
|
||||
break;
|
||||
|
||||
if (!of_device_is_compatible(np, "cache"))
|
||||
goto err_out;
|
||||
return -EINVAL;
|
||||
if (of_property_read_u32(np, "cache-level", &level))
|
||||
goto err_out;
|
||||
return -EINVAL;
|
||||
if (level <= levels)
|
||||
goto err_out;
|
||||
return -EINVAL;
|
||||
|
||||
leaves += of_count_cache_leaves(np);
|
||||
levels = level;
|
||||
}
|
||||
|
||||
of_node_put(np);
|
||||
this_cpu_ci->num_levels = levels;
|
||||
this_cpu_ci->num_leaves = leaves;
|
||||
|
||||
return 0;
|
||||
|
||||
err_out:
|
||||
of_node_put(np);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
Loading…
Reference in New Issue
Block a user