All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] tracing: Ensure module defining synth event cannot be unloaded while tracing
@ 2025-03-18 18:09 Douglas RAILLARD
  2025-03-19 13:29 ` Masami Hiramatsu
  0 siblings, 1 reply; 2+ messages in thread
From: Douglas RAILLARD @ 2025-03-18 18:09 UTC (permalink / raw)
  To: rostedt
  Cc: douglas.raillard, Masami Hiramatsu, Mathieu Desnoyers,
	linux-kernel, linux-trace-kernel

From: Douglas Raillard <douglas.raillard@arm.com>

Currently, using synth_event_delete() will fail if the event is being
used (tracing in progress), but that is normally done in the module exit
function. At that stage, failing is problematic as returning a non-zero
status means the module will become locked (impossible to unload or
reload again).

Instead, ensure the module exit function does not get called in the
first place by increasing the module refcnt when the event is enabled.

Signed-off-by: Douglas Raillard <douglas.raillard@arm.com>
---
 kernel/trace/trace_events_synth.c | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
index e3f7d09e5512..bb7ef6e76991 100644
--- a/kernel/trace/trace_events_synth.c
+++ b/kernel/trace/trace_events_synth.c
@@ -852,6 +852,34 @@ static struct trace_event_fields synth_event_fields_array[] = {
 	{}
 };
 
+static int synth_event_reg(struct trace_event_call *call,
+		    enum trace_reg type, void *data)
+{
+	struct synth_event *event = container_of(call, struct synth_event, call);
+
+	switch (type) {
+	case TRACE_REG_REGISTER:
+	case TRACE_REG_PERF_REGISTER:
+		if (!try_module_get(event->mod))
+			return -EBUSY;
+		break;
+	default:
+		break;
+	}
+
+	int ret = trace_event_reg(call, type, data);
+
+	switch (type) {
+	case TRACE_REG_UNREGISTER:
+	case TRACE_REG_PERF_UNREGISTER:
+		module_put(event->mod);
+		break;
+	default:
+		break;
+	}
+	return ret;
+}
+
 static int register_synth_event(struct synth_event *event)
 {
 	struct trace_event_call *call = &event->call;
@@ -881,7 +909,7 @@ static int register_synth_event(struct synth_event *event)
 		goto out;
 	}
 	call->flags = TRACE_EVENT_FL_TRACEPOINT;
-	call->class->reg = trace_event_reg;
+	call->class->reg = synth_event_reg;
 	call->class->probe = trace_event_raw_event_synth;
 	call->data = event;
 	call->tp = event->tp;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] tracing: Ensure module defining synth event cannot be unloaded while tracing
  2025-03-18 18:09 [PATCH] tracing: Ensure module defining synth event cannot be unloaded while tracing Douglas RAILLARD
@ 2025-03-19 13:29 ` Masami Hiramatsu
  0 siblings, 0 replies; 2+ messages in thread
From: Masami Hiramatsu @ 2025-03-19 13:29 UTC (permalink / raw)
  To: Douglas RAILLARD
  Cc: rostedt, Masami Hiramatsu, Mathieu Desnoyers, linux-kernel,
	linux-trace-kernel

On Tue, 18 Mar 2025 18:09:05 +0000
Douglas RAILLARD <douglas.raillard@arm.com> wrote:

> From: Douglas Raillard <douglas.raillard@arm.com>
> 
> Currently, using synth_event_delete() will fail if the event is being
> used (tracing in progress), but that is normally done in the module exit
> function. At that stage, failing is problematic as returning a non-zero
> status means the module will become locked (impossible to unload or
> reload again).
> 
> Instead, ensure the module exit function does not get called in the
> first place by increasing the module refcnt when the event is enabled.
> 

OK, I think this is correct way to fix that scenario.

Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>

Thank you,

> Signed-off-by: Douglas Raillard <douglas.raillard@arm.com>
> ---
>  kernel/trace/trace_events_synth.c | 30 +++++++++++++++++++++++++++++-
>  1 file changed, 29 insertions(+), 1 deletion(-)
> 
> diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
> index e3f7d09e5512..bb7ef6e76991 100644
> --- a/kernel/trace/trace_events_synth.c
> +++ b/kernel/trace/trace_events_synth.c
> @@ -852,6 +852,34 @@ static struct trace_event_fields synth_event_fields_array[] = {
>  	{}
>  };
>  
> +static int synth_event_reg(struct trace_event_call *call,
> +		    enum trace_reg type, void *data)
> +{
> +	struct synth_event *event = container_of(call, struct synth_event, call);
> +
> +	switch (type) {
> +	case TRACE_REG_REGISTER:
> +	case TRACE_REG_PERF_REGISTER:
> +		if (!try_module_get(event->mod))
> +			return -EBUSY;
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	int ret = trace_event_reg(call, type, data);
> +
> +	switch (type) {
> +	case TRACE_REG_UNREGISTER:
> +	case TRACE_REG_PERF_UNREGISTER:
> +		module_put(event->mod);
> +		break;
> +	default:
> +		break;
> +	}
> +	return ret;
> +}
> +
>  static int register_synth_event(struct synth_event *event)
>  {
>  	struct trace_event_call *call = &event->call;
> @@ -881,7 +909,7 @@ static int register_synth_event(struct synth_event *event)
>  		goto out;
>  	}
>  	call->flags = TRACE_EVENT_FL_TRACEPOINT;
> -	call->class->reg = trace_event_reg;
> +	call->class->reg = synth_event_reg;
>  	call->class->probe = trace_event_raw_event_synth;
>  	call->data = event;
>  	call->tp = event->tp;
> -- 
> 2.43.0
> 


-- 
Masami Hiramatsu (Google) <mhiramat@kernel.org>

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-03-19 13:29 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-18 18:09 [PATCH] tracing: Ensure module defining synth event cannot be unloaded while tracing Douglas RAILLARD
2025-03-19 13:29 ` Masami Hiramatsu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.