mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Gabriele Monaco <gmonaco@redhat.com>
To: wen.yang@linux.dev
Cc: Nam Cao <namcao@linutronix.de>,
	linux-trace-kernel@vger.kernel.org,
	 linux-kernel@vger.kernel.org
Subject: Re: [PATCH v5 3/5] rv/reactors: export rv_register_reactor() and rv_unregister_reactor()
Date: Fri, 11 Sep 2026 08:53:33 +0200	[thread overview]
Message-ID: <b5ec9da630968a5f801623c8d6e2aaeb0bb509d8.camel@redhat.com> (raw)
In-Reply-To: <7c931773dacd7c3da35a22629c3d7dc286b5a0fe.1788705281.git.wen.yang@linux.dev>

On Mon, 2026-09-07 at 01:10 +0800, wen.yang@linux.dev wrote:
> From: Wen Yang <wen.yang@linux.dev>
> 
> rv_react() is exported to modules, but the reactor registration helpers
> are not.  Export them with EXPORT_SYMBOL_GPL() so reactor modules and
> the tristate KUnit test module can register and unregister reactors
> without hitting undefined symbol errors at link time(modpost).
> 
> Commit 3d3800b4f7f4 ("rv: Remove reactor's reference counter") noted
> that if module-based reactors are supported, try_module_get()/module_put()
> should be used. Add struct module *owner to struct rv_reactor so a module
> cat set owner = THIS_MODULE; pin the module in monitor_swap_reactors_gingle()
> and release it when a monitor detaches or is unregistered.

You needed these symbols in KUnit and we are exporting them for /potential/
future support of reactors as modules. I don't see any technical reason why we
shouldn't support this, but they are currently /not/ supported.

I know sashiko and other LLMs complain about this, and they have a point, but
you can ignore them. At most state in this commit message that this does NOT add
support for reactors as modules.

Let's focus this series on its original intent (fix a lockdep warning and add
some KUnit tests that expose a reproducer), then if adding support for reactors
as modules is so simple, you can do it in another series.

If you really want to /also/ add support for reactors as modules in this series,
you need to make that very explicit (not just a vague line in the changelog, but
rather rewrite the entire cover letter and commit message).
And mind that this would mean your series needs to go through another round of
review and serious testing: you are adding a new feature.

> In-tree reactors leave owner = NULL and are unaffected.
> 
> Reviewed-by: Gabriele Monaco <gmonaco@redhat.com>

Please, whenever you significantly change an already reviewed patch, remove the
reviewed-by, so I can quickly see I need to review it again.

Thanks,
Gabriele

