Linux Trace Kernel
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Tobias Schaffner" <tobias.schaffner@siemens.com>
Cc: linux-trace-kernel@vger.kernel.org
Subject: Re: [RFC 2/3] rv: add per-monitor edge-stat facility and stats file
Date: Thu, 27 Aug 2026 07:39:30 +0000	[thread overview]
Message-ID: <20260827073931.150F91F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260827072400.45734-3-tobias.schaffner@siemens.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] destroy_monitor_dir() frees mon->edge_pcpu before VFS synchronization, allowing concurrent readers to access freed memory via the tracefs stats file.
- [Medium] Non-atomic memset corrupts local64_t counters, racing with concurrent NMI tracepoint updates and lockless tracefs reads.
- [Medium] rv_edge_reset() only resets statistics on currently online CPUs, violating the guarantee that counters are fully cleared on enablement.
--

commit 5d961f88b7dec86f152d8e652fbd68ebc65c3317
Author: Tobias Schaffner <tobias.schaffner@siemens.com>
rv: add per-monitor edge-stat facility and stats file

This commit introduces CONFIG_RV_EDGE_STAT, an optional feature that records
how long a monitor's automaton dwells in a state. It allocates a per-CPU
buffer on first enable and exposes the counters via a per-monitor stats file.

> diff --git a/kernel/trace/rv/rv.c b/kernel/trace/rv/rv.c
> index ee4e68102f175..88a0bbaec4d0a 100644
> --- a/kernel/trace/rv/rv.c
> +++ b/kernel/trace/rv/rv.c

[ ... ]

> @@ -289,9 +298,15 @@ static int rv_enable_single(struct rv_monitor *mon)
>  
>  	retval = mon->enable();
>  
> -	if (!retval)
> +	if (!retval) {
>  		mon->enabled = 1;
>  
> +		if (rv_edge_setup(mon))
> +			pr_warn("rv: %s: edge statistics unavailable (out of memory)\n",
> +				mon->name);
> +		rv_edge_reset(mon);

[Severity: Medium]
Does resetting the statistics with memset() after the monitor is already
enabled risk data corruption?

Since mon->enable() is called before rv_edge_reset(), NMI tracepoint
updates can fire concurrently. Using memset() in rv_edge_reset_ipi() to
clear the array of local64_t counters could race with these
read-modify-write updates, potentially resulting in torn reads or
corrupted atomic statistics when rv_edge_stats_show() accesses them.

> +	}
> +
>  	return retval;
>  }

[ ... ]

> +static void rv_edge_reset_ipi(void *info)
> +{
> +	struct rv_monitor *mon = info;
> +
> +	memset(this_cpu_ptr(mon->edge_pcpu), 0, rv_edge_blob_size(mon));
> +}
> +
> +/* rv_edge_reset - zero the statistics; call from a monitor reset/enable. */
> +static void rv_edge_reset(struct rv_monitor *mon)
> +{
> +	if (mon->edge_pcpu)
> +		on_each_cpu(rv_edge_reset_ipi, mon, 1);
> +}

[Severity: Medium]
Will this skip clearing the statistics on offline CPUs?

Because on_each_cpu() only targets online CPUs, dynamically allocated
per-CPU edge statistics buffers for offline CPUs remain uncleared. If
an offline CPU is later brought online, reading the tracefs stats file
will iterate over it via for_each_online_cpu() and report stale,
un-reset values from previous runs.

[ ... ]

> @@ -747,6 +857,10 @@ static const struct file_operations monitoring_on_fops = {
>  
>  static void destroy_monitor_dir(struct rv_monitor *mon)
>  {
> +#ifdef CONFIG_RV_EDGE_STAT
> +	free_percpu(mon->edge_pcpu);
> +	mon->edge_pcpu = NULL;
> +#endif
>  	rv_remove(mon->root_d);
>  }

[Severity: High]
Could this lead to a use-after-free if the tracefs stats file is read
while the monitor is being unregistered?

The per-cpu buffer is explicitly freed here before the rv_remove()
synchronization point removes the tracefs file. A concurrent lockless
reader using rv_edge_stats_show() could access the freed mon->edge_pcpu
memory:

kernel/trace/rv/rv.c:rv_edge_stats_show() {
    ...
    if (!mon->edge_pcpu)
        return 0;

    for_each_online_cpu(cpu) {
        struct rv_edge_stat *s = per_cpu_ptr(mon->edge_pcpu, cpu);
    ...
}

Should rv_remove() be called before freeing the per-CPU buffer?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260827072400.45734-1-tobias.schaffner@siemens.com?part=2

  reply	other threads:[~2026-08-27  7:39 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-27  7:23 [RFC 0/3] rv: per-edge dwell-time statistics for per-cpu monitors Tobias Schaffner
2026-08-27  7:23 ` [RFC 1/3] rv: add per-edge dwell-time statistics primitive Tobias Schaffner
2026-08-27  7:34   ` sashiko-bot
2026-08-27  8:22   ` Gabriele Monaco
2026-08-27 10:10     ` Tobias Schaffner
2026-08-27  7:23 ` [RFC 2/3] rv: add per-monitor edge-stat facility and stats file Tobias Schaffner
2026-08-27  7:39   ` sashiko-bot [this message]
2026-08-27  7:24 ` [RFC 3/3] rv: collect per-edge dwell time for per-cpu DA/HA monitors Tobias Schaffner
2026-08-27  7:37   ` sashiko-bot
2026-08-27  8:18 ` [RFC 0/3] rv: per-edge dwell-time statistics for per-cpu monitors Gabriele Monaco
2026-08-27 18:21   ` Tobias Schaffner

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=20260827073931.150F91F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=linux-trace-kernel@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=tobias.schaffner@siemens.com \
    /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