* [PATCH 0/2] rv: Tidy up with auto-cleanup
@ 2025-11-16 15:35 Nam Cao
2025-11-16 15:35 ` [PATCH 1/2] rv: Convert to use lock guard Nam Cao
2025-11-16 15:35 ` [PATCH 2/2] rv: Convert to use __free Nam Cao
0 siblings, 2 replies; 7+ messages in thread
From: Nam Cao @ 2025-11-16 15:35 UTC (permalink / raw)
To: Gabriele Monaco, Steven Rostedt
Cc: Masami Hiramatsu, Mathieu Desnoyers, linux-trace-kernel,
linux-kernel, Nam Cao
This series tidies up rv code with __free and lock guard. This is motivated
by a bug:
https://lore.kernel.org/all/20250903065112.1878330-1-zhen.ni@easystack.cn/
which was caused by a missing mutex_unlock. This series makes such bug less
likely in the future, and also reduces some code lines.
Nam Cao (2):
rv: Convert to use lock guard
rv: Convert to use __free
kernel/trace/rv/rv.c | 104 ++++++++++++++--------------------
kernel/trace/rv/rv.h | 6 +-
kernel/trace/rv/rv_reactors.c | 58 +++++++------------
3 files changed, 66 insertions(+), 102 deletions(-)
--
2.51.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/2] rv: Convert to use lock guard
2025-11-16 15:35 [PATCH 0/2] rv: Tidy up with auto-cleanup Nam Cao
@ 2025-11-16 15:35 ` Nam Cao
2025-11-16 15:35 ` [PATCH 2/2] rv: Convert to use __free Nam Cao
1 sibling, 0 replies; 7+ messages in thread
From: Nam Cao @ 2025-11-16 15:35 UTC (permalink / raw)
To: Gabriele Monaco, Steven Rostedt
Cc: Masami Hiramatsu, Mathieu Desnoyers, linux-trace-kernel,
linux-kernel, Nam Cao
Convert to use lock guard to tidy up the code.
Signed-off-by: Nam Cao <namcao@linutronix.de>
---
kernel/trace/rv/rv.c | 39 ++++++++++++-----------------------
kernel/trace/rv/rv_reactors.c | 26 +++++++----------------
2 files changed, 20 insertions(+), 45 deletions(-)
diff --git a/kernel/trace/rv/rv.c b/kernel/trace/rv/rv.c
index 43e9ea473cda..b1059a3cf4fa 100644
--- a/kernel/trace/rv/rv.c
+++ b/kernel/trace/rv/rv.c
@@ -375,15 +375,13 @@ static ssize_t monitor_enable_write_data(struct file *filp, const char __user *u
if (retval)
return retval;
- mutex_lock(&rv_interface_lock);
+ guard(mutex)(&rv_interface_lock);
if (val)
retval = rv_enable_monitor(mon);
else
retval = rv_disable_monitor(mon);
- mutex_unlock(&rv_interface_lock);
-
return retval ? : count;
}
@@ -568,7 +566,7 @@ static void disable_all_monitors(void)
struct rv_monitor *mon;
int enabled = 0;
- mutex_lock(&rv_interface_lock);
+ guard(mutex)(&rv_interface_lock);
list_for_each_entry(mon, &rv_monitors_list, list)
enabled += __rv_disable_monitor(mon, false);
@@ -581,8 +579,6 @@ static void disable_all_monitors(void)
*/
tracepoint_synchronize_unregister();
}
-
- mutex_unlock(&rv_interface_lock);
}
static int enabled_monitors_open(struct inode *inode, struct file *file)
@@ -623,7 +619,7 @@ static ssize_t enabled_monitors_write(struct file *filp, const char __user *user
if (!len)
return count;
- mutex_lock(&rv_interface_lock);
+ guard(mutex)(&rv_interface_lock);
retval = -EINVAL;
@@ -644,13 +640,11 @@ static ssize_t enabled_monitors_write(struct file *filp, const char __user *user
else
retval = rv_disable_monitor(mon);
- if (!retval)
- retval = count;
-
- break;
+ if (retval)
+ return retval;
+ return count;
}
- mutex_unlock(&rv_interface_lock);
return retval;
}
@@ -737,7 +731,7 @@ static ssize_t monitoring_on_write_data(struct file *filp, const char __user *us
if (retval)
return retval;
- mutex_lock(&rv_interface_lock);
+ guard(mutex)(&rv_interface_lock);
if (val)
turn_monitoring_on_with_reset();
@@ -750,8 +744,6 @@ static ssize_t monitoring_on_write_data(struct file *filp, const char __user *us
*/
tracepoint_synchronize_unregister();
- mutex_unlock(&rv_interface_lock);
-
return count;
}
@@ -784,28 +776,26 @@ int rv_register_monitor(struct rv_monitor *monitor, struct rv_monitor *parent)
return -EINVAL;
}
- mutex_lock(&rv_interface_lock);
+ guard(mutex)(&rv_interface_lock);
list_for_each_entry(r, &rv_monitors_list, list) {
if (strcmp(monitor->name, r->name) == 0) {
pr_info("Monitor %s is already registered\n", monitor->name);
- retval = -EEXIST;
- goto out_unlock;
+ return -EEXIST;
}
}
if (parent && rv_is_nested_monitor(parent)) {
pr_info("Parent monitor %s is already nested, cannot nest further\n",
parent->name);
- retval = -EINVAL;
- goto out_unlock;
+ return -EINVAL;
}
monitor->parent = parent;
retval = create_monitor_dir(monitor, parent);
if (retval)
- goto out_unlock;
+ return retval;
/* keep children close to the parent for easier visualisation */
if (parent)
@@ -813,9 +803,7 @@ int rv_register_monitor(struct rv_monitor *monitor, struct rv_monitor *parent)
else
list_add_tail(&monitor->list, &rv_monitors_list);
-out_unlock:
- mutex_unlock(&rv_interface_lock);
- return retval;
+ return 0;
}
/**
@@ -826,13 +814,12 @@ int rv_register_monitor(struct rv_monitor *monitor, struct rv_monitor *parent)
*/
int rv_unregister_monitor(struct rv_monitor *monitor)
{
- mutex_lock(&rv_interface_lock);
+ guard(mutex)(&rv_interface_lock);
rv_disable_monitor(monitor);
list_del(&monitor->list);
destroy_monitor_dir(monitor);
- mutex_unlock(&rv_interface_lock);
return 0;
}
diff --git a/kernel/trace/rv/rv_reactors.c b/kernel/trace/rv/rv_reactors.c
index d32859fec238..37d1d37a27a3 100644
--- a/kernel/trace/rv/rv_reactors.c
+++ b/kernel/trace/rv/rv_reactors.c
@@ -232,9 +232,7 @@ monitor_reactors_write(struct file *file, const char __user *user_buf,
seq_f = file->private_data;
mon = seq_f->private;
- mutex_lock(&rv_interface_lock);
-
- retval = -EINVAL;
+ guard(mutex)(&rv_interface_lock);
list_for_each_entry(reactor, &rv_reactors_list, list) {
if (strcmp(ptr, reactor->name) != 0)
@@ -242,13 +240,10 @@ monitor_reactors_write(struct file *file, const char __user *user_buf,
monitor_swap_reactors(mon, reactor);
- retval = count;
- break;
+ return count;
}
- mutex_unlock(&rv_interface_lock);
-
- return retval;
+ return -EINVAL;
}
/*
@@ -309,18 +304,14 @@ static int __rv_register_reactor(struct rv_reactor *reactor)
*/
int rv_register_reactor(struct rv_reactor *reactor)
{
- int retval = 0;
-
if (strlen(reactor->name) >= MAX_RV_REACTOR_NAME_SIZE) {
pr_info("Reactor %s has a name longer than %d\n",
reactor->name, MAX_RV_MONITOR_NAME_SIZE);
return -EINVAL;
}
- mutex_lock(&rv_interface_lock);
- retval = __rv_register_reactor(reactor);
- mutex_unlock(&rv_interface_lock);
- return retval;
+ guard(mutex)(&rv_interface_lock);
+ return __rv_register_reactor(reactor);
}
/**
@@ -331,9 +322,8 @@ int rv_register_reactor(struct rv_reactor *reactor)
*/
int rv_unregister_reactor(struct rv_reactor *reactor)
{
- mutex_lock(&rv_interface_lock);
+ guard(mutex)(&rv_interface_lock);
list_del(&reactor->list);
- mutex_unlock(&rv_interface_lock);
return 0;
}
@@ -389,7 +379,7 @@ static ssize_t reacting_on_write_data(struct file *filp, const char __user *user
if (retval)
return retval;
- mutex_lock(&rv_interface_lock);
+ guard(mutex)(&rv_interface_lock);
if (val)
turn_reacting_on();
@@ -402,8 +392,6 @@ static ssize_t reacting_on_write_data(struct file *filp, const char __user *user
*/
tracepoint_synchronize_unregister();
- mutex_unlock(&rv_interface_lock);
-
return count;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/2] rv: Convert to use __free
2025-11-16 15:35 [PATCH 0/2] rv: Tidy up with auto-cleanup Nam Cao
2025-11-16 15:35 ` [PATCH 1/2] rv: Convert to use lock guard Nam Cao
@ 2025-11-16 15:35 ` Nam Cao
2025-11-17 7:27 ` Gabriele Monaco
2025-11-17 15:07 ` Steven Rostedt
1 sibling, 2 replies; 7+ messages in thread
From: Nam Cao @ 2025-11-16 15:35 UTC (permalink / raw)
To: Gabriele Monaco, Steven Rostedt
Cc: Masami Hiramatsu, Mathieu Desnoyers, linux-trace-kernel,
linux-kernel, Nam Cao
Convert to use __free to tidy up the code.
Signed-off-by: Nam Cao <namcao@linutronix.de>
---
kernel/trace/rv/rv.c | 65 +++++++++++++++--------------------
kernel/trace/rv/rv.h | 6 ++--
kernel/trace/rv/rv_reactors.c | 32 ++++++++---------
3 files changed, 46 insertions(+), 57 deletions(-)
diff --git a/kernel/trace/rv/rv.c b/kernel/trace/rv/rv.c
index b1059a3cf4fa..e83dc9f0c7bb 100644
--- a/kernel/trace/rv/rv.c
+++ b/kernel/trace/rv/rv.c
@@ -420,35 +420,28 @@ static const struct file_operations interface_desc_fops = {
static int create_monitor_dir(struct rv_monitor *mon, struct rv_monitor *parent)
{
struct dentry *root = parent ? parent->root_d : get_monitors_root();
- const char *name = mon->name;
+ struct dentry *dir __free(rv_remove) = rv_create_dir(mon->name, root);
struct dentry *tmp;
int retval;
- mon->root_d = rv_create_dir(name, root);
- if (!mon->root_d)
+ if (!dir)
return -ENOMEM;
- tmp = rv_create_file("enable", RV_MODE_WRITE, mon->root_d, mon, &interface_enable_fops);
- if (!tmp) {
- retval = -ENOMEM;
- goto out_remove_root;
- }
+ tmp = rv_create_file("enable", RV_MODE_WRITE, dir, mon, &interface_enable_fops);
+ if (!tmp)
+ return -ENOMEM;
- tmp = rv_create_file("desc", RV_MODE_READ, mon->root_d, mon, &interface_desc_fops);
- if (!tmp) {
- retval = -ENOMEM;
- goto out_remove_root;
- }
+ tmp = rv_create_file("desc", RV_MODE_READ, dir, mon, &interface_desc_fops);
+ if (!tmp)
+ return -ENOMEM;
- retval = reactor_populate_monitor(mon);
+ retval = reactor_populate_monitor(mon, dir);
if (retval)
- goto out_remove_root;
+ return retval;
+ mon->root_d = dir;
+ retain_and_null_ptr(dir);
return 0;
-
-out_remove_root:
- rv_remove(mon->root_d);
- return retval;
}
/*
@@ -827,39 +820,37 @@ int __init rv_init_interface(void)
{
struct dentry *tmp;
int retval;
+ struct dentry *root_dir __free(rv_remove) = rv_create_dir("rv", NULL);
- rv_root.root_dir = rv_create_dir("rv", NULL);
- if (!rv_root.root_dir)
- goto out_err;
+ if (!root_dir)
+ return 1;
- rv_root.monitors_dir = rv_create_dir("monitors", rv_root.root_dir);
+ rv_root.monitors_dir = rv_create_dir("monitors", root_dir);
if (!rv_root.monitors_dir)
- goto out_err;
+ return 1;
- tmp = rv_create_file("available_monitors", RV_MODE_READ, rv_root.root_dir, NULL,
+ tmp = rv_create_file("available_monitors", RV_MODE_READ, root_dir, NULL,
&available_monitors_ops);
if (!tmp)
- goto out_err;
+ return 1;
- tmp = rv_create_file("enabled_monitors", RV_MODE_WRITE, rv_root.root_dir, NULL,
+ tmp = rv_create_file("enabled_monitors", RV_MODE_WRITE, root_dir, NULL,
&enabled_monitors_ops);
if (!tmp)
- goto out_err;
+ return 1;
- tmp = rv_create_file("monitoring_on", RV_MODE_WRITE, rv_root.root_dir, NULL,
+ tmp = rv_create_file("monitoring_on", RV_MODE_WRITE, root_dir, NULL,
&monitoring_on_fops);
if (!tmp)
- goto out_err;
- retval = init_rv_reactors(rv_root.root_dir);
+ return 1;
+ retval = init_rv_reactors(root_dir);
if (retval)
- goto out_err;
+ return 1;
turn_monitoring_on();
- return 0;
+ rv_root.root_dir = root_dir;
+ retain_and_null_ptr(root_dir);
-out_err:
- rv_remove(rv_root.root_dir);
- printk(KERN_ERR "RV: Error while creating the RV interface\n");
- return 1;
+ return 0;
}
diff --git a/kernel/trace/rv/rv.h b/kernel/trace/rv/rv.h
index 1485a70c1bf4..8661d1b6ede4 100644
--- a/kernel/trace/rv/rv.h
+++ b/kernel/trace/rv/rv.h
@@ -17,6 +17,8 @@ struct rv_interface {
#define rv_create_file tracefs_create_file
#define rv_remove tracefs_remove
+DEFINE_FREE(rv_remove, struct dentry *, rv_remove(_T));
+
#define MAX_RV_MONITOR_NAME_SIZE 32
#define MAX_RV_REACTOR_NAME_SIZE 32
@@ -30,10 +32,10 @@ bool rv_is_container_monitor(struct rv_monitor *mon);
bool rv_is_nested_monitor(struct rv_monitor *mon);
#ifdef CONFIG_RV_REACTORS
-int reactor_populate_monitor(struct rv_monitor *mon);
+int reactor_populate_monitor(struct rv_monitor *mon, struct dentry *root);
int init_rv_reactors(struct dentry *root_dir);
#else
-static inline int reactor_populate_monitor(struct rv_monitor *mon)
+static inline int reactor_populate_monitor(struct rv_monitor *mon, struct dentry *root)
{
return 0;
}
diff --git a/kernel/trace/rv/rv_reactors.c b/kernel/trace/rv/rv_reactors.c
index 37d1d37a27a3..ce7d22cbde57 100644
--- a/kernel/trace/rv/rv_reactors.c
+++ b/kernel/trace/rv/rv_reactors.c
@@ -404,14 +404,15 @@ static const struct file_operations reacting_on_fops = {
/**
* reactor_populate_monitor - creates per monitor reactors file
* @mon: The monitor.
+ * @root: The directory of the monitor.
*
* Returns 0 if successful, error otherwise.
*/
-int reactor_populate_monitor(struct rv_monitor *mon)
+int reactor_populate_monitor(struct rv_monitor *mon, struct dentry *root)
{
struct dentry *tmp;
- tmp = rv_create_file("reactors", RV_MODE_WRITE, mon->root_d, mon, &monitor_reactors_ops);
+ tmp = rv_create_file("reactors", RV_MODE_WRITE, root, mon, &monitor_reactors_ops);
if (!tmp)
return -ENOMEM;
@@ -438,30 +439,25 @@ static struct rv_reactor rv_nop = {
int init_rv_reactors(struct dentry *root_dir)
{
- struct dentry *available, *reacting;
int retval;
- available = rv_create_file("available_reactors", RV_MODE_READ, root_dir, NULL,
- &available_reactors_ops);
- if (!available)
- goto out_err;
+ struct dentry *available __free(rv_remove) =
+ rv_create_file("available_reactors", RV_MODE_READ, root_dir,
+ NULL, &available_reactors_ops);
- reacting = rv_create_file("reacting_on", RV_MODE_WRITE, root_dir, NULL, &reacting_on_fops);
- if (!reacting)
- goto rm_available;
+ struct dentry *reacting =
+ rv_create_file("reacting_on", RV_MODE_WRITE, root_dir, NULL, &reacting_on_fops);
+
+ if (!reacting || !available)
+ return -ENOMEM;
retval = __rv_register_reactor(&rv_nop);
if (retval)
- goto rm_reacting;
+ return retval;
turn_reacting_on();
+ retain_and_null_ptr(available);
+ retain_and_null_ptr(reacting);
return 0;
-
-rm_reacting:
- rv_remove(reacting);
-rm_available:
- rv_remove(available);
-out_err:
- return -ENOMEM;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] rv: Convert to use __free
2025-11-16 15:35 ` [PATCH 2/2] rv: Convert to use __free Nam Cao
@ 2025-11-17 7:27 ` Gabriele Monaco
2025-11-17 8:30 ` Nam Cao
2025-11-17 15:07 ` Steven Rostedt
1 sibling, 1 reply; 7+ messages in thread
From: Gabriele Monaco @ 2025-11-17 7:27 UTC (permalink / raw)
To: Nam Cao, Steven Rostedt
Cc: Masami Hiramatsu, Mathieu Desnoyers, linux-trace-kernel,
linux-kernel
On Sun, 2025-11-16 at 15:35 +0000, Nam Cao wrote:
> Convert to use __free to tidy up the code.
>
> Signed-off-by: Nam Cao <namcao@linutronix.de>
Both patches look very neat, thanks!
I have a few comments on this one:
> ---
> kernel/trace/rv/rv.c | 65 +++++++++++++++--------------------
> kernel/trace/rv/rv.h | 6 ++--
> kernel/trace/rv/rv_reactors.c | 32 ++++++++---------
> 3 files changed, 46 insertions(+), 57 deletions(-)
>
> diff --git a/kernel/trace/rv/rv.c b/kernel/trace/rv/rv.c
> index b1059a3cf4fa..e83dc9f0c7bb 100644
> --- a/kernel/trace/rv/rv.c
> +++ b/kernel/trace/rv/rv.c
> @@ -420,35 +420,28 @@ static const struct file_operations interface_desc_fops
> = {
> static int create_monitor_dir(struct rv_monitor *mon, struct rv_monitor
> *parent)
> {
> ...
> + mon->root_d = dir;
> + retain_and_null_ptr(dir);
I think you could just save a line by doing:
+ mon->root_d = no_free_ptr(dir);
> return 0;
> -
> -out_remove_root:
> - rv_remove(mon->root_d);
> - return retval;
> }
>
> /*
> @@ -827,39 +820,37 @@ int __init rv_init_interface(void)
> {
> struct dentry *tmp;
> int retval;
> + struct dentry *root_dir __free(rv_remove) = rv_create_dir("rv",
> NULL);
>
> - rv_root.root_dir = rv_create_dir("rv", NULL);
> - if (!rv_root.root_dir)
> - goto out_err;
> + if (!root_dir)
> + return 1;
>
> - rv_root.monitors_dir = rv_create_dir("monitors", rv_root.root_dir);
> + rv_root.monitors_dir = rv_create_dir("monitors", root_dir);
> if (!rv_root.monitors_dir)
> - goto out_err;
> + return 1;
>
> - tmp = rv_create_file("available_monitors", RV_MODE_READ,
> rv_root.root_dir, NULL,
> + tmp = rv_create_file("available_monitors", RV_MODE_READ, root_dir,
> NULL,
> &available_monitors_ops);
> if (!tmp)
> - goto out_err;
> + return 1;
>
> - tmp = rv_create_file("enabled_monitors", RV_MODE_WRITE,
> rv_root.root_dir, NULL,
> + tmp = rv_create_file("enabled_monitors", RV_MODE_WRITE, root_dir,
> NULL,
> &enabled_monitors_ops);
> if (!tmp)
> - goto out_err;
> + return 1;
>
> - tmp = rv_create_file("monitoring_on", RV_MODE_WRITE,
> rv_root.root_dir, NULL,
> + tmp = rv_create_file("monitoring_on", RV_MODE_WRITE, root_dir, NULL,
> &monitoring_on_fops);
> if (!tmp)
> - goto out_err;
> - retval = init_rv_reactors(rv_root.root_dir);
> + return 1;
> + retval = init_rv_reactors(root_dir);
> if (retval)
> - goto out_err;
> + return 1;
>
> turn_monitoring_on();
>
> - return 0;
> + rv_root.root_dir = root_dir;
> + retain_and_null_ptr(root_dir);
Same as above:
+ mon->root_d = no_free_ptr(root_dir);
>
> -out_err:
> - rv_remove(rv_root.root_dir);
> - printk(KERN_ERR "RV: Error while creating the RV interface\n");
By removing this, you are also not logging in case of failure, right?
I'm still liking to be rid of goto's, but what about moving this error reporting
to the caller tracer_init_tracefs() ?
> - return 1;
> + return 0;
> }
> diff --git a/kernel/trace/rv/rv.h b/kernel/trace/rv/rv.h
> index 1485a70c1bf4..8661d1b6ede4 100644
> --- a/kernel/trace/rv/rv.h
> +++ b/kernel/trace/rv/rv.h
> @@ -17,6 +17,8 @@ struct rv_interface {
> #define rv_create_file tracefs_create_file
> #define rv_remove tracefs_remove
>
> +DEFINE_FREE(rv_remove, struct dentry *, rv_remove(_T));
It's kind of idiomatic to do things like `if (_T) free(_T)` in those.
Although free (like tracefs_remove) checks for null, it's probably safer to keep
it that way here as well (as the entire system, including the return_ptr magic
relies on it):
+DEFINE_FREE(rv_remove, struct dentry *, if (_T) rv_remove(_T));
> diff --git a/kernel/trace/rv/rv_reactors.c b/kernel/trace/rv/rv_reactors.c
> index 37d1d37a27a3..ce7d22cbde57 100644
> --- a/kernel/trace/rv/rv_reactors.c
> +++ b/kernel/trace/rv/rv_reactors.c
> @@ -438,30 +439,25 @@ static struct rv_reactor rv_nop = {
>
> int init_rv_reactors(struct dentry *root_dir)
> {
> - struct dentry *available, *reacting;
> int retval;
>
> - available = rv_create_file("available_reactors", RV_MODE_READ,
> root_dir, NULL,
> - &available_reactors_ops);
> - if (!available)
> - goto out_err;
> + struct dentry *available __free(rv_remove) =
> + rv_create_file("available_reactors", RV_MODE_READ, root_dir,
> + NULL, &available_reactors_ops);
>
> - reacting = rv_create_file("reacting_on", RV_MODE_WRITE, root_dir,
> NULL, &reacting_on_fops);
> - if (!reacting)
> - goto rm_available;
> + struct dentry *reacting =
> + rv_create_file("reacting_on", RV_MODE_WRITE, root_dir, NULL,
> &reacting_on_fops);
Nothing is removing "reacting_on" in case of successive failure, is it?
Am I missing anything or couldn't we just set both variables to __free() ?
Thanks,
Gabriele
> +
> + if (!reacting || !available)
> + return -ENOMEM;
>
> retval = __rv_register_reactor(&rv_nop);
> if (retval)
> - goto rm_reacting;
> + return retval;
>
> turn_reacting_on();
>
> + retain_and_null_ptr(available);
> + retain_and_null_ptr(reacting);
> return 0;
> -
> -rm_reacting:
> - rv_remove(reacting);
> -rm_available:
> - rv_remove(available);
> -out_err:
> - return -ENOMEM;
> }
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] rv: Convert to use __free
2025-11-17 7:27 ` Gabriele Monaco
@ 2025-11-17 8:30 ` Nam Cao
0 siblings, 0 replies; 7+ messages in thread
From: Nam Cao @ 2025-11-17 8:30 UTC (permalink / raw)
To: Gabriele Monaco, Steven Rostedt
Cc: Masami Hiramatsu, Mathieu Desnoyers, linux-trace-kernel,
linux-kernel
Gabriele Monaco <gmonaco@redhat.com> writes:
> On Sun, 2025-11-16 at 15:35 +0000, Nam Cao wrote:
>> - reacting = rv_create_file("reacting_on", RV_MODE_WRITE, root_dir,
>> NULL, &reacting_on_fops);
>> - if (!reacting)
>> - goto rm_available;
>> + struct dentry *reacting =
>> + rv_create_file("reacting_on", RV_MODE_WRITE, root_dir, NULL,
>> &reacting_on_fops);
>
> Nothing is removing "reacting_on" in case of successive failure, is it?
> Am I missing anything or couldn't we just set both variables to __free() ?
We can. I overlooked this one :(
Nam
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] rv: Convert to use __free
2025-11-16 15:35 ` [PATCH 2/2] rv: Convert to use __free Nam Cao
2025-11-17 7:27 ` Gabriele Monaco
@ 2025-11-17 15:07 ` Steven Rostedt
2025-11-17 15:20 ` Nam Cao
1 sibling, 1 reply; 7+ messages in thread
From: Steven Rostedt @ 2025-11-17 15:07 UTC (permalink / raw)
To: Nam Cao
Cc: Gabriele Monaco, Masami Hiramatsu, Mathieu Desnoyers,
linux-trace-kernel, linux-kernel
On Sun, 16 Nov 2025 15:35:12 +0000
Nam Cao <namcao@linutronix.de> wrote:
> Convert to use __free to tidy up the code.
>
> Signed-off-by: Nam Cao <namcao@linutronix.de>
> ---
> kernel/trace/rv/rv.c | 65 +++++++++++++++--------------------
> kernel/trace/rv/rv.h | 6 ++--
> kernel/trace/rv/rv_reactors.c | 32 ++++++++---------
> 3 files changed, 46 insertions(+), 57 deletions(-)
>
> diff --git a/kernel/trace/rv/rv.c b/kernel/trace/rv/rv.c
> index b1059a3cf4fa..e83dc9f0c7bb 100644
> --- a/kernel/trace/rv/rv.c
> +++ b/kernel/trace/rv/rv.c
> @@ -420,35 +420,28 @@ static const struct file_operations interface_desc_fops = {
> static int create_monitor_dir(struct rv_monitor *mon, struct rv_monitor *parent)
> {
> struct dentry *root = parent ? parent->root_d : get_monitors_root();
> - const char *name = mon->name;
> + struct dentry *dir __free(rv_remove) = rv_create_dir(mon->name, root);
> struct dentry *tmp;
> int retval;
>
> - mon->root_d = rv_create_dir(name, root);
> - if (!mon->root_d)
> + if (!dir)
> return -ENOMEM;
>
> - tmp = rv_create_file("enable", RV_MODE_WRITE, mon->root_d, mon, &interface_enable_fops);
> - if (!tmp) {
> - retval = -ENOMEM;
> - goto out_remove_root;
> - }
> + tmp = rv_create_file("enable", RV_MODE_WRITE, dir, mon, &interface_enable_fops);
> + if (!tmp)
> + return -ENOMEM;
>
> - tmp = rv_create_file("desc", RV_MODE_READ, mon->root_d, mon, &interface_desc_fops);
> - if (!tmp) {
> - retval = -ENOMEM;
> - goto out_remove_root;
> - }
> + tmp = rv_create_file("desc", RV_MODE_READ, dir, mon, &interface_desc_fops);
> + if (!tmp)
> + return -ENOMEM;
>
> - retval = reactor_populate_monitor(mon);
> + retval = reactor_populate_monitor(mon, dir);
> if (retval)
> - goto out_remove_root;
> + return retval;
>
> + mon->root_d = dir;
> + retain_and_null_ptr(dir);
> return 0;
Why the "retain_and_null_ptr() and not just:
mon->root-d = no_free_ptr(dir);
return 0;
As from my understanding is that the retain_and_null_ptr() is for use of
passing the variable to a function that will consume it. But for assigning
to a variable, I usually just use the no_free_ptr().
> -
> -out_remove_root:
> - rv_remove(mon->root_d);
> - return retval;
> }
>
> /*
> @@ -827,39 +820,37 @@ int __init rv_init_interface(void)
> {
> struct dentry *tmp;
> int retval;
> + struct dentry *root_dir __free(rv_remove) = rv_create_dir("rv", NULL);
>
> - rv_root.root_dir = rv_create_dir("rv", NULL);
> - if (!rv_root.root_dir)
> - goto out_err;
> + if (!root_dir)
> + return 1;
>
> - rv_root.monitors_dir = rv_create_dir("monitors", rv_root.root_dir);
> + rv_root.monitors_dir = rv_create_dir("monitors", root_dir);
> if (!rv_root.monitors_dir)
> - goto out_err;
> + return 1;
>
> - tmp = rv_create_file("available_monitors", RV_MODE_READ, rv_root.root_dir, NULL,
> + tmp = rv_create_file("available_monitors", RV_MODE_READ, root_dir, NULL,
> &available_monitors_ops);
> if (!tmp)
> - goto out_err;
> + return 1;
>
> - tmp = rv_create_file("enabled_monitors", RV_MODE_WRITE, rv_root.root_dir, NULL,
> + tmp = rv_create_file("enabled_monitors", RV_MODE_WRITE, root_dir, NULL,
> &enabled_monitors_ops);
> if (!tmp)
> - goto out_err;
> + return 1;
>
> - tmp = rv_create_file("monitoring_on", RV_MODE_WRITE, rv_root.root_dir, NULL,
> + tmp = rv_create_file("monitoring_on", RV_MODE_WRITE, root_dir, NULL,
> &monitoring_on_fops);
> if (!tmp)
> - goto out_err;
> - retval = init_rv_reactors(rv_root.root_dir);
> + return 1;
> + retval = init_rv_reactors(root_dir);
> if (retval)
> - goto out_err;
> + return 1;
>
> turn_monitoring_on();
>
> - return 0;
> + rv_root.root_dir = root_dir;
> + retain_and_null_ptr(root_dir);
Same here.
>
> -out_err:
> - rv_remove(rv_root.root_dir);
> - printk(KERN_ERR "RV: Error while creating the RV interface\n");
> - return 1;
> + return 0;
> }
> @@ -438,30 +439,25 @@ static struct rv_reactor rv_nop = {
>
> int init_rv_reactors(struct dentry *root_dir)
> {
> - struct dentry *available, *reacting;
> int retval;
>
> - available = rv_create_file("available_reactors", RV_MODE_READ, root_dir, NULL,
> - &available_reactors_ops);
> - if (!available)
> - goto out_err;
> + struct dentry *available __free(rv_remove) =
> + rv_create_file("available_reactors", RV_MODE_READ, root_dir,
> + NULL, &available_reactors_ops);
>
> - reacting = rv_create_file("reacting_on", RV_MODE_WRITE, root_dir, NULL, &reacting_on_fops);
> - if (!reacting)
> - goto rm_available;
> + struct dentry *reacting =
> + rv_create_file("reacting_on", RV_MODE_WRITE, root_dir, NULL, &reacting_on_fops);
> +
> + if (!reacting || !available)
> + return -ENOMEM;
>
> retval = __rv_register_reactor(&rv_nop);
> if (retval)
> - goto rm_reacting;
> + return retval;
>
> turn_reacting_on();
>
> + retain_and_null_ptr(available);
> + retain_and_null_ptr(reacting);
Here it makes sense to use retain_and_null_ptr() as the two variables were
passed to another function. But the other two locations should simply use
the no_free_ptr() wrapper.
-- Steve
> return 0;
> -
> -rm_reacting:
> - rv_remove(reacting);
> -rm_available:
> - rv_remove(available);
> -out_err:
> - return -ENOMEM;
> }
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] rv: Convert to use __free
2025-11-17 15:07 ` Steven Rostedt
@ 2025-11-17 15:20 ` Nam Cao
0 siblings, 0 replies; 7+ messages in thread
From: Nam Cao @ 2025-11-17 15:20 UTC (permalink / raw)
To: Steven Rostedt
Cc: Gabriele Monaco, Masami Hiramatsu, Mathieu Desnoyers,
linux-trace-kernel, linux-kernel
Steven Rostedt <rostedt@goodmis.org> writes:
> On Sun, 16 Nov 2025 15:35:12 +0000
> Nam Cao <namcao@linutronix.de> wrote:
>> + mon->root_d = dir;
>> + retain_and_null_ptr(dir);
>> return 0;
>
> Why the "retain_and_null_ptr() and not just:
>
> mon->root-d = no_free_ptr(dir);
> return 0;
>
> As from my understanding is that the retain_and_null_ptr() is for use of
> passing the variable to a function that will consume it. But for assigning
> to a variable, I usually just use the no_free_ptr().
I wasn't aware that no_free_ptr() exists. Gabriele has pointed this out,
and I fixed it up in v2.
Nam
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-11-17 15:20 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-16 15:35 [PATCH 0/2] rv: Tidy up with auto-cleanup Nam Cao
2025-11-16 15:35 ` [PATCH 1/2] rv: Convert to use lock guard Nam Cao
2025-11-16 15:35 ` [PATCH 2/2] rv: Convert to use __free Nam Cao
2025-11-17 7:27 ` Gabriele Monaco
2025-11-17 8:30 ` Nam Cao
2025-11-17 15:07 ` Steven Rostedt
2025-11-17 15:20 ` Nam Cao
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).