> Signed-off-by: Wen Yang <wen.yang@linux.dev>
> ---
>  include/linux/rv.h            |  3 +++
>  kernel/trace/rv/rv.c          |  5 +++++
>  kernel/trace/rv/rv_reactors.c | 38 +++++++++++++++++++++++++++++------
>  3 files changed, 40 insertions(+), 6 deletions(-)
> 
> diff --git a/include/linux/rv.h b/include/linux/rv.h
> index 541ba404926a..ff3289ba4f02 100644
> --- a/include/linux/rv.h
> +++ b/include/linux/rv.h
> @@ -128,10 +128,13 @@ union rv_task_monitor {
>  };
>  
>  #ifdef CONFIG_RV_REACTORS
> +struct module;
> +
>  struct rv_reactor {
>  	const char		*name;
>  	const char		*description;
>  	__printf(1, 0) void	(*react)(const char *msg, va_list args);
> +	struct module		*owner;
>  	struct list_head	list;
>  };
>  #endif
> diff --git a/kernel/trace/rv/rv.c b/kernel/trace/rv/rv.c
> index 29f155c6968b..458b17c005b3 100644
> --- a/kernel/trace/rv/rv.c
> +++ b/kernel/trace/rv/rv.c
> @@ -803,6 +803,11 @@ int rv_unregister_monitor(struct rv_monitor *monitor)
>  	guard(mutex)(&rv_interface_lock);
>  
>  	rv_disable_monitor(monitor);
> +#ifdef CONFIG_RV_REACTORS
> +	if (monitor->reactor)
> +		module_put(monitor->reactor->owner);
> +
> +#endif
>  	list_del(&monitor->list);
>  	destroy_monitor_dir(monitor);
>  
> diff --git a/kernel/trace/rv/rv_reactors.c b/kernel/trace/rv/rv_reactors.c
> index ff7d478227c3..136eb7f47c4a 100644
> --- a/kernel/trace/rv/rv_reactors.c
> +++ b/kernel/trace/rv/rv_reactors.c
> @@ -62,6 +62,7 @@
>   */
>  
>  #include <linux/lockdep.h>
> +#include <linux/module.h>
>  #include <linux/slab.h>
>  
>  #include "rv.h"
> @@ -159,7 +160,7 @@ static const struct seq_operations
> monitor_reactors_seq_ops = {
>  	.show	= monitor_reactor_show
>  };
>  
> -static void monitor_swap_reactors_single(struct rv_monitor *mon,
> +static int monitor_swap_reactors_single(struct rv_monitor *mon,
>  					 struct rv_reactor *reactor,
>  					 bool nested)
>  {
> @@ -167,29 +168,39 @@ static void monitor_swap_reactors_single(struct
> rv_monitor *mon,
>  
>  	/* nothing to do */
>  	if (mon->reactor == reactor)
> -		return;
> +		return 0;
> +
> +	if (reactor->owner && !try_module_get(reactor->owner))
> +		return -EBUSY;
>  
>  	monitor_enabled = mon->enabled;
>  	if (monitor_enabled)
>  		rv_disable_monitor(mon);
>  
> +	if (mon->reactor)
> +		module_put(mon->reactor->owner);
>  	mon->reactor = reactor;
>  	mon->react = reactor->react;
>  
>  	/* enable only once if iterating through a container */
>  	if (monitor_enabled && !nested)
>  		rv_enable_monitor(mon);
> +
> +	return 0;
>  }
>  
> -static void monitor_swap_reactors(struct rv_monitor *mon, struct rv_reactor
> *reactor)
> +static int monitor_swap_reactors(struct rv_monitor *mon, struct rv_reactor
> *reactor)
>  {
>  	struct rv_monitor *p = mon;
> +	int ret;
>  
>  	if (rv_is_container_monitor(mon))
>  		list_for_each_entry_continue(p, &rv_monitors_list, list) {
>  			if (p->parent != mon)
>  				break;
> -			monitor_swap_reactors_single(p, reactor, true);
> +			ret = monitor_swap_reactors_single(p, reactor, true);
> +			if (ret)
> +				return ret;
>  		}
>  	/*
>  	 * This call enables and disables the monitor if they were active.
> @@ -197,7 +208,7 @@ static void monitor_swap_reactors(struct rv_monitor *mon,
> struct rv_reactor *rea
>  	 * All nested monitors are enabled also if they were off, we may
> refine
>  	 * this logic in the future.
>  	 */
> -	monitor_swap_reactors_single(mon, reactor, false);
> +	return monitor_swap_reactors_single(mon, reactor, false);
>  }
>  
>  static ssize_t
> @@ -236,10 +247,14 @@ monitor_reactors_write(struct file *file, const char
> __user *user_buf,
>  	guard(mutex)(&rv_interface_lock);
>  
>  	list_for_each_entry(reactor, &rv_reactors_list, list) {
> +		int ret;
> +
>  		if (strcmp(ptr, reactor->name) != 0)
>  			continue;
>  
> -		monitor_swap_reactors(mon, reactor);
> +		ret = monitor_swap_reactors(mon, reactor);
> +		if (ret)
> +			return ret;
>  
>  		return count;
>  	}
> @@ -314,6 +329,7 @@ int rv_register_reactor(struct rv_reactor *reactor)
>  	guard(mutex)(&rv_interface_lock);
>  	return __rv_register_reactor(reactor);
>  }
> +EXPORT_SYMBOL_GPL(rv_register_reactor);
>  
>  /**
>   * rv_unregister_reactor - unregister a rv reactor.
> @@ -327,6 +343,7 @@ int rv_unregister_reactor(struct rv_reactor *reactor)
>  	list_del(&reactor->list);
>  	return 0;
>  }
> +EXPORT_SYMBOL_GPL(rv_unregister_reactor);
>  
>  /*
>   * reacting_on interface.
> @@ -421,6 +438,15 @@ int reactor_populate_monitor(struct rv_monitor *mon,
> struct dentry *root)
>  	 * Configure as the rv_nop reactor.
>  	 */
>  	mon->reactor = get_reactor_rdef_by_name("nop");
> +	if (WARN_ON(!mon->reactor)) {
> +		rv_remove(tmp);
> +		return -EINVAL;
> +	}
> +
> +	if (mon->reactor->owner && !try_module_get(mon->reactor->owner)) {
> +		rv_remove(tmp);
> +		return -EBUSY;
> +	}
>  
>  	return 0;
>  }


  reply	other threads:[~2026-09-11  6:53 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-06 17:10 [PATCH v5 0/5] rv/reactors: fix lockdep warning and add tests wen.yang
2026-09-06 17:10 ` [PATCH v5 1/5] rv/reactors: use LD_WAIT_SPIN as the reactor lockdep wait type wen.yang
2026-09-06 17:10 ` [PATCH v5 2/5] rv/reactors: propagate rv_register_reactor() error from reactor init wen.yang
2026-09-06 17:10 ` [PATCH v5 3/5] rv/reactors: export rv_register_reactor() and rv_unregister_reactor() wen.yang
2026-09-11  6:53   ` Gabriele Monaco [this message]
2026-09-06 17:10 ` [PATCH v5 4/5] rv/reactors: add KUnit tests for reactor registration and dispatch wen.yang
2026-09-06 17:10 ` [PATCH v5 5/5] selftests/verification: Test loadable module-based reactor wen.yang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b5ec9da630968a5f801623c8d6e2aaeb0bb509d8.camel@redhat.com \
    --to=gmonaco@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-trace-kernel@vger.kernel.org \
    --cc=namcao@linutronix.de \
    --cc=wen.yang@linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®