* Re: [PATCH v9 1/2] lib: Introduce hierarchical per-cpu counters
From: Mathieu Desnoyers @ 2025-11-22 21:26 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, Paul E. McKenney, Steven Rostedt, Masami Hiramatsu,
Dennis Zhou, Tejun Heo, Christoph Lameter, Martin Liu,
David Rientjes, christian.koenig, Shakeel Butt, SeongJae Park,
Michal Hocko, Johannes Weiner, Sweet Tea Dorminy, Lorenzo Stoakes,
Liam R . Howlett, Mike Rapoport, Suren Baghdasaryan,
Vlastimil Babka, Christian Brauner, Wei Yang, David Hildenbrand,
Miaohe Lin, Al Viro, linux-mm, linux-trace-kernel, Yu Zhao,
Roman Gushchin, Mateusz Guzik, Matthew Wilcox, Baolin Wang,
Aboorva Devarajan
In-Reply-To: <a3652f6b-cd3b-45ad-a3ad-e92369cf4068@efficios.com>
On 2025-11-22 12:15, Mathieu Desnoyers wrote:
>...
> The fact that the max inaccuracy is bounded means that we can perform
> approximate comparisons in a fast path (which is enough if the values
> to compare greatly vary), and only have to do the more expensive
> "precise" comparison when values are close to each other and we
> actually care about their relative order.
>
> I'm thinking memory usage tracking, runtime usage (scheduler ?), cgroups
> ressource accounting.
Another use-case worth explicitly mentioning is accounting the
resources (memory, CPU, I/O) used by a given entity (process,
cgroup) and enforce quota validation based on a configured
capacity limit.
This is a comparison with a limit which can be much larger than
the current resource usage value. Therefore, because the inaccuracy
is known, it is possible to enforce the quota limit with an
approximate comparison, and only use a precise sum when the current
value is near the limit, and rate-limit the frequency at which precise
limit validation is done.
Thanks,
Mathieu
--
Mathieu Desnoyers
EfficiOS Inc.
https://www.efficios.com
^ permalink raw reply
* Re: [PATCH v9 1/2] lib: Introduce hierarchical per-cpu counters
From: Andrew Morton @ 2025-11-22 19:13 UTC (permalink / raw)
To: Mathieu Desnoyers
Cc: linux-kernel, Paul E. McKenney, Steven Rostedt, Masami Hiramatsu,
Dennis Zhou, Tejun Heo, Christoph Lameter, Martin Liu,
David Rientjes, christian.koenig, Shakeel Butt, SeongJae Park,
Michal Hocko, Johannes Weiner, Sweet Tea Dorminy, Lorenzo Stoakes,
Liam R . Howlett, Mike Rapoport, Suren Baghdasaryan,
Vlastimil Babka, Christian Brauner, Wei Yang, David Hildenbrand,
Miaohe Lin, Al Viro, linux-mm, linux-trace-kernel, Yu Zhao,
Roman Gushchin, Mateusz Guzik, Matthew Wilcox, Baolin Wang,
Aboorva Devarajan
In-Reply-To: <a3652f6b-cd3b-45ad-a3ad-e92369cf4068@efficios.com>
On Sat, 22 Nov 2025 12:15:02 -0500 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> wrote:
> >
> >> include/linux/percpu_counter_tree.h | 239 +++++++++++++++
> >> init/main.c | 2 +
> >> lib/Makefile | 1 +
> >> lib/percpu_counter_tree.c | 443 ++++++++++++++++++++++++++++
> >> 4 files changed, 685 insertions(+)
> >> create mode 100644 include/linux/percpu_counter_tree.h
> >> create mode 100644 lib/percpu_counter_tree.c
> >
> > An in-kernel test suite would be great. Like lib/*test*.c or
> > tools/testing/.
>
> I'll keep a note to port the tests from my userspace librseq
> percpu counters feature branch to the kernel. I did not do it
> initially because I wanted to see if the overall approach was
> deemed interesting for the kernel.
It deems interesting to me - certainly seems useful in addressing some
nasty problems.
If it hasn't been massacred by reviewers, please poke me in a week or
so and I'll look at giving it some exposure in mm.git's mm-new branch
(which isn't included in linux-next).
^ permalink raw reply
* [PATCH v1] tools/rtla: Add common_usage()
From: Costa Shulyupin @ 2025-11-22 18:09 UTC (permalink / raw)
To: Steven Rostedt, Tomas Glozar, Crystal Wood, Wander Lairson Costa,
Costa Shulyupin, John Kacur, Ivan Pravdin, linux-trace-kernel,
linux-kernel
The rtla tools (osnoise and timerlat, both hist and top) have
significant code duplication in their usage() functions. Each tool
implements its own version of the same help text formatting and option
descriptions, leading to maintenance overhead and inconsistencies.
Documentation/tools/rtla/common_options.rst lists 14 common options.
Add common_usage() infrastructure to consolidate help formatting.
Subsequent patches will extend this to handle other common options.
The refactored output is almost identical to the original, with the
following changes:
- add square brackets to specify optionality: `usage: [rtla] ...`
- remove `-q` from timerlat hist because hist tools don't support it
- minor spacing
Signed-off-by: Costa Shulyupin <costa.shul@redhat.com>
---
tools/tracing/rtla/src/common.c | 39 ++++++++++++++++++++++++++
tools/tracing/rtla/src/common.h | 3 ++
tools/tracing/rtla/src/osnoise_hist.c | 22 ++++++---------
tools/tracing/rtla/src/osnoise_top.c | 37 ++++++++++--------------
tools/tracing/rtla/src/timerlat_hist.c | 22 ++++++---------
tools/tracing/rtla/src/timerlat_top.c | 22 ++++++---------
6 files changed, 81 insertions(+), 64 deletions(-)
diff --git a/tools/tracing/rtla/src/common.c b/tools/tracing/rtla/src/common.c
index b197037fc58b..18b92c5e4b1a 100644
--- a/tools/tracing/rtla/src/common.c
+++ b/tools/tracing/rtla/src/common.c
@@ -4,6 +4,7 @@
#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include "common.h"
@@ -348,3 +349,41 @@ int hist_main_loop(struct osnoise_tool *tool)
return retval;
}
+
+static void print_msg_array(const char * const *msgs)
+{
+ if (!msgs)
+ return;
+
+ for (int i = 0; msgs[i]; i++)
+ fprintf(stderr, "%s\n", msgs[i]);
+}
+
+/*
+ * common_usage - print complete usage information
+ */
+void common_usage(const char *tool, const char *mode,
+ const char *desc, const char * const *start_msgs, const char * const *opt_msgs)
+{
+ static const char * const common_options[] = {
+ " -h/--help: print this menu",
+ NULL
+ };
+ fprintf(stderr, "rtla %s", tool);
+ if (strcmp(mode, ""))
+ fprintf(stderr, " %s", mode);
+ fprintf(stderr, ": %s (version %s)\n\n", desc, VERSION);
+ fprintf(stderr, " usage: [rtla] %s ", tool);
+
+ if (strcmp(mode, "top") == 0)
+ fprintf(stderr, "[top] [-h] ");
+ else
+ fprintf(stderr, "%s [-h] ", mode);
+
+ print_msg_array(start_msgs);
+ fprintf(stderr, "\n");
+ print_msg_array(common_options);
+ print_msg_array(opt_msgs);
+
+ exit(EXIT_SUCCESS);
+}
diff --git a/tools/tracing/rtla/src/common.h b/tools/tracing/rtla/src/common.h
index 9ec2b7632c37..b44e910ba72c 100644
--- a/tools/tracing/rtla/src/common.h
+++ b/tools/tracing/rtla/src/common.h
@@ -156,3 +156,6 @@ bool osnoise_trace_is_off(struct osnoise_tool *tool, struct osnoise_tool *record
int common_apply_config(struct osnoise_tool *tool, struct common_params *params);
int top_main_loop(struct osnoise_tool *tool);
int hist_main_loop(struct osnoise_tool *tool);
+
+void common_usage(const char *tool, const char *mode,
+ const char *desc, const char * const *start_msgs, const char * const *opt_msgs);
diff --git a/tools/tracing/rtla/src/osnoise_hist.c b/tools/tracing/rtla/src/osnoise_hist.c
index ff8c231e47c4..372128db9e4a 100644
--- a/tools/tracing/rtla/src/osnoise_hist.c
+++ b/tools/tracing/rtla/src/osnoise_hist.c
@@ -409,16 +409,15 @@ osnoise_print_stats(struct osnoise_tool *tool)
*/
static void osnoise_hist_usage(void)
{
- int i;
-
- static const char * const msg[] = {
- "",
- " usage: rtla osnoise hist [-h] [-D] [-d s] [-a us] [-p us] [-r us] [-s us] [-S us] \\",
+ static const char * const msg_start[] = {
+ "[-D] [-d s] [-a us] [-p us] [-r us] [-s us] [-S us] \\",
" [-T us] [-t [file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] \\",
" [-c cpu-list] [-H cpu-list] [-P priority] [-b N] [-E N] [--no-header] [--no-summary] \\",
" [--no-index] [--with-zeros] [-C [cgroup_name]] [--warm-up]",
- "",
- " -h/--help: print this menu",
+ NULL,
+ };
+
+ static const char * const msg_opts[] = {
" -a/--auto: set automatic trace mode, stopping the session if argument in us sample is hit",
" -p/--period us: osnoise period in us",
" -r/--runtime us: osnoise runtime in us",
@@ -453,13 +452,8 @@ static void osnoise_hist_usage(void)
NULL,
};
- fprintf(stderr, "rtla osnoise hist: a per-cpu histogram of the OS noise (version %s)\n",
- VERSION);
-
- for (i = 0; msg[i]; i++)
- fprintf(stderr, "%s\n", msg[i]);
-
- exit(EXIT_SUCCESS);
+ common_usage("osnoise", "hist", "a per-cpu histogram of the OS noise",
+ msg_start, msg_opts);
}
/*
diff --git a/tools/tracing/rtla/src/osnoise_top.c b/tools/tracing/rtla/src/osnoise_top.c
index 04c699bdd736..1db1d946b600 100644
--- a/tools/tracing/rtla/src/osnoise_top.c
+++ b/tools/tracing/rtla/src/osnoise_top.c
@@ -257,14 +257,16 @@ osnoise_print_stats(struct osnoise_tool *top)
*/
static void osnoise_top_usage(struct osnoise_params *params)
{
- int i;
+ const char *tool, *mode, *desc;
- static const char * const msg[] = {
- " [-h] [-q] [-D] [-d s] [-a us] [-p us] [-r us] [-s us] [-S us] \\",
+ static const char * const msg_start[] = {
+ "[-q] [-D] [-d s] [-a us] [-p us] [-r us] [-s us] [-S us] \\",
" [-T us] [-t [file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] \\",
" [-c cpu-list] [-H cpu-list] [-P priority] [-C [cgroup_name]] [--warm-up s]",
- "",
- " -h/--help: print this menu",
+ NULL,
+ };
+
+ static const char * const msg_opts[] = {
" -a/--auto: set automatic trace mode, stopping the session if argument in us sample is hit",
" -p/--period us: osnoise period in us",
" -r/--runtime us: osnoise runtime in us",
@@ -295,25 +297,16 @@ static void osnoise_top_usage(struct osnoise_params *params)
};
if (params->mode == MODE_OSNOISE) {
- fprintf(stderr,
- "rtla osnoise top: a per-cpu summary of the OS noise (version %s)\n",
- VERSION);
-
- fprintf(stderr, " usage: rtla osnoise [top]");
+ tool = "osnoise";
+ mode = "top";
+ desc = "a per-cpu summary of the OS noise";
+ } else {
+ tool = "hwnoise";
+ mode = "";
+ desc = "a summary of hardware-related noise";
}
- if (params->mode == MODE_HWNOISE) {
- fprintf(stderr,
- "rtla hwnoise: a summary of hardware-related noise (version %s)\n",
- VERSION);
-
- fprintf(stderr, " usage: rtla hwnoise");
- }
-
- for (i = 0; msg[i]; i++)
- fprintf(stderr, "%s\n", msg[i]);
-
- exit(EXIT_SUCCESS);
+ common_usage(tool, mode, desc, msg_start, msg_opts);
}
/*
diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c
index 1fb471a787b7..2a5c543217ba 100644
--- a/tools/tracing/rtla/src/timerlat_hist.c
+++ b/tools/tracing/rtla/src/timerlat_hist.c
@@ -696,17 +696,16 @@ timerlat_print_stats(struct osnoise_tool *tool)
*/
static void timerlat_hist_usage(void)
{
- int i;
-
- char *msg[] = {
- "",
- " usage: [rtla] timerlat hist [-h] [-q] [-d s] [-D] [-n] [-a us] [-p us] [-i us] [-T us] [-s us] \\",
+ static const char * const msg_start[] = {
+ "[-d s] [-D] [-n] [-a us] [-p us] [-i us] [-T us] [-s us] \\",
" [-t [file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] [-c cpu-list] [-H cpu-list]\\",
" [-P priority] [-E N] [-b N] [--no-irq] [--no-thread] [--no-header] [--no-summary] \\",
" [--no-index] [--with-zeros] [--dma-latency us] [-C [cgroup_name]] [--no-aa] [--dump-task] [-u|-k]",
" [--warm-up s] [--deepest-idle-state n]",
- "",
- " -h/--help: print this menu",
+ NULL,
+ };
+
+ static const char * const msg_opts[] = {
" -a/--auto: set automatic trace mode, stopping the session if argument in us latency is hit",
" -p/--period us: timerlat period in us",
" -i/--irq us: stop trace if the irq latency is higher than the argument in us",
@@ -750,13 +749,8 @@ static void timerlat_hist_usage(void)
NULL,
};
- fprintf(stderr, "rtla timerlat hist: a per-cpu histogram of the timer latency (version %s)\n",
- VERSION);
-
- for (i = 0; msg[i]; i++)
- fprintf(stderr, "%s\n", msg[i]);
-
- exit(EXIT_SUCCESS);
+ common_usage("timerlat", "hist", "a per-cpu histogram of the timer latency",
+ msg_start, msg_opts);
}
/*
diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c
index 29c2c1f717ed..9ed8b931552f 100644
--- a/tools/tracing/rtla/src/timerlat_top.c
+++ b/tools/tracing/rtla/src/timerlat_top.c
@@ -476,15 +476,14 @@ timerlat_print_stats(struct osnoise_tool *top)
*/
static void timerlat_top_usage(void)
{
- int i;
-
- static const char *const msg[] = {
- "",
- " usage: rtla timerlat [top] [-h] [-q] [-a us] [-d s] [-D] [-n] [-p us] [-i us] [-T us] [-s us] \\",
+ static const char *const msg_start[] = {
+ "[-q] [-a us] [-d s] [-D] [-n] [-p us] [-i us] [-T us] [-s us] \\",
" [[-t [file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] [-c cpu-list] [-H cpu-list]\\",
" [-P priority] [--dma-latency us] [--aa-only us] [-C [cgroup_name]] [-u|-k] [--warm-up s] [--deepest-idle-state n]",
- "",
- " -h/--help: print this menu",
+ NULL,
+ };
+
+ static const char *const msg_opts[] = {
" -a/--auto: set automatic trace mode, stopping the session if argument in us latency is hit",
" --aa-only us: stop if <us> latency is hit, only printing the auto analysis (reduces CPU usage)",
" -p/--period us: timerlat period in us",
@@ -522,13 +521,8 @@ static void timerlat_top_usage(void)
NULL,
};
- fprintf(stderr, "rtla timerlat top: a per-cpu summary of the timer latency (version %s)\n",
- VERSION);
-
- for (i = 0; msg[i]; i++)
- fprintf(stderr, "%s\n", msg[i]);
-
- exit(EXIT_SUCCESS);
+ common_usage("timerlat", "top", "a per-cpu summary of the timer latency",
+ msg_start, msg_opts);
}
/*
--
2.51.1
^ permalink raw reply related
* Re: [PATCH v9 1/2] lib: Introduce hierarchical per-cpu counters
From: Mathieu Desnoyers @ 2025-11-22 17:15 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, Paul E. McKenney, Steven Rostedt, Masami Hiramatsu,
Dennis Zhou, Tejun Heo, Christoph Lameter, Martin Liu,
David Rientjes, christian.koenig, Shakeel Butt, SeongJae Park,
Michal Hocko, Johannes Weiner, Sweet Tea Dorminy, Lorenzo Stoakes,
Liam R . Howlett, Mike Rapoport, Suren Baghdasaryan,
Vlastimil Babka, Christian Brauner, Wei Yang, David Hildenbrand,
Miaohe Lin, Al Viro, linux-mm, linux-trace-kernel, Yu Zhao,
Roman Gushchin, Mateusz Guzik, Matthew Wilcox, Baolin Wang,
Aboorva Devarajan
In-Reply-To: <20251121100308.65b36af9e090a78a66144c6c@linux-foundation.org>
On 2025-11-21 13:03, Andrew Morton wrote:
> On Thu, 20 Nov 2025 16:03:53 -0500 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> wrote:
>> ...
>> It aims at fixing the per-mm RSS tracking which has become too
>> inaccurate for OOM killer purposes on large many-core systems [1].
>
> Presentation nit: the info at [1] is rather well hidden until one reads
> the [2/2] changelog. You might want to move that material into the
> [0/N] - after all, it's the entire point of the patchset.
Will do.
>> The hierarchical per-CPU counters propagate a sum approximation through
>> a N-way tree. When reaching the batch size, the carry is propagated
>> through a binary tree which consists of logN(nr_cpu_ids) levels. The
>> batch size for each level is twice the batch size of the prior level.
>> ...
> Looks very neat.
I'm glad you like the approach :) When looking at this problem, a
hierarchical tree approach seemed like a good candidate to solve the
general problem.
>
> Have you identified other parts of the kernel which could use this?
I have not surveyed other possible users yet. At first glance, users
of the linux/percpu_counter.h percpu_counter_read_positive() may
be good candidates for the hierarchical tree. Here is a list:
lib/flex_proportions.c
157: num = percpu_counter_read_positive(&pl->events);
158: den = percpu_counter_read_positive(&p->events);
fs/file_table.c
88: return percpu_counter_read_positive(&nr_files);
fs/ext4/balloc.c
627: free_clusters = percpu_counter_read_positive(fcc);
628: dirty_clusters = percpu_counter_read_positive(dcc);
fs/ext4/ialloc.c
448: freei = percpu_counter_read_positive(&sbi->s_freeinodes_counter);
450: freec = percpu_counter_read_positive(&sbi->s_freeclusters_counter);
453: ndirs = percpu_counter_read_positive(&sbi->s_dirs_counter);
fs/ext4/extents_status.c
1682: nr = percpu_counter_read_positive(&sbi->s_es_stats.es_stats_shk_cnt);
1694: ret = percpu_counter_read_positive(&sbi->s_es_stats.es_stats_shk_cnt);
1699: ret = percpu_counter_read_positive(&sbi->s_es_stats.es_stats_shk_cnt);
fs/ext4/inode.c
3091: percpu_counter_read_positive(&sbi->s_freeclusters_counter);
3093: percpu_counter_read_positive(&sbi->s_dirtyclusters_counter);
fs/btrfs/space-info.c
1028: ordered = percpu_counter_read_positive(&fs_info->ordered_bytes) >> 1;
1029: delalloc = percpu_counter_read_positive(&fs_info->delalloc_bytes);
fs/quota/dquot.c
808: percpu_counter_read_positive(&dqstats.counter[DQST_FREE_DQUOTS]));
fs/ext2/balloc.c
1162: free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
fs/ext2/ialloc.c
268: freei = percpu_counter_read_positive(&sbi->s_freeinodes_counter);
270: free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
272: ndirs = percpu_counter_read_positive(&sbi->s_dirs_counter);
fs/jbd2/journal.c
1263: count = percpu_counter_read_positive(&journal->j_checkpoint_jh_count);
1268: count = percpu_counter_read_positive(&journal->j_checkpoint_jh_count);
1287: count = percpu_counter_read_positive(&journal->j_checkpoint_jh_count);
fs/xfs/xfs_ioctl.c
1149: .allocino = percpu_counter_read_positive(&mp->m_icount),
1150: .freeino = percpu_counter_read_positive(&mp->m_ifree),
fs/xfs/xfs_mount.h
736: return percpu_counter_read_positive(&mp->m_free[ctr].count);
fs/xfs/libxfs/xfs_ialloc.c
732: percpu_counter_read_positive(&args.mp->m_icount) + newlen >
1913: * Read rough value of mp->m_icount by percpu_counter_read_positive,
1917: percpu_counter_read_positive(&mp->m_icount) + igeo->ialloc_inos
mm/util.c
965: if (percpu_counter_read_positive(&vm_committed_as) < allowed)
drivers/md/dm-crypt.c
1734: if (unlikely(percpu_counter_read_positive(&cc->n_allocated_pages) +
2750: * Note, percpu_counter_read_positive() may over (and under) estimate
2754: if (unlikely(percpu_counter_read_positive(&cc->n_allocated_pages) >= dm_crypt_pages_per_client) &&
io_uring/io_uring.c
2502: return percpu_counter_read_positive(&tctx->inflight);
include/linux/backing-dev.h
71: return percpu_counter_read_positive(&wb->stat[item]);
include/net/sock.h
1435: return percpu_counter_read_positive(sk->sk_prot->sockets_allocated);
include/net/dst_ops.h
48: return percpu_counter_read_positive(&dst->pcpuc_entries);
There are probably other use-cases lurking out there. Anything
that requires sorting resources taken by objects used from many
CPUs concurrently in order to make decisions are good candidates.
The fact that the max inaccuracy is bounded means that we can perform
approximate comparisons in a fast path (which is enough if the values
to compare greatly vary), and only have to do the more expensive
"precise" comparison when values are close to each other and we
actually care about their relative order.
I'm thinking memory usage tracking, runtime usage (scheduler ?), cgroups
ressource accounting.
>
>> include/linux/percpu_counter_tree.h | 239 +++++++++++++++
>> init/main.c | 2 +
>> lib/Makefile | 1 +
>> lib/percpu_counter_tree.c | 443 ++++++++++++++++++++++++++++
>> 4 files changed, 685 insertions(+)
>> create mode 100644 include/linux/percpu_counter_tree.h
>> create mode 100644 lib/percpu_counter_tree.c
>
> An in-kernel test suite would be great. Like lib/*test*.c or
> tools/testing/.
I'll keep a note to port the tests from my userspace librseq
percpu counters feature branch to the kernel. I did not do it
initially because I wanted to see if the overall approach was
deemed interesting for the kernel.
>> +struct percpu_counter_tree {
>>...
>> +};
>
> I find that understanding the data structure leads to understanding the
> code, so additional documentation for the various fields would be
> helpful.
Will do.
>
>> +
>> +static inline
>> +int percpu_counter_tree_carry(int orig, int res, int inc, unsigned int bit_mask)
>> +{
>> ...
>> +}
>> +
>> +static inline
>> +void percpu_counter_tree_add(struct percpu_counter_tree *counter, int inc)
>> +{
>> ...
>> +}
(x86-64 asm below when expanding the inline functions into a real function)
00000000000006a0 <disasm_percpu_counter_tree_add>:
[...]
6a4: 8b 4f 08 mov 0x8(%rdi),%ecx
6a7: 48 8b 17 mov (%rdi),%rdx
6aa: 89 f0 mov %esi,%eax
6ac: 65 0f c1 02 xadd %eax,%gs:(%rdx)
6b0: 41 89 c8 mov %ecx,%r8d
6b3: 8d 14 06 lea (%rsi,%rax,1),%edx
6b6: 41 f7 d8 neg %r8d
6b9: 85 f6 test %esi,%esi
6bb: 78 18 js 6d5 <disasm_percpu_counter_tree_add+0x35>
6bd: 44 21 c6 and %r8d,%esi
6c0: 31 f0 xor %esi,%eax
6c2: 31 d0 xor %edx,%eax
6c4: 8d 14 31 lea (%rcx,%rsi,1),%edx
6c7: 85 c8 test %ecx,%eax
6c9: 0f 45 f2 cmovne %edx,%esi
6cc: 85 f6 test %esi,%esi
6ce: 75 1d jne 6ed <disasm_percpu_counter_tree_add+0x4d>
6d0: e9 00 00 00 00 jmp 6d5 <disasm_percpu_counter_tree_add+0x35>
6d5: f7 de neg %esi
6d7: 44 21 c6 and %r8d,%esi
6da: f7 de neg %esi
6dc: 31 f0 xor %esi,%eax
6de: 31 d0 xor %edx,%eax
6e0: 89 f2 mov %esi,%edx
6e2: 29 ca sub %ecx,%edx
6e4: 85 c8 test %ecx,%eax
6e6: 0f 45 f2 cmovne %edx,%esi
6e9: 85 f6 test %esi,%esi
6eb: 74 e3 je 6d0 <disasm_percpu_counter_tree_add+0x30>
6ed: e9 ae fb ff ff jmp 2a0 <percpu_counter_tree_add_slowpath>
>> +
>> +static inline
>> +int percpu_counter_tree_approximate_sum(struct percpu_counter_tree *counter)
>> +{
>> ...
>> +}
0000000000000710 <disasm_percpu_counter_tree_approximate_sum>:
[...]
714: 48 8b 47 10 mov 0x10(%rdi),%rax
718: 8b 10 mov (%rax),%edx
71a: 8b 47 18 mov 0x18(%rdi),%eax
71d: 01 d0 add %edx,%eax
71f: e9 00 00 00 00 jmp 724 <disasm_percpu_counter_tree_approximate_sum+0x14>
>
> These are pretty large after all the nested inlining is expanded. Are
> you sure that inlining them is the correct call?
percpu_counter_tree_add: 30 insn, 79 bytes
percpu_counter_tree_approximate_sum: 5 insn, 16 bytes
So I agree that inlining "add" may not be the right call there due
to the relatively large footprint of bitwise operations used to pick
the carry, and the fact that it contains a xadd which is ~9 cycles
on recent CPUs, so adding the overhead of a function call should not
be so significant.
Inlining "approximate_sum" seems to be the right call, because the
function is really small (16 bytes), and it only contains loads and
a "add", which are faster than a function call.
>
>
>> +#else /* !CONFIG_SMP */
>> +
>>
>> ...
>>
>> +#include <linux/percpu_counter_tree.h>
>> +#include <linux/cpumask.h>
>> +#include <linux/percpu.h>
>> +#include <linux/atomic.h>
>> +#include <linux/errno.h>
>> +#include <linux/slab.h>
>> +#include <linux/math.h>
>> +
>> +#define MAX_NR_LEVELS 5
>> +
>> +struct counter_config {
>> + unsigned int nr_items;
>> + unsigned char nr_levels;
>> + unsigned char n_arity_order[MAX_NR_LEVELS];
>> +};
>> +
>> +/*
>> + * nr_items is the number of items in the tree for levels 1 to and
>> + * including the final level (approximate sum). It excludes the level 0
>> + * per-cpu counters.
>> + */
>
> That's referring to counter_config.nr_items? Comment appears to be
> misplaced.
Good point, I'll move it besides the "nr_items" field in counter_config.
I'll also document the other fields.
>>...
>> + /* Batch size must be power of 2 */
>> + if (!batch_size || (batch_size & (batch_size - 1)))
>> + return -EINVAL;
>
> It's a bug, yes? Worth a WARN?
I'll add a WARN_ON().
>>...
> It would be nice to kerneldocify the exported API.
OK
>
> Some fairly detailed words explaining the pros and cons of precise vs
> approximate would be helpful to people who are using this API.
Good point.
>> +int __init percpu_counter_tree_subsystem_init(void)
>
> I'm not sure that the "subsystem_" adds any value.
The symbol "percpu_counter_tree_init()" is already taken
for initialization of individual counter trees, so I added
"subsystem" here do distinguish between the two symbols.
Looking at kernel bootup functions "subsystem_init" seems
to be used at least once:
1108: acpi_subsystem_init();
>
>> +{
>> +
>> + nr_cpus_order = get_count_order(nr_cpu_ids);
>
> Stray newline.
OK
Thanks for the review!
Mathieu
--
Mathieu Desnoyers
EfficiOS Inc.
https://www.efficios.com
^ permalink raw reply
* Re: [PATCH bpf-next v3 6/6] bpf: implement "jmp" mode for trampoline
From: Alexei Starovoitov @ 2025-11-22 2:37 UTC (permalink / raw)
To: Steven Rostedt
Cc: Menglong Dong, Alexei Starovoitov, Daniel Borkmann,
John Fastabend, Andrii Nakryiko, Martin KaFai Lau, Eduard,
Song Liu, Yonghong Song, KP Singh, Stanislav Fomichev, Hao Luo,
Jiri Olsa, Masami Hiramatsu, Mark Rutland, Mathieu Desnoyers,
jiang.biao, bpf, LKML, linux-trace-kernel
In-Reply-To: <20251118200304.29f2bd7a@gandalf.local.home>
On Tue, Nov 18, 2025 at 5:02 PM Steven Rostedt <rostedt@goodmis.org> wrote:
>
> On Tue, 18 Nov 2025 16:59:59 -0800
> Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:
>
> > Steven,
> > are you happy with patch 1?
> > Can you pls Ack?
>
> Let me run patch 1 and 2 through my tests.
gentle ping.
^ permalink raw reply
* [PATCH v2] tracing: Add boot-time backup of persistent ring buffer
From: Masami Hiramatsu (Google) @ 2025-11-22 0:31 UTC (permalink / raw)
To: Steven Rostedt
Cc: Masami Hiramatsu, Mathieu Desnoyers, linux-kernel,
linux-trace-kernel
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Currently, the persistent ring buffer instance needs to be read before
using it. This means we have to wait for boot up user space and dump
the persistent ring buffer. However, in that case we can not start
tracing on it from the kernel cmdline.
To solve this limitation, this adds an option which allows to create
a trace instance as a backup of the persistent ring buffer at boot.
If user specifies trace_instance=<BACKUP>=<PERSIST_RB> then the
<BACKUP> instance is made as a copy of the <PERSIST_RB> instance.
For example, the below kernel cmdline records all syscalls, scheduler
and interrupt events on the persistent ring buffer `boot_map` but
before starting the tracing, it makes a `backup` instance from the
`boot_map`. Thus, the `backup` instance has the previous boot events.
'reserve_mem=12M:4M:trace trace_instance=boot_map@trace,syscalls:*,sched:*,irq:* trace_instance=backup=boot_map'
As you can see, this just make a copy of entire reserved area and
make a backup instance on it. So you can release (or shrink) the
backup instance after use it to save the memory usage.
/sys/kernel/tracing/instances # free
total used free shared buff/cache available
Mem: 1999284 55704 1930520 10132 13060 1914628
Swap: 0 0 0
/sys/kernel/tracing/instances # rmdir backup/
/sys/kernel/tracing/instances # free
total used free shared buff/cache available
Mem: 1999284 40640 1945584 10132 13060 1929692
Swap: 0 0 0
Note: since there is no reason to make a copy of empty buffer, this
backup only accepts a persistent ring buffer as the original instance.
Also, since this backup is based on vmalloc(), it does not support
user-space mmap().
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
---
Changes in v2:
- Drop mmap() support on backup ring buffer.
- Add a space between if blocks for readability.
---
kernel/trace/trace.c | 63 +++++++++++++++++++++++++++++++++++++++++++++-----
kernel/trace/trace.h | 1 +
2 files changed, 58 insertions(+), 6 deletions(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index d1e527cf2aae..4b016f949bc3 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -8791,8 +8791,8 @@ static int tracing_buffers_mmap(struct file *filp, struct vm_area_struct *vma)
struct trace_iterator *iter = &info->iter;
int ret = 0;
- /* A memmap'ed buffer is not supported for user space mmap */
- if (iter->tr->flags & TRACE_ARRAY_FL_MEMMAP)
+ /* A memmap'ed and backup buffers are not supported for user space mmap */
+ if (iter->tr->flags & (TRACE_ARRAY_FL_MEMMAP | TRACE_ARRAY_FL_VMALLOC))
return -ENODEV;
ret = get_snapshot_map(iter->tr);
@@ -10206,6 +10206,8 @@ static int __remove_instance(struct trace_array *tr)
reserve_mem_release_by_name(tr->range_name);
kfree(tr->range_name);
}
+ if (tr->flags & TRACE_ARRAY_FL_VMALLOC)
+ vfree((void *)tr->range_addr_start);
for (i = 0; i < tr->nr_topts; i++) {
kfree(tr->topts[i].topts);
@@ -11008,6 +11010,42 @@ __init static void do_allocate_snapshot(const char *name)
static inline void do_allocate_snapshot(const char *name) { }
#endif
+__init static int backup_instance_area(const char *backup,
+ unsigned long *addr, phys_addr_t *size)
+{
+ struct trace_array *backup_tr;
+ void *allocated_vaddr = NULL;
+
+ backup_tr = trace_array_get_by_name(backup, NULL);
+ if (!backup_tr) {
+ pr_warn("Tracing: Instance %s is not found.\n", backup);
+ return -ENOENT;
+ }
+
+ if (!(backup_tr->flags & TRACE_ARRAY_FL_BOOT)) {
+ pr_warn("Tracing: Instance %s is not boot mapped.\n", backup);
+ trace_array_put(backup_tr);
+ return -EINVAL;
+ }
+
+ *size = backup_tr->range_addr_size;
+
+ allocated_vaddr = vzalloc(*size);
+ if (!allocated_vaddr) {
+ pr_warn("Tracing: Failed to allocate memory for copying instance %s (size 0x%lx)\n",
+ backup, (unsigned long)*size);
+ trace_array_put(backup_tr);
+ return -ENOMEM;
+ }
+
+ memcpy(allocated_vaddr,
+ (void *)backup_tr->range_addr_start, (size_t)*size);
+ *addr = (unsigned long)allocated_vaddr;
+
+ trace_array_put(backup_tr);
+ return 0;
+}
+
__init static void enable_instances(void)
{
struct trace_array *tr;
@@ -11030,11 +11068,15 @@ __init static void enable_instances(void)
char *flag_delim;
char *addr_delim;
char *rname __free(kfree) = NULL;
+ char *backup;
tok = strsep(&curr_str, ",");
- flag_delim = strchr(tok, '^');
- addr_delim = strchr(tok, '@');
+ name = strsep(&tok, "=");
+ backup = tok;
+
+ flag_delim = strchr(name, '^');
+ addr_delim = strchr(name, '@');
if (addr_delim)
*addr_delim++ = '\0';
@@ -11042,7 +11084,10 @@ __init static void enable_instances(void)
if (flag_delim)
*flag_delim++ = '\0';
- name = tok;
+ if (backup) {
+ if (backup_instance_area(backup, &addr, &size) < 0)
+ continue;
+ }
if (flag_delim) {
char *flag;
@@ -11138,7 +11183,13 @@ __init static void enable_instances(void)
tr->ref++;
}
- if (start) {
+ /*
+ * Backup buffers can be freed but need vfree().
+ */
+ if (backup)
+ tr->flags |= TRACE_ARRAY_FL_VMALLOC;
+
+ if (start || backup) {
tr->flags |= TRACE_ARRAY_FL_BOOT | TRACE_ARRAY_FL_LAST_BOOT;
tr->range_name = no_free_ptr(rname);
}
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 85eabb454bee..259967c13dbe 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -448,6 +448,7 @@ enum {
TRACE_ARRAY_FL_LAST_BOOT = BIT(2),
TRACE_ARRAY_FL_MOD_INIT = BIT(3),
TRACE_ARRAY_FL_MEMMAP = BIT(4),
+ TRACE_ARRAY_FL_VMALLOC = BIT(5),
};
#ifdef CONFIG_MODULES
^ permalink raw reply related
* Re: [PATCH] tracing: Add boot-time backup of persistent ring buffer
From: Masami Hiramatsu @ 2025-11-21 23:56 UTC (permalink / raw)
To: Steven Rostedt; +Cc: Mathieu Desnoyers, linux-kernel, linux-trace-kernel
In-Reply-To: <20251121134840.0a92f49a@gandalf.local.home>
On Fri, 21 Nov 2025 13:48:40 -0500
Steven Rostedt <rostedt@goodmis.org> wrote:
> On Fri, 21 Nov 2025 16:01:05 +0900
> "Masami Hiramatsu (Google)" <mhiramat@kernel.org> wrote:
>
> > Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
> > ---
> > kernel/trace/trace.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++---
> > kernel/trace/trace.h | 1 +
> > 2 files changed, 55 insertions(+), 4 deletions(-)
> >
> > diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
> > index 33fcde91924c..616d24580371 100644
> > --- a/kernel/trace/trace.c
> > +++ b/kernel/trace/trace.c
> > @@ -10523,6 +10523,8 @@ static int __remove_instance(struct trace_array *tr)
> > reserve_mem_release_by_name(tr->range_name);
> > kfree(tr->range_name);
> > }
> > + if (tr->flags & TRACE_ARRAY_FL_VMALLOC)
> > + vfree((void *)tr->range_addr_start);
>
> The ring buffer user space mapping expects the ring buffer to be real
> memory. Thus, virtual mapping is not supported. Either we need to allocate
> normal memory, or the mmap function of his array must return an error.
Hmm, I think allocating contiguous memory at boot is not realistic,
and mmap support is a lower priority than a single copy at boot time.
> >
> > for (i = 0; i < tr->nr_topts; i++) {
> > kfree(tr->topts[i].topts);
> > @@ -11328,6 +11330,41 @@ __init static void do_allocate_snapshot(const char *name)
> > static inline void do_allocate_snapshot(const char *name) { }
> > #endif
> >
> > +__init static int backup_instance_area(const char *backup,
> > + unsigned long *addr, phys_addr_t *size)
> > +{
> > + struct trace_array *backup_tr;
> > + void *allocated_vaddr = NULL;
> > +
> > + backup_tr = trace_array_get_by_name(backup, NULL);
> > + if (!backup_tr) {
> > + pr_warn("Tracing: Instance %s is not found.\n", backup);
> > + return -ENOENT;
> > + }
>
> Add space.
OK
>
> > + if (!(backup_tr->flags & TRACE_ARRAY_FL_BOOT)) {
> > + pr_warn("Tracing: Instance %s is not boot mapped.\n", backup);
> > + trace_array_put(backup_tr);
> > + return -EINVAL;
> > + }
> > +
> > + *size = backup_tr->range_addr_size;
> > +
> > + allocated_vaddr = vzalloc(*size);
> > + if (!allocated_vaddr) {
> > + pr_warn("Tracing: Failed to allocate memory for copying instance %s (size 0x%lx)\n",
> > + backup, (unsigned long)*size);
> > + trace_array_put(backup_tr);
> > + return -ENOMEM;
> > + }
> > +
> > + memcpy(allocated_vaddr,
> > + (void *)backup_tr->range_addr_start, (size_t)*size);
> > + *addr = (unsigned long)allocated_vaddr;
> > +
> > + trace_array_put(backup_tr);
> > + return 0;
> > +}
> > +
> > __init static void enable_instances(void)
> > {
> > struct trace_array *tr;
> > @@ -11350,11 +11387,15 @@ __init static void enable_instances(void)
> > char *flag_delim;
> > char *addr_delim;
> > char *rname __free(kfree) = NULL;
> > + char *backup;
> >
> > tok = strsep(&curr_str, ",");
> >
> > - flag_delim = strchr(tok, '^');
> > - addr_delim = strchr(tok, '@');
> > + name = strsep(&tok, "=");
> > + backup = tok;
> > +
> > + flag_delim = strchr(name, '^');
> > + addr_delim = strchr(name, '@');
> >
> > if (addr_delim)
> > *addr_delim++ = '\0';
> > @@ -11362,7 +11403,10 @@ __init static void enable_instances(void)
> > if (flag_delim)
> > *flag_delim++ = '\0';
> >
> > - name = tok;
> > + if (backup) {
> > + if (backup_instance_area(backup, &addr, &size) < 0)
> > + continue;
> > + }
> >
> > if (flag_delim) {
> > char *flag;
> > @@ -11458,7 +11502,13 @@ __init static void enable_instances(void)
> > tr->ref++;
> > }
> >
> > - if (start) {
> > + /*
> > + * Backup buffers can be freed but need vfree().
> > + */
> > + if (backup)
> > + tr->flags |= TRACE_ARRAY_FL_VMALLOC;
> > +
> > + if (start || backup) {
> > tr->flags |= TRACE_ARRAY_FL_BOOT | TRACE_ARRAY_FL_LAST_BOOT;
> > tr->range_name = no_free_ptr(rname);
> > }
>
> This would then need:
>
> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
> index d1e527cf2aae..104e385e718e 100644
> --- a/kernel/trace/trace.c
> +++ b/kernel/trace/trace.c
> @@ -8791,8 +8791,8 @@ static int tracing_buffers_mmap(struct file *filp, struct vm_area_struct *vma)
> struct trace_iterator *iter = &info->iter;
> int ret = 0;
>
> - /* A memmap'ed buffer is not supported for user space mmap */
> - if (iter->tr->flags & TRACE_ARRAY_FL_MEMMAP)
> + /* A memmap'ed and backup buffers are not supported for user space mmap */
> + if (iter->tr->flags & (TRACE_ARRAY_FL_MEMMAP | TRACE_ARRAY_FL_VMALLOC))
> return -ENODEV;
>
> ret = get_snapshot_map(iter->tr);
>
Ah, thanks for the code :)
>
> As without it, when I tried mmapping the backup buffer I got this;
>
> [ 251.615441] BUG: unable to handle page fault for address: ffffd1c31e0000c8
> [ 251.615447] #PF: supervisor read access in kernel mode
> [ 251.615449] #PF: error_code(0x0000) - not-present page
> [ 251.615451] PGD 0 P4D 0
> [ 251.615456] Oops: Oops: 0000 [#1] SMP PTI
> [ 251.615463] CPU: 6 UID: 0 PID: 1450 Comm: mmap-rb-lib Not tainted 6.18.0-rc3-ftest-00018-g02548113c2f6 #287 PREEMPT_{RT,LAZY}
> [ 251.615469] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
> [ 251.615471] RIP: 0010:validate_page_before_insert+0x5/0x90
> [ 251.615479] Code: 48 c1 e8 0e 89 c2 83 e2 01 89 d0 c3 cc cc cc cc 0f 1f 44 00 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 0f 1f 44 00 00 <48> 8b 46 08 a8 01 75 5d 66 90 48 89 f0 8b 50 34 85 d2 74 68 48 89
> [ 251.615481] RSP: 0018:ffffa52b443d7988 EFLAGS: 00010246
> [ 251.615484] RAX: ffff8a84dcac4000 RBX: 00007f07e0c10000 RCX: 0000000108d2f067
> [ 251.615486] RDX: 0000000108d2f067 RSI: ffffd1c31e0000c0 RDI: ffff8a84dd865700
> [ 251.615487] RBP: 0000000000000000 R08: 000000005ab70715 R09: 0000000000000009
> [ 251.615489] R10: 0000000000000009 R11: ffff8a84c9320fb8 R12: ffff8a84dd865700
> [ 251.615490] R13: 0000000000000000 R14: ffffd1c31e0000c0 R15: ffff8a84c8d2f080
> [ 251.615492] FS: 00007f07e0e8e740(0000) GS:ffff8a86afbb7000(0000) knlGS:0000000000000000
> [ 251.615494] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 251.615496] CR2: ffffd1c31e0000c8 CR3: 000000011c390006 CR4: 0000000000170ef0
> [ 251.615501] Call Trace:
> [ 251.615502] <TASK>
> [ 251.615504] vm_insert_pages+0x157/0x360
> [ 251.615513] __rb_map_vma+0x1ef/0x390
> [ 251.615521] ring_buffer_map+0x261/0x370
> [ 251.615527] tracing_buffers_mmap+0x7e/0x100
> [ 251.615532] __mmap_region+0x831/0xe00
> [ 251.615554] do_mmap+0x4bf/0x6b0
> [ 251.615560] vm_mmap_pgoff+0x126/0x230
> [ 251.615569] ksys_mmap_pgoff+0x162/0x220
> [ 251.615573] do_syscall_64+0x76/0x9a0
> [ 251.615581] entry_SYSCALL_64_after_hwframe+0x76/0x7e
> [ 251.615584] RIP: 0033:0x7f07e0f9dde2
> [ 251.615589] Code: 00 00 00 0f 1f 44 00 00
>
> -- Steve
>
>
> > diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
> > index 58be6d741d72..9e5186c96e9c 100644
> > --- a/kernel/trace/trace.h
> > +++ b/kernel/trace/trace.h
> > @@ -453,6 +453,7 @@ enum {
> > TRACE_ARRAY_FL_LAST_BOOT = BIT(2),
> > TRACE_ARRAY_FL_MOD_INIT = BIT(3),
> > TRACE_ARRAY_FL_MEMMAP = BIT(4),
> > + TRACE_ARRAY_FL_VMALLOC = BIT(5),
> > };
> >
> > #ifdef CONFIG_MODULES
>
>
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply
* Re: [PATCH] tracing: Add system trigger file to enable triggers for all the system's events
From: kernel test robot @ 2025-11-21 23:53 UTC (permalink / raw)
To: Steven Rostedt, LKML, Linux Trace Kernel
Cc: llvm, oe-kbuild-all, Masami Hiramatsu, Mathieu Desnoyers,
Tom Zanussi
In-Reply-To: <20251120160003.2fa33d80@gandalf.local.home>
Hi Steven,
kernel test robot noticed the following build warnings:
[auto build test WARNING on trace/for-next]
[also build test WARNING on linus/master v6.18-rc6 next-20251121]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Steven-Rostedt/tracing-Add-system-trigger-file-to-enable-triggers-for-all-the-system-s-events/20251121-050454
base: https://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace for-next
patch link: https://lore.kernel.org/r/20251120160003.2fa33d80%40gandalf.local.home
patch subject: [PATCH] tracing: Add system trigger file to enable triggers for all the system's events
config: sparc64-defconfig (https://download.01.org/0day-ci/archive/20251122/202511220730.PQFWRcck-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251122/202511220730.PQFWRcck-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202511220730.PQFWRcck-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> kernel/trace/trace_events_trigger.c:432:6: warning: variable 'len' set but not used [-Wunused-but-set-variable]
432 | int len;
| ^
1 warning generated.
vim +/len +432 kernel/trace/trace_events_trigger.c
420
421 static ssize_t
422 event_system_trigger_write(struct file *filp, const char __user *ubuf,
423 size_t cnt, loff_t *ppos)
424 {
425 struct trace_subsystem_dir *dir = filp->private_data;
426 struct event_command *p;
427 char *command, *next;
428 char *buf __free(kfree) = get_user_buf(ubuf, cnt);
429 bool remove = false;
430 bool found = false;
431 ssize_t ret;
> 432 int len;
433
434 if (!buf)
435 return 0;
436
437 if (IS_ERR(buf))
438 return PTR_ERR(buf);
439
440 /* system triggers are not allowed to have counters */
441 if (strchr(buf, ':'))
442 return -EINVAL;
443
444 /* If opened for read too, dir is in the seq_file descriptor */
445 if (filp->f_mode & FMODE_READ) {
446 struct seq_file *m = filp->private_data;
447 dir = m->private;
448 }
449
450 /* Skip added space at beginning of buf */
451 next = buf;
452 strim(next);
453
454 command = strsep(&next, " \t");
455 if (next) {
456 next = skip_spaces(next);
457 if (!*next)
458 next = NULL;
459 }
460 if (command[0] == '!') {
461 remove = true;
462 command++;
463 }
464
465 len = strlen(command);
466 if (next)
467 len += strlen(next) + 1;
468
469 guard(mutex)(&event_mutex);
470 guard(mutex)(&trigger_cmd_mutex);
471
472 list_for_each_entry(p, &trigger_commands, list) {
473 /* Allow to remove any trigger */
474 if (!remove && !(p->flags & EVENT_CMD_FL_SYSTEM))
475 continue;
476 if (strcmp(p->name, command) == 0) {
477 found = true;
478 ret = process_system_events(dir, p, buf, command, next);
479 break;
480 }
481 }
482
483 if (!found)
484 ret = -ENODEV;
485
486 if (!ret)
487 *ppos += cnt;
488
489 if (remove || ret < 0)
490 return ret ? : cnt;
491
492 return cnt;
493 }
494
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* [PATCH v2 11/13] tracing: Fix multiple typos in trace_osnoise.c
From: Maurice Hieronymus @ 2025-11-21 22:18 UTC (permalink / raw)
To: rostedt, mhiramat; +Cc: linux-kernel, linux-trace-kernel, mhi
In-Reply-To: <20251121221835.28032-1-mhi@mailbox.org>
Fix multiple typos in comments:
"Anotate" -> "Annotate"
"infor" -> "info"
"timestemp" -> "timestamp"
"tread" -> "thread"
"varaibles" -> "variables"
"wast" -> "waste"
Signed-off-by: Maurice Hieronymus <mhi@mailbox.org>
---
kernel/trace/trace_osnoise.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c
index a9962d4497e8..827104d00bc0 100644
--- a/kernel/trace/trace_osnoise.c
+++ b/kernel/trace/trace_osnoise.c
@@ -329,7 +329,7 @@ static struct osnoise_data {
u64 print_stack; /* print IRQ stack if total > */
int timerlat_tracer; /* timerlat tracer */
#endif
- bool tainted; /* infor users and developers about a problem */
+ bool tainted; /* info users and developers about a problem */
} osnoise_data = {
.sample_period = DEFAULT_SAMPLE_PERIOD,
.sample_runtime = DEFAULT_SAMPLE_RUNTIME,
@@ -738,7 +738,7 @@ cond_move_thread_delta_start(struct osnoise_variables *osn_var, u64 duration)
/*
* get_int_safe_duration - Get the duration of a window
*
- * The irq, softirq and thread varaibles need to have its duration without
+ * The irq, softirq and thread variables need to have its duration without
* the interference from higher priority interrupts. Instead of keeping a
* variable to discount the interrupt interference from these variables, the
* starting time of these variables are pushed forward with the interrupt's
@@ -1460,7 +1460,7 @@ static int run_osnoise(void)
stop_in = osnoise_data.stop_tracing * NSEC_PER_USEC;
/*
- * Start timestemp
+ * Start timestamp
*/
start = time_get();
@@ -1881,7 +1881,7 @@ static int timerlat_main(void *data)
tlat->kthread = current;
osn_var->pid = current->pid;
/*
- * Anotate the arrival time.
+ * Annotate the arrival time.
*/
tlat->abs_period = hrtimer_cb_get_time(&tlat->timer);
@@ -1978,7 +1978,7 @@ static void stop_per_cpu_kthreads(void)
}
/*
- * start_kthread - Start a workload tread
+ * start_kthread - Start a workload thread
*/
static int start_kthread(unsigned int cpu)
{
@@ -2705,7 +2705,7 @@ static int osnoise_create_cpu_timerlat_fd(struct dentry *top_dir)
* Why not using tracing instance per_cpu/ dir?
*
* Because osnoise/timerlat have a single workload, having
- * multiple files like these are wast of memory.
+ * multiple files like these are waste of memory.
*/
per_cpu = tracefs_create_dir("per_cpu", top_dir);
if (!per_cpu)
--
2.50.1
^ permalink raw reply related
* [PATCH v2 09/13] tracing: Fix typo in trace_events_trigger.c
From: Maurice Hieronymus @ 2025-11-21 22:18 UTC (permalink / raw)
To: rostedt, mhiramat; +Cc: linux-kernel, linux-trace-kernel, mhi
In-Reply-To: <20251121221835.28032-1-mhi@mailbox.org>
Fix typo "componenents" to "components".
Signed-off-by: Maurice Hieronymus <mhi@mailbox.org>
---
kernel/trace/trace_events_trigger.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c
index cbfc306c0159..4f3627060e59 100644
--- a/kernel/trace/trace_events_trigger.c
+++ b/kernel/trace/trace_events_trigger.c
@@ -644,7 +644,7 @@ static void unregister_trigger(char *glob,
* param - text following cmd and ':' and stripped of filter
* filter - the optional filter text following (and including) 'if'
*
- * To illustrate the use of these componenents, here are some concrete
+ * To illustrate the use of these components, here are some concrete
* examples. For the following triggers:
*
* echo 'traceon:5 if pid == 0' > trigger
--
2.50.1
^ permalink raw reply related
* [PATCH v2 13/13] tracing: Fix typo in trace_seq.c
From: Maurice Hieronymus @ 2025-11-21 22:18 UTC (permalink / raw)
To: rostedt, mhiramat; +Cc: linux-kernel, linux-trace-kernel, mhi
In-Reply-To: <20251121221835.28032-1-mhi@mailbox.org>
Fix typo "wont" to "won't".
Signed-off-by: Maurice Hieronymus <mhi@mailbox.org>
---
kernel/trace/trace_seq.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/trace/trace_seq.c b/kernel/trace/trace_seq.c
index c158d65a8a88..32684ef4fb9d 100644
--- a/kernel/trace/trace_seq.c
+++ b/kernel/trace/trace_seq.c
@@ -15,7 +15,7 @@
*
* A write to the buffer will either succeed or fail. That is, unlike
* sprintf() there will not be a partial write (well it may write into
- * the buffer but it wont update the pointers). This allows users to
+ * the buffer but it won't update the pointers). This allows users to
* try to write something into the trace_seq buffer and if it fails
* they can flush it and try again.
*
--
2.50.1
^ permalink raw reply related
* [PATCH v2 08/13] tracing: Fix typo in trace_events_hist.c
From: Maurice Hieronymus @ 2025-11-21 22:18 UTC (permalink / raw)
To: rostedt, mhiramat; +Cc: linux-kernel, linux-trace-kernel, mhi
In-Reply-To: <20251121221835.28032-1-mhi@mailbox.org>
Fix typo "tigger" to "trigger".
Signed-off-by: Maurice Hieronymus <mhi@mailbox.org>
---
kernel/trace/trace_events_hist.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index 6bfaf1210dd2..1b6b9c789da1 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -5283,7 +5283,7 @@ hist_trigger_actions(struct hist_trigger_data *hist_data,
* on the stack, so when the histogram trigger is initialized
* a percpu array of 4 hist_pad structures is allocated.
* This will cover every context from normal, softirq, irq and NMI
- * in the very unlikely event that a tigger happens at each of
+ * in the very unlikely event that a trigger happens at each of
* these contexts and interrupts a currently active trigger.
*/
struct hist_pad {
--
2.50.1
^ permalink raw reply related
* [PATCH v2 12/13] tracing: Fix typo in trace_probe.c
From: Maurice Hieronymus @ 2025-11-21 22:18 UTC (permalink / raw)
To: rostedt, mhiramat; +Cc: linux-kernel, linux-trace-kernel, mhi
In-Reply-To: <20251121221835.28032-1-mhi@mailbox.org>
Fix typo "separater" to "separator".
Signed-off-by: Maurice Hieronymus <mhi@mailbox.org>
---
kernel/trace/trace_probe.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
index bb67f6a2136c..2f571083ce9e 100644
--- a/kernel/trace/trace_probe.c
+++ b/kernel/trace/trace_probe.c
@@ -517,7 +517,7 @@ static void clear_btf_context(struct traceprobe_parse_context *ctx)
}
}
-/* Return 1 if the field separater is arrow operator ('->') */
+/* Return 1 if the field separator is arrow operator ('->') */
static int split_next_field(char *varname, char **next_field,
struct traceprobe_parse_context *ctx)
{
--
2.50.1
^ permalink raw reply related
* [PATCH v2 10/13] tracing: Fix multiple typos in trace_events_user.c
From: Maurice Hieronymus @ 2025-11-21 22:18 UTC (permalink / raw)
To: rostedt, mhiramat; +Cc: linux-kernel, linux-trace-kernel, mhi
In-Reply-To: <20251121221835.28032-1-mhi@mailbox.org>
Fix multiple typos in comments:
"ambigious" -> "ambiguous"
"explictly" -> "explicitly"
"Uknown" -> "Unknown"
Signed-off-by: Maurice Hieronymus <mhi@mailbox.org>
---
kernel/trace/trace_events_user.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/kernel/trace/trace_events_user.c b/kernel/trace/trace_events_user.c
index c428dafe7496..778f13ef94cf 100644
--- a/kernel/trace/trace_events_user.c
+++ b/kernel/trace/trace_events_user.c
@@ -1041,7 +1041,7 @@ static int user_field_array_size(const char *type)
static int user_field_size(const char *type)
{
- /* long is not allowed from a user, since it's ambigious in size */
+ /* long is not allowed from a user, since it's ambiguous in size */
if (strcmp(type, "s64") == 0)
return sizeof(s64);
if (strcmp(type, "u64") == 0)
@@ -1079,7 +1079,7 @@ static int user_field_size(const char *type)
if (str_has_prefix(type, "__rel_loc "))
return sizeof(u32);
- /* Uknown basic type, error */
+ /* Unknown basic type, error */
return -EINVAL;
}
@@ -2475,7 +2475,7 @@ static long user_events_ioctl_reg(struct user_event_file_info *info,
/*
* Prevent users from using the same address and bit multiple times
* within the same mm address space. This can cause unexpected behavior
- * for user processes that is far easier to debug if this is explictly
+ * for user processes that is far easier to debug if this is explicitly
* an error upon registering.
*/
if (current_user_event_enabler_exists((unsigned long)reg.enable_addr,
--
2.50.1
^ permalink raw reply related
* [PATCH v2 07/13] tracing: Fix typo in trace_events_filter.c
From: Maurice Hieronymus @ 2025-11-21 22:18 UTC (permalink / raw)
To: rostedt, mhiramat; +Cc: linux-kernel, linux-trace-kernel, mhi
In-Reply-To: <20251121221835.28032-1-mhi@mailbox.org>
Fix typo "singe" to "single".
Signed-off-by: Maurice Hieronymus <mhi@mailbox.org>
---
kernel/trace/trace_events_filter.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index 54226b48b2d1..385af8405392 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -142,7 +142,7 @@ static bool is_not(const char *str)
}
/**
- * struct prog_entry - a singe entry in the filter program
+ * struct prog_entry - a single entry in the filter program
* @target: Index to jump to on a branch (actually one minus the index)
* @when_to_branch: The value of the result of the predicate to do a branch
* @pred: The predicate to execute.
--
2.50.1
^ permalink raw reply related
* [PATCH v2 06/13] tracing: Fix multiple typos in trace_events.c
From: Maurice Hieronymus @ 2025-11-21 22:18 UTC (permalink / raw)
To: rostedt, mhiramat; +Cc: linux-kernel, linux-trace-kernel, mhi
In-Reply-To: <20251121221835.28032-1-mhi@mailbox.org>
Fix multiple typos in comments:
"appened" -> "appended"
"paranthesis" -> "parenthesis"
"parethesis" -> "parenthesis"
"wont" -> "won't"
Signed-off-by: Maurice Hieronymus <mhi@mailbox.org>
---
kernel/trace/trace_events.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 9b07ad9eb284..b16a5a158040 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -360,7 +360,7 @@ static bool process_string(const char *fmt, int len, struct trace_event_call *ca
/* Anything else, this isn't a function */
break;
}
- /* A function could be wrapped in parethesis, try the next one */
+ /* A function could be wrapped in parenthesis, try the next one */
s = r + 1;
} while (s < e);
@@ -567,7 +567,7 @@ static void test_event_printk(struct trace_event_call *call)
* If start_arg is zero, then this is the start of the
* first argument. The processing of the argument happens
* when the end of the argument is found, as it needs to
- * handle paranthesis and such.
+ * handle parenthesis and such.
*/
if (!start_arg) {
start_arg = i;
@@ -785,7 +785,7 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file,
*
* When soft_disable is not set but the soft_mode is,
* we do nothing. Do not disable the tracepoint, otherwise
- * "soft enable"s (clearing the SOFT_DISABLED bit) wont work.
+ * "soft enable"s (clearing the SOFT_DISABLED bit) won't work.
*/
if (soft_disable) {
if (atomic_dec_return(&file->sm_ref) > 0)
@@ -1394,7 +1394,7 @@ int ftrace_set_clr_event(struct trace_array *tr, char *buf, int set)
if (!tr)
return -ENOENT;
- /* Modules events can be appened with :mod:<module> */
+ /* Modules events can be appended with :mod:<module> */
mod = strstr(buf, ":mod:");
if (mod) {
*mod = '\0';
--
2.50.1
^ permalink raw reply related
* [PATCH v2 05/13] tracing: Fix multiple typos in trace.c
From: Maurice Hieronymus @ 2025-11-21 22:18 UTC (permalink / raw)
To: rostedt, mhiramat; +Cc: linux-kernel, linux-trace-kernel, mhi
In-Reply-To: <20251121221835.28032-1-mhi@mailbox.org>
Fix multiple typos in comments:
"alse" -> "also"
"enabed" -> "enabled"
"instane" -> "instance"
"outputing" -> "outputting"
"seperated" -> "separated"
Signed-off-by: Maurice Hieronymus <mhi@mailbox.org>
---
kernel/trace/trace.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 8ae95800592d..966d29cc7513 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -125,7 +125,7 @@ cpumask_var_t __read_mostly tracing_buffer_mask;
* If there is an oops (or kernel panic) and the ftrace_dump_on_oops
* is set, then ftrace_dump is called. This will output the contents
* of the ftrace buffers to the console. This is very useful for
- * capturing traces that lead to crashes and outputing it to a
+ * capturing traces that lead to crashes and outputting it to a
* serial console.
*
* It is default off, but you can enable it with either specifying
@@ -134,7 +134,7 @@ cpumask_var_t __read_mostly tracing_buffer_mask;
* Set 1 if you want to dump buffers of all CPUs
* Set 2 if you want to dump the buffer of the CPU that triggered oops
* Set instance name if you want to dump the specific trace instance
- * Multiple instance dump is also supported, and instances are seperated
+ * Multiple instance dump is also supported, and instances are separated
* by commas.
*/
/* Set to string format zero to disable by default */
@@ -5279,7 +5279,7 @@ int set_tracer_flag(struct trace_array *tr, u64 mask, int enabled)
return -EINVAL;
/*
* An instance must always have it set.
- * by default, that's the global_trace instane.
+ * by default, that's the global_trace instance.
*/
if (printk_trace == tr)
update_printk_trace(&global_trace);
@@ -7557,7 +7557,7 @@ char *trace_user_fault_read(struct trace_user_buf_info *tinfo,
migrate_disable();
/*
- * Now preemption is being enabed and another task can come in
+ * Now preemption is being enabled and another task can come in
* and use the same buffer and corrupt our data.
*/
preempt_enable_notrace();
@@ -11316,7 +11316,7 @@ __init static void do_allocate_snapshot(const char *name)
/*
* When allocate_snapshot is set, the next call to
* allocate_trace_buffers() (called by trace_array_get_by_name())
- * will allocate the snapshot buffer. That will alse clear
+ * will allocate the snapshot buffer. That will also clear
* this flag.
*/
allocate_snapshot = true;
--
2.50.1
^ permalink raw reply related
* [PATCH v2 01/13] tracing: Fix typo in fgraph.c
From: Maurice Hieronymus @ 2025-11-21 22:18 UTC (permalink / raw)
To: rostedt, mhiramat; +Cc: linux-kernel, linux-trace-kernel, mhi
In-Reply-To: <20251121221835.28032-1-mhi@mailbox.org>
Fix typo "reservered" to "reserved".
Signed-off-by: Maurice Hieronymus <mhi@mailbox.org>
---
kernel/trace/fgraph.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/trace/fgraph.c b/kernel/trace/fgraph.c
index 7fb9b169d6d4..8ba62fe986f1 100644
--- a/kernel/trace/fgraph.c
+++ b/kernel/trace/fgraph.c
@@ -163,7 +163,7 @@ enum {
#define RET_STACK(t, offset) ((struct ftrace_ret_stack *)(&(t)->ret_stack[offset]))
/*
- * Each fgraph_ops has a reservered unsigned long at the end (top) of the
+ * Each fgraph_ops has a reserved unsigned long at the end (top) of the
* ret_stack to store task specific state.
*/
#define SHADOW_STACK_TASK_VARS(ret_stack) \
--
2.50.1
^ permalink raw reply related
* [PATCH v2 04/13] tracing: Fix typo in ring_buffer_benchmark.c
From: Maurice Hieronymus @ 2025-11-21 22:18 UTC (permalink / raw)
To: rostedt, mhiramat; +Cc: linux-kernel, linux-trace-kernel, mhi
In-Reply-To: <20251121221835.28032-1-mhi@mailbox.org>
Fix typo "overwite" to "overwrite".
Signed-off-by: Maurice Hieronymus <mhi@mailbox.org>
---
kernel/trace/ring_buffer_benchmark.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/trace/ring_buffer_benchmark.c b/kernel/trace/ring_buffer_benchmark.c
index cdc3aea12c93..593e3b59e42e 100644
--- a/kernel/trace/ring_buffer_benchmark.c
+++ b/kernel/trace/ring_buffer_benchmark.c
@@ -433,7 +433,7 @@ static int __init ring_buffer_benchmark_init(void)
{
int ret;
- /* make a one meg buffer in overwite mode */
+ /* make a one meg buffer in overwrite mode */
buffer = ring_buffer_alloc(1000000, RB_FL_OVERWRITE);
if (!buffer)
return -ENOMEM;
--
2.50.1
^ permalink raw reply related
* [PATCH v2 03/13] tracing: Fix multiple typos in ring_buffer.c
From: Maurice Hieronymus @ 2025-11-21 22:18 UTC (permalink / raw)
To: rostedt, mhiramat; +Cc: linux-kernel, linux-trace-kernel, mhi
In-Reply-To: <20251121221835.28032-1-mhi@mailbox.org>
Fix multiple typos in comments:
"ording" -> "ordering"
"scatch" -> "scratch"
"wont" -> "won't"
Signed-off-by: Maurice Hieronymus <mhi@mailbox.org>
---
kernel/trace/ring_buffer.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index afcd3747264d..9139a020ece4 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -1735,7 +1735,7 @@ static bool rb_meta_init(struct trace_buffer *buffer, int scratch_size)
bmeta->total_size = total_size;
bmeta->buffers_offset = (void *)ptr - (void *)bmeta;
- /* Zero out the scatch pad */
+ /* Zero out the scratch pad */
memset((void *)bmeta + sizeof(*bmeta), 0, bmeta->buffers_offset - sizeof(*bmeta));
return false;
@@ -6073,7 +6073,7 @@ static void rb_clear_buffer_page(struct buffer_page *page)
* id field, and updated via this function.
*
* But for a fixed memory mapped buffer, the id is already assigned for
- * fixed memory ording in the memory layout and can not be used. Instead
+ * fixed memory ordering in the memory layout and can not be used. Instead
* the index of where the page lies in the memory layout is used.
*
* For the normal pages, set the buffer page id with the passed in @id
@@ -7660,7 +7660,7 @@ static __init int test_ringbuffer(void)
/*
* Show buffer is enabled before setting rb_test_started.
* Yes there's a small race window where events could be
- * dropped and the thread wont catch it. But when a ring
+ * dropped and the thread won't catch it. But when a ring
* buffer gets enabled, there will always be some kind of
* delay before other CPUs see it. Thus, we don't care about
* those dropped events. We care about events dropped after
--
2.50.1
^ permalink raw reply related
* [PATCH v2 02/13] tracing: Fix typo in fprobe.c
From: Maurice Hieronymus @ 2025-11-21 22:18 UTC (permalink / raw)
To: rostedt, mhiramat; +Cc: linux-kernel, linux-trace-kernel, mhi
In-Reply-To: <20251121221835.28032-1-mhi@mailbox.org>
Fix typo "funciton" to "function".
Signed-off-by: Maurice Hieronymus <mhi@mailbox.org>
---
kernel/trace/fprobe.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/trace/fprobe.c b/kernel/trace/fprobe.c
index 0b1ee8e585f2..1188eefef07c 100644
--- a/kernel/trace/fprobe.c
+++ b/kernel/trace/fprobe.c
@@ -30,7 +30,7 @@
* fprobe_table: hold 'fprobe_hlist::hlist' for checking the fprobe still
* exists. The key is the address of fprobe instance.
* fprobe_ip_table: hold 'fprobe_hlist::array[*]' for searching the fprobe
- * instance related to the funciton address. The key is the ftrace IP
+ * instance related to the function address. The key is the ftrace IP
* address.
*
* When unregistering the fprobe, fprobe_hlist::fp and fprobe_hlist::array[*].fp
--
2.50.1
^ permalink raw reply related
* [PATCH v2 01/13] tracing: Fix typo in fpgraph.c
From: Maurice Hieronymus @ 2025-11-21 22:18 UTC (permalink / raw)
To: rostedt, mhiramat; +Cc: linux-kernel, linux-trace-kernel, mhi
In-Reply-To: <20251121221835.28032-1-mhi@mailbox.org>
Fix typo "reservered" to "reserved".
Signed-off-by: Maurice Hieronymus <mhi@mailbox.org>
---
kernel/trace/fgraph.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/trace/fgraph.c b/kernel/trace/fgraph.c
index 7fb9b169d6d4..8ba62fe986f1 100644
--- a/kernel/trace/fgraph.c
+++ b/kernel/trace/fgraph.c
@@ -163,7 +163,7 @@ enum {
#define RET_STACK(t, offset) ((struct ftrace_ret_stack *)(&(t)->ret_stack[offset]))
/*
- * Each fgraph_ops has a reservered unsigned long at the end (top) of the
+ * Each fgraph_ops has a reserved unsigned long at the end (top) of the
* ret_stack to store task specific state.
*/
#define SHADOW_STACK_TASK_VARS(ret_stack) \
--
2.50.1
^ permalink raw reply related
* [PATCH v2 00/13] tracing: Fix several comment spelling mistakes
From: Maurice Hieronymus @ 2025-11-21 22:18 UTC (permalink / raw)
To: rostedt, mhiramat; +Cc: linux-kernel, linux-trace-kernel, mhi
Fix several spelling mistakes in comments in the trace subsystem.
No functional changes. These fixes improve readability and correctness
of comments in the tracing subsystem.
Changes from v1:
https://lore.kernel.org/all/20251116210302.141405-1-mhi@mailbox.org/
- Split up changes in patch per file
- Base work on trace/for-next instead of trace/master
Maurice Hieronymus (13):
tracing: Fix typo in fgraph.c
tracing: Fix typo in fprobe.c
tracing: Fix multiple typos in ring_buffer.c
tracing: Fix typo in ring_buffer_benchmark.c
tracing: Fix multiple typos in trace.c
tracing: Fix multiple typos in trace_events.c
tracing: Fix typo in trace_events_filter.c
tracing: Fix typo in trace_events_hist.c
tracing: Fix typo in trace_events_trigger.c
tracing: Fix multiple typos in trace_events_user.c
tracing: Fix multiple typos in trace_osnoise.c
tracing: Fix typo in trace_probe.c
tracing: Fix typo in trace_seq.c
kernel/trace/fgraph.c | 2 +-
kernel/trace/fprobe.c | 2 +-
kernel/trace/ring_buffer.c | 6 +++---
kernel/trace/ring_buffer_benchmark.c | 2 +-
kernel/trace/trace.c | 10 +++++-----
kernel/trace/trace_events.c | 8 ++++----
kernel/trace/trace_events_filter.c | 2 +-
kernel/trace/trace_events_hist.c | 2 +-
kernel/trace/trace_events_trigger.c | 2 +-
kernel/trace/trace_events_user.c | 6 +++---
kernel/trace/trace_osnoise.c | 12 ++++++------
kernel/trace/trace_probe.c | 2 +-
kernel/trace/trace_seq.c | 2 +-
13 files changed, 29 insertions(+), 29 deletions(-)
base-commit: b668bb6dfc3a72a98994671898af28c39bd3cb6a
--
2.50.1
^ permalink raw reply
* Re: [PATCH 2/3] tracing: Add bulk garbage collection of freeing event_trigger_data
From: Steven Rostedt @ 2025-11-21 19:51 UTC (permalink / raw)
To: Masami Hiramatsu (Google)
Cc: Steven Rostedt, linux-kernel, linux-trace-kernel, Mark Rutland,
Mathieu Desnoyers, Andrew Morton, Tom Zanussi
In-Reply-To: <20251122001206.57ad6d77b96726421503da41@kernel.org>
On Sat, 22 Nov 2025 00:12:06 +0900
Masami Hiramatsu (Google) <mhiramat@kernel.org> wrote:
> > /* Avoid typos */
> > diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c
> > index e5dcfcbb2cd5..16e3449f3cfe 100644
> > --- a/kernel/trace/trace_events_trigger.c
> > +++ b/kernel/trace/trace_events_trigger.c
> > @@ -6,26 +6,76 @@
> > */
> >
> > #include <linux/security.h>
> > +#include <linux/kthread.h>
> > #include <linux/module.h>
> > #include <linux/ctype.h>
> > #include <linux/mutex.h>
> > #include <linux/slab.h>
> > #include <linux/rculist.h>
> > +#include <linux/llist.h>
>
> nit: Shouldn't we include this in "trace.h" too, because llist_node is used?
You mean to move it to trace.h instead of here?
>
> >
> > #include "trace.h"
> >
> > static LIST_HEAD(trigger_commands);
> > static DEFINE_MUTEX(trigger_cmd_mutex);
> >
> > +static struct task_struct *trigger_kthread;
> > +static struct llist_head trigger_data_free_list;
> > +static DEFINE_MUTEX(trigger_data_kthread_mutex);
> > +
> > +/* Bulk garbage collection of event_trigger_data elements */
> > +static int trigger_kthread_fn(void *ignore)
> > +{
> > + struct event_trigger_data *data, *tmp;
> > + struct llist_node *llnodes;
> > +
> > + /* Once this task starts, it lives forever */
> > + for (;;) {
> > + set_current_state(TASK_INTERRUPTIBLE);
> > + if (llist_empty(&trigger_data_free_list))
> > + schedule();
> > +
> > + __set_current_state(TASK_RUNNING);
> > +
> > + llnodes = llist_del_all(&trigger_data_free_list);
> > +
> > + /* make sure current triggers exit before free */
> > + tracepoint_synchronize_unregister();
> > +
> > + llist_for_each_entry_safe(data, tmp, llnodes, llist)
> > + kfree(data);
> > + }
> > +
> > + return 0;
> > +}
> > +
> > void trigger_data_free(struct event_trigger_data *data)
> > {
> > if (data->cmd_ops->set_filter)
> > data->cmd_ops->set_filter(NULL, data, NULL);
> >
> > - /* make sure current triggers exit before free */
> > - tracepoint_synchronize_unregister();
> > + if (unlikely(!trigger_kthread)) {
> > + guard(mutex)(&trigger_data_kthread_mutex);
> > + /* Check again after taking mutex */
> > + if (!trigger_kthread) {
> > + struct task_struct *kthread;
> > +
> > + kthread = kthread_create(trigger_kthread_fn, NULL,
> > + "trigger_data_free");
> > + if (!IS_ERR(kthread))
> > + WRITE_ONCE(trigger_kthread, kthread);
> > + }
> > + }
> > +
>
> Hmm,
> /* This continues above error case, but we should do it without lock. */
> ?
Does this really need a comment? The lock is only needed to make sure we
only create one kthread. If that fails, then we do it the slow way. The
code below is unrelated to the lock. The lock is for kthread creation, not
the trigger_kthread variable itself.
-- Steve
>
> > + if (!trigger_kthread) {
> > + /* Do it the slow way */
> > + tracepoint_synchronize_unregister();
> > + kfree(data);
> > + return;
> > + }
> >
> > - kfree(data);
> > + llist_add(&data->llist, &trigger_data_free_list);
> > + wake_up_process(trigger_kthread);
> > }
> >
> > static inline void data_ops_trigger(struct event_trigger_data *data,
> > --
> > 2.51.0
> >
> >
>
>
^ permalink raw reply
* Re: [PATCH] tracing: Add boot-time backup of persistent ring buffer
From: Steven Rostedt @ 2025-11-21 18:48 UTC (permalink / raw)
To: Masami Hiramatsu (Google)
Cc: Mathieu Desnoyers, linux-kernel, linux-trace-kernel
In-Reply-To: <176370846529.314463.7508792463190591259.stgit@mhiramat.tok.corp.google.com>
On Fri, 21 Nov 2025 16:01:05 +0900
"Masami Hiramatsu (Google)" <mhiramat@kernel.org> wrote:
> Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
> ---
> kernel/trace/trace.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++---
> kernel/trace/trace.h | 1 +
> 2 files changed, 55 insertions(+), 4 deletions(-)
>
> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
> index 33fcde91924c..616d24580371 100644
> --- a/kernel/trace/trace.c
> +++ b/kernel/trace/trace.c
> @@ -10523,6 +10523,8 @@ static int __remove_instance(struct trace_array *tr)
> reserve_mem_release_by_name(tr->range_name);
> kfree(tr->range_name);
> }
> + if (tr->flags & TRACE_ARRAY_FL_VMALLOC)
> + vfree((void *)tr->range_addr_start);
The ring buffer user space mapping expects the ring buffer to be real
memory. Thus, virtual mapping is not supported. Either we need to allocate
normal memory, or the mmap function of his array must return an error.
>
> for (i = 0; i < tr->nr_topts; i++) {
> kfree(tr->topts[i].topts);
> @@ -11328,6 +11330,41 @@ __init static void do_allocate_snapshot(const char *name)
> static inline void do_allocate_snapshot(const char *name) { }
> #endif
>
> +__init static int backup_instance_area(const char *backup,
> + unsigned long *addr, phys_addr_t *size)
> +{
> + struct trace_array *backup_tr;
> + void *allocated_vaddr = NULL;
> +
> + backup_tr = trace_array_get_by_name(backup, NULL);
> + if (!backup_tr) {
> + pr_warn("Tracing: Instance %s is not found.\n", backup);
> + return -ENOENT;
> + }
Add space.
> + if (!(backup_tr->flags & TRACE_ARRAY_FL_BOOT)) {
> + pr_warn("Tracing: Instance %s is not boot mapped.\n", backup);
> + trace_array_put(backup_tr);
> + return -EINVAL;
> + }
> +
> + *size = backup_tr->range_addr_size;
> +
> + allocated_vaddr = vzalloc(*size);
> + if (!allocated_vaddr) {
> + pr_warn("Tracing: Failed to allocate memory for copying instance %s (size 0x%lx)\n",
> + backup, (unsigned long)*size);
> + trace_array_put(backup_tr);
> + return -ENOMEM;
> + }
> +
> + memcpy(allocated_vaddr,
> + (void *)backup_tr->range_addr_start, (size_t)*size);
> + *addr = (unsigned long)allocated_vaddr;
> +
> + trace_array_put(backup_tr);
> + return 0;
> +}
> +
> __init static void enable_instances(void)
> {
> struct trace_array *tr;
> @@ -11350,11 +11387,15 @@ __init static void enable_instances(void)
> char *flag_delim;
> char *addr_delim;
> char *rname __free(kfree) = NULL;
> + char *backup;
>
> tok = strsep(&curr_str, ",");
>
> - flag_delim = strchr(tok, '^');
> - addr_delim = strchr(tok, '@');
> + name = strsep(&tok, "=");
> + backup = tok;
> +
> + flag_delim = strchr(name, '^');
> + addr_delim = strchr(name, '@');
>
> if (addr_delim)
> *addr_delim++ = '\0';
> @@ -11362,7 +11403,10 @@ __init static void enable_instances(void)
> if (flag_delim)
> *flag_delim++ = '\0';
>
> - name = tok;
> + if (backup) {
> + if (backup_instance_area(backup, &addr, &size) < 0)
> + continue;
> + }
>
> if (flag_delim) {
> char *flag;
> @@ -11458,7 +11502,13 @@ __init static void enable_instances(void)
> tr->ref++;
> }
>
> - if (start) {
> + /*
> + * Backup buffers can be freed but need vfree().
> + */
> + if (backup)
> + tr->flags |= TRACE_ARRAY_FL_VMALLOC;
> +
> + if (start || backup) {
> tr->flags |= TRACE_ARRAY_FL_BOOT | TRACE_ARRAY_FL_LAST_BOOT;
> tr->range_name = no_free_ptr(rname);
> }
This would then need:
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index d1e527cf2aae..104e385e718e 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -8791,8 +8791,8 @@ static int tracing_buffers_mmap(struct file *filp, struct vm_area_struct *vma)
struct trace_iterator *iter = &info->iter;
int ret = 0;
- /* A memmap'ed buffer is not supported for user space mmap */
- if (iter->tr->flags & TRACE_ARRAY_FL_MEMMAP)
+ /* A memmap'ed and backup buffers are not supported for user space mmap */
+ if (iter->tr->flags & (TRACE_ARRAY_FL_MEMMAP | TRACE_ARRAY_FL_VMALLOC))
return -ENODEV;
ret = get_snapshot_map(iter->tr);
As without it, when I tried mmapping the backup buffer I got this;
[ 251.615441] BUG: unable to handle page fault for address: ffffd1c31e0000c8
[ 251.615447] #PF: supervisor read access in kernel mode
[ 251.615449] #PF: error_code(0x0000) - not-present page
[ 251.615451] PGD 0 P4D 0
[ 251.615456] Oops: Oops: 0000 [#1] SMP PTI
[ 251.615463] CPU: 6 UID: 0 PID: 1450 Comm: mmap-rb-lib Not tainted 6.18.0-rc3-ftest-00018-g02548113c2f6 #287 PREEMPT_{RT,LAZY}
[ 251.615469] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
[ 251.615471] RIP: 0010:validate_page_before_insert+0x5/0x90
[ 251.615479] Code: 48 c1 e8 0e 89 c2 83 e2 01 89 d0 c3 cc cc cc cc 0f 1f 44 00 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 0f 1f 44 00 00 <48> 8b 46 08 a8 01 75 5d 66 90 48 89 f0 8b 50 34 85 d2 74 68 48 89
[ 251.615481] RSP: 0018:ffffa52b443d7988 EFLAGS: 00010246
[ 251.615484] RAX: ffff8a84dcac4000 RBX: 00007f07e0c10000 RCX: 0000000108d2f067
[ 251.615486] RDX: 0000000108d2f067 RSI: ffffd1c31e0000c0 RDI: ffff8a84dd865700
[ 251.615487] RBP: 0000000000000000 R08: 000000005ab70715 R09: 0000000000000009
[ 251.615489] R10: 0000000000000009 R11: ffff8a84c9320fb8 R12: ffff8a84dd865700
[ 251.615490] R13: 0000000000000000 R14: ffffd1c31e0000c0 R15: ffff8a84c8d2f080
[ 251.615492] FS: 00007f07e0e8e740(0000) GS:ffff8a86afbb7000(0000) knlGS:0000000000000000
[ 251.615494] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 251.615496] CR2: ffffd1c31e0000c8 CR3: 000000011c390006 CR4: 0000000000170ef0
[ 251.615501] Call Trace:
[ 251.615502] <TASK>
[ 251.615504] vm_insert_pages+0x157/0x360
[ 251.615513] __rb_map_vma+0x1ef/0x390
[ 251.615521] ring_buffer_map+0x261/0x370
[ 251.615527] tracing_buffers_mmap+0x7e/0x100
[ 251.615532] __mmap_region+0x831/0xe00
[ 251.615554] do_mmap+0x4bf/0x6b0
[ 251.615560] vm_mmap_pgoff+0x126/0x230
[ 251.615569] ksys_mmap_pgoff+0x162/0x220
[ 251.615573] do_syscall_64+0x76/0x9a0
[ 251.615581] entry_SYSCALL_64_after_hwframe+0x76/0x7e
[ 251.615584] RIP: 0033:0x7f07e0f9dde2
[ 251.615589] Code: 00 00 00 0f 1f 44 00 00
-- Steve
> diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
> index 58be6d741d72..9e5186c96e9c 100644
> --- a/kernel/trace/trace.h
> +++ b/kernel/trace/trace.h
> @@ -453,6 +453,7 @@ enum {
> TRACE_ARRAY_FL_LAST_BOOT = BIT(2),
> TRACE_ARRAY_FL_MOD_INIT = BIT(3),
> TRACE_ARRAY_FL_MEMMAP = BIT(4),
> + TRACE_ARRAY_FL_VMALLOC = BIT(5),
> };
>
> #ifdef CONFIG_MODULES
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox