* [PATCH v9 5/6] x86/vdso: Use CFI macros in __vdso_sgx_enter_enclave()
From: Jens Remus @ 2026-02-11 14:13 UTC (permalink / raw)
To: linux-kernel, linux-trace-kernel, bpf, x86, linux-mm,
Steven Rostedt
Cc: Jens Remus, Josh Poimboeuf, Masami Hiramatsu, Mathieu Desnoyers,
Peter Zijlstra, Ingo Molnar, Jiri Olsa, Arnaldo Carvalho de Melo,
Namhyung Kim, Thomas Gleixner, Andrii Nakryiko, Indu Bhagat,
Jose E. Marchesi, Beau Belgrave, Linus Torvalds, Andrew Morton,
Florian Weimer, Kees Cook, Carlos O'Donell, Sam James,
Dylan Hatch, Borislav Petkov, Dave Hansen, David Hildenbrand,
H. Peter Anvin, Liam R. Howlett, Lorenzo Stoakes, Michal Hocko,
Mike Rapoport, Suren Baghdasaryan, Vlastimil Babka,
Heiko Carstens, Vasily Gorbik, Steven Rostedt (Google)
In-Reply-To: <20260211141357.271402-1-jremus@linux.ibm.com>
From: Josh Poimboeuf <jpoimboe@kernel.org>
Use the CFI macros instead of the raw .cfi_* directives to be consistent
with the rest of the VDSO asm. It's also easier on the eyes.
No functional changes.
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Acked-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
---
arch/x86/entry/vdso/vdso64/vsgx.S | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/arch/x86/entry/vdso/vdso64/vsgx.S b/arch/x86/entry/vdso/vdso64/vsgx.S
index c0342238c976..76efbeb1e287 100644
--- a/arch/x86/entry/vdso/vdso64/vsgx.S
+++ b/arch/x86/entry/vdso/vdso64/vsgx.S
@@ -25,12 +25,12 @@
SYM_FUNC_START(__vdso_sgx_enter_enclave)
push %rbp
- .cfi_adjust_cfa_offset 8
- .cfi_rel_offset %rbp, 0
+ CFI_ADJUST_CFA_OFFSET 8
+ CFI_REL_OFFSET %rbp, 0
mov %rsp, %rbp
- .cfi_def_cfa_register %rbp
+ CFI_DEF_CFA_REGISTER %rbp
push %rbx
- .cfi_rel_offset %rbx, -8
+ CFI_REL_OFFSET %rbx, -8
mov %ecx, %eax
.Lenter_enclave:
@@ -77,13 +77,11 @@ SYM_FUNC_START(__vdso_sgx_enter_enclave)
.Lout:
pop %rbx
leave
- .cfi_def_cfa %rsp, 8
+ CFI_DEF_CFA %rsp, 8
RET
- /* The out-of-line code runs with the pre-leave stack frame. */
- .cfi_def_cfa %rbp, 16
-
.Linvalid_input:
+ CFI_DEF_CFA %rbp, 16
mov $(-EINVAL), %eax
jmp .Lout
--
2.51.0
^ permalink raw reply related
* Re: [PATCH v2 1/4] tools/rtla: Consolidate nr_cpus usage across all tools
From: Tomas Glozar @ 2026-02-11 11:15 UTC (permalink / raw)
To: Wander Lairson Costa
Cc: Costa Shulyupin, Steven Rostedt, Crystal Wood, Ivan Pravdin,
John Kacur, Tiezhu Yang, linux-trace-kernel, linux-kernel, bpf
In-Reply-To: <aYxhtrJ8cw7SNOJy@fedora>
st 11. 2. 2026 v 12:03 odesílatel Wander Lairson Costa
<wander@redhat.com> napsal:
> > `#pragma once` in timerlat_u.h is needed for pre-C23 compilers to avoid
> > redefinition errors.
>
> Isn't it necessary for C23 compilers?
>
C23 allowed struct redefinition [1] to enable template-like macros. As
a side effect, including timerlat_u.h twice does not break anything,
in C23 only. But the Linux kernel supports building with lower
standards of C, so it has to work there, too.
Tomas
[1] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3003.pdf
^ permalink raw reply
* Re: [PATCH v2 2/4] tools/rtla: Remove unneeded nr_cpus arguments
From: Wander Lairson Costa @ 2026-02-11 11:03 UTC (permalink / raw)
To: Costa Shulyupin
Cc: Steven Rostedt, Tomas Glozar, Crystal Wood, Ivan Pravdin,
John Kacur, Tiezhu Yang, linux-trace-kernel, linux-kernel, bpf
In-Reply-To: <20260209092436.2899888-3-costa.shul@redhat.com>
On Mon, Feb 09, 2026 at 11:24:34AM +0200, Costa Shulyupin wrote:
> nr_cpus does not change at runtime, so passing it through function
> arguments is unnecessary.
>
> Use the global nr_cpus instead of propagating it via parameters.
The parameter should also be removed from timerlat_bpf_get_hist_value(),
shouldn't it?
>
> Signed-off-by: Costa Shulyupin <costa.shul@redhat.com>
> ---
> tools/tracing/rtla/src/osnoise_hist.c | 4 ++--
> tools/tracing/rtla/src/osnoise_top.c | 4 ++--
> tools/tracing/rtla/src/timerlat_bpf.c | 5 ++---
> tools/tracing/rtla/src/timerlat_bpf.h | 6 ++----
> tools/tracing/rtla/src/timerlat_hist.c | 19 +++++++------------
> tools/tracing/rtla/src/timerlat_top.c | 19 +++++++------------
> tools/tracing/rtla/src/timerlat_u.c | 6 +++---
> 7 files changed, 25 insertions(+), 38 deletions(-)
>
> diff --git a/tools/tracing/rtla/src/osnoise_hist.c b/tools/tracing/rtla/src/osnoise_hist.c
> index 03ebff34fff4..d83ee047a5f5 100644
> --- a/tools/tracing/rtla/src/osnoise_hist.c
> +++ b/tools/tracing/rtla/src/osnoise_hist.c
> @@ -62,7 +62,7 @@ static void osnoise_free_hist_tool(struct osnoise_tool *tool)
> * osnoise_alloc_histogram - alloc runtime data
> */
> static struct osnoise_hist_data
> -*osnoise_alloc_histogram(int nr_cpus, int entries, int bucket_size)
> +*osnoise_alloc_histogram(int entries, int bucket_size)
> {
> struct osnoise_hist_data *data;
> int cpu;
> @@ -652,7 +652,7 @@ static struct osnoise_tool
> if (!tool)
> return NULL;
>
> - tool->data = osnoise_alloc_histogram(nr_cpus, params->hist.entries,
> + tool->data = osnoise_alloc_histogram(params->hist.entries,
> params->hist.bucket_size);
> if (!tool->data)
> goto out_err;
> diff --git a/tools/tracing/rtla/src/osnoise_top.c b/tools/tracing/rtla/src/osnoise_top.c
> index 7dcd2e318205..73b3ac0dd43b 100644
> --- a/tools/tracing/rtla/src/osnoise_top.c
> +++ b/tools/tracing/rtla/src/osnoise_top.c
> @@ -51,7 +51,7 @@ static void osnoise_free_top_tool(struct osnoise_tool *tool)
> /*
> * osnoise_alloc_histogram - alloc runtime data
> */
> -static struct osnoise_top_data *osnoise_alloc_top(int nr_cpus)
> +static struct osnoise_top_data *osnoise_alloc_top(void)
> {
> struct osnoise_top_data *data;
>
> @@ -496,7 +496,7 @@ struct osnoise_tool *osnoise_init_top(struct common_params *params)
> if (!tool)
> return NULL;
>
> - tool->data = osnoise_alloc_top(nr_cpus);
> + tool->data = osnoise_alloc_top();
> if (!tool->data) {
> osnoise_destroy_tool(tool);
> return NULL;
> diff --git a/tools/tracing/rtla/src/timerlat_bpf.c b/tools/tracing/rtla/src/timerlat_bpf.c
> index 05adf18303df..8d5c3a095e41 100644
> --- a/tools/tracing/rtla/src/timerlat_bpf.c
> +++ b/tools/tracing/rtla/src/timerlat_bpf.c
> @@ -191,13 +191,12 @@ int timerlat_bpf_get_hist_value(int key,
> int timerlat_bpf_get_summary_value(enum summary_field key,
> long long *value_irq,
> long long *value_thread,
> - long long *value_user,
> - int cpus)
> + long long *value_user)
> {
> return get_value(bpf->maps.summary_irq,
> bpf->maps.summary_thread,
> bpf->maps.summary_user,
> - key, value_irq, value_thread, value_user, cpus);
> + key, value_irq, value_thread, value_user, nr_cpus);
> }
>
> /*
> diff --git a/tools/tracing/rtla/src/timerlat_bpf.h b/tools/tracing/rtla/src/timerlat_bpf.h
> index 169abeaf4363..f4a5476f2abb 100644
> --- a/tools/tracing/rtla/src/timerlat_bpf.h
> +++ b/tools/tracing/rtla/src/timerlat_bpf.h
> @@ -28,8 +28,7 @@ int timerlat_bpf_get_hist_value(int key,
> int timerlat_bpf_get_summary_value(enum summary_field key,
> long long *value_irq,
> long long *value_thread,
> - long long *value_user,
> - int cpus);
> + long long *value_user);
> int timerlat_load_bpf_action_program(const char *program_path);
> static inline int have_libbpf_support(void) { return 1; }
> #else
> @@ -53,8 +52,7 @@ static inline int timerlat_bpf_get_hist_value(int key,
> static inline int timerlat_bpf_get_summary_value(enum summary_field key,
> long long *value_irq,
> long long *value_thread,
> - long long *value_user,
> - int cpus)
> + long long *value_user)
> {
> return -1;
> }
> diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c
> index 841118ed84f2..dee5fbf622c3 100644
> --- a/tools/tracing/rtla/src/timerlat_hist.c
> +++ b/tools/tracing/rtla/src/timerlat_hist.c
> @@ -83,7 +83,7 @@ static void timerlat_free_histogram_tool(struct osnoise_tool *tool)
> * timerlat_alloc_histogram - alloc runtime data
> */
> static struct timerlat_hist_data
> -*timerlat_alloc_histogram(int nr_cpus, int entries, int bucket_size)
> +*timerlat_alloc_histogram(int entries, int bucket_size)
> {
> struct timerlat_hist_data *data;
> int cpu;
> @@ -223,8 +223,7 @@ static int timerlat_hist_bpf_pull_data(struct osnoise_tool *tool)
>
> /* Pull summary */
> err = timerlat_bpf_get_summary_value(SUMMARY_COUNT,
> - value_irq, value_thread, value_user,
> - data->nr_cpus);
> + value_irq, value_thread, value_user);
> if (err)
> return err;
> for (i = 0; i < data->nr_cpus; i++) {
> @@ -234,8 +233,7 @@ static int timerlat_hist_bpf_pull_data(struct osnoise_tool *tool)
> }
>
> err = timerlat_bpf_get_summary_value(SUMMARY_MIN,
> - value_irq, value_thread, value_user,
> - data->nr_cpus);
> + value_irq, value_thread, value_user);
> if (err)
> return err;
> for (i = 0; i < data->nr_cpus; i++) {
> @@ -245,8 +243,7 @@ static int timerlat_hist_bpf_pull_data(struct osnoise_tool *tool)
> }
>
> err = timerlat_bpf_get_summary_value(SUMMARY_MAX,
> - value_irq, value_thread, value_user,
> - data->nr_cpus);
> + value_irq, value_thread, value_user);
> if (err)
> return err;
> for (i = 0; i < data->nr_cpus; i++) {
> @@ -256,8 +253,7 @@ static int timerlat_hist_bpf_pull_data(struct osnoise_tool *tool)
> }
>
> err = timerlat_bpf_get_summary_value(SUMMARY_SUM,
> - value_irq, value_thread, value_user,
> - data->nr_cpus);
> + value_irq, value_thread, value_user);
> if (err)
> return err;
> for (i = 0; i < data->nr_cpus; i++) {
> @@ -267,8 +263,7 @@ static int timerlat_hist_bpf_pull_data(struct osnoise_tool *tool)
> }
>
> err = timerlat_bpf_get_summary_value(SUMMARY_OVERFLOW,
> - value_irq, value_thread, value_user,
> - data->nr_cpus);
> + value_irq, value_thread, value_user);
> if (err)
> return err;
> for (i = 0; i < data->nr_cpus; i++) {
> @@ -1036,7 +1031,7 @@ static struct osnoise_tool
> if (!tool)
> return NULL;
>
> - tool->data = timerlat_alloc_histogram(nr_cpus, params->hist.entries,
> + tool->data = timerlat_alloc_histogram(params->hist.entries,
> params->hist.bucket_size);
> if (!tool->data)
> goto out_err;
> diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c
> index 3e395ce4fa9f..25b4d81b4fe0 100644
> --- a/tools/tracing/rtla/src/timerlat_top.c
> +++ b/tools/tracing/rtla/src/timerlat_top.c
> @@ -62,7 +62,7 @@ static void timerlat_free_top_tool(struct osnoise_tool *tool)
> /*
> * timerlat_alloc_histogram - alloc runtime data
> */
> -static struct timerlat_top_data *timerlat_alloc_top(int nr_cpus)
> +static struct timerlat_top_data *timerlat_alloc_top(void)
> {
> struct timerlat_top_data *data;
> int cpu;
> @@ -196,8 +196,7 @@ static int timerlat_top_bpf_pull_data(struct osnoise_tool *tool)
>
> /* Pull summary */
> err = timerlat_bpf_get_summary_value(SUMMARY_CURRENT,
> - value_irq, value_thread, value_user,
> - data->nr_cpus);
> + value_irq, value_thread, value_user);
> if (err)
> return err;
> for (i = 0; i < data->nr_cpus; i++) {
> @@ -207,8 +206,7 @@ static int timerlat_top_bpf_pull_data(struct osnoise_tool *tool)
> }
>
> err = timerlat_bpf_get_summary_value(SUMMARY_COUNT,
> - value_irq, value_thread, value_user,
> - data->nr_cpus);
> + value_irq, value_thread, value_user);
> if (err)
> return err;
> for (i = 0; i < data->nr_cpus; i++) {
> @@ -218,8 +216,7 @@ static int timerlat_top_bpf_pull_data(struct osnoise_tool *tool)
> }
>
> err = timerlat_bpf_get_summary_value(SUMMARY_MIN,
> - value_irq, value_thread, value_user,
> - data->nr_cpus);
> + value_irq, value_thread, value_user);
> if (err)
> return err;
> for (i = 0; i < data->nr_cpus; i++) {
> @@ -229,8 +226,7 @@ static int timerlat_top_bpf_pull_data(struct osnoise_tool *tool)
> }
>
> err = timerlat_bpf_get_summary_value(SUMMARY_MAX,
> - value_irq, value_thread, value_user,
> - data->nr_cpus);
> + value_irq, value_thread, value_user);
> if (err)
> return err;
> for (i = 0; i < data->nr_cpus; i++) {
> @@ -240,8 +236,7 @@ static int timerlat_top_bpf_pull_data(struct osnoise_tool *tool)
> }
>
> err = timerlat_bpf_get_summary_value(SUMMARY_SUM,
> - value_irq, value_thread, value_user,
> - data->nr_cpus);
> + value_irq, value_thread, value_user);
> if (err)
> return err;
> for (i = 0; i < data->nr_cpus; i++) {
> @@ -782,7 +777,7 @@ static struct osnoise_tool
> if (!top)
> return NULL;
>
> - top->data = timerlat_alloc_top(nr_cpus);
> + top->data = timerlat_alloc_top();
> if (!top->data)
> goto out_err;
>
> diff --git a/tools/tracing/rtla/src/timerlat_u.c b/tools/tracing/rtla/src/timerlat_u.c
> index a569fe7f93aa..03b4e68e8b1e 100644
> --- a/tools/tracing/rtla/src/timerlat_u.c
> +++ b/tools/tracing/rtla/src/timerlat_u.c
> @@ -99,7 +99,7 @@ static int timerlat_u_main(int cpu, struct timerlat_u_params *params)
> *
> * Return the number of processes that received the kill.
> */
> -static int timerlat_u_send_kill(pid_t *procs, int nr_cpus)
> +static int timerlat_u_send_kill(pid_t *procs)
> {
> int killed = 0;
> int i, retval;
> @@ -169,7 +169,7 @@ void *timerlat_u_dispatcher(void *data)
>
> /* parent */
> if (pid == -1) {
> - timerlat_u_send_kill(procs, nr_cpus);
> + timerlat_u_send_kill(procs);
> debug_msg("Failed to create child processes");
> pthread_exit(&retval);
> }
> @@ -196,7 +196,7 @@ void *timerlat_u_dispatcher(void *data)
> sleep(1);
> }
>
> - timerlat_u_send_kill(procs, nr_cpus);
> + timerlat_u_send_kill(procs);
>
> while (procs_count) {
> pid = waitpid(-1, &wstatus, 0);
> --
> 2.52.0
>
^ permalink raw reply
* Re: [PATCH v2 1/4] tools/rtla: Consolidate nr_cpus usage across all tools
From: Wander Lairson Costa @ 2026-02-11 11:03 UTC (permalink / raw)
To: Costa Shulyupin
Cc: Steven Rostedt, Tomas Glozar, Crystal Wood, Ivan Pravdin,
John Kacur, Tiezhu Yang, linux-trace-kernel, linux-kernel, bpf
In-Reply-To: <20260209092436.2899888-2-costa.shul@redhat.com>
On Mon, Feb 09, 2026 at 11:24:33AM +0200, Costa Shulyupin wrote:
> sysconf(_SC_NPROCESSORS_CONF) (via get_nprocs_conf) reflects
> cpu_possible_mask, which is fixed at boot time, so querying it
> repeatedly is unnecessary.
>
> Replace multiple calls to sysconf(_SC_NPROCESSORS_CONF) with a single
> global nr_cpus variable initialized once at startup.
>
> `#pragma once` in timerlat_u.h is needed for pre-C23 compilers to avoid
> redefinition errors.
Isn't it necessary for C23 compilers?
>
> Signed-off-by: Costa Shulyupin <costa.shul@redhat.com>
> ---
> tools/tracing/rtla/src/common.c | 7 +++++--
> tools/tracing/rtla/src/common.h | 2 ++
> tools/tracing/rtla/src/osnoise_hist.c | 3 ---
> tools/tracing/rtla/src/osnoise_top.c | 7 -------
> tools/tracing/rtla/src/timerlat.c | 5 +----
> tools/tracing/rtla/src/timerlat_aa.c | 1 -
> tools/tracing/rtla/src/timerlat_hist.c | 3 ---
> tools/tracing/rtla/src/timerlat_top.c | 7 -------
> tools/tracing/rtla/src/timerlat_u.c | 3 +--
> tools/tracing/rtla/src/timerlat_u.h | 1 +
> tools/tracing/rtla/src/utils.c | 10 +---------
> 11 files changed, 11 insertions(+), 38 deletions(-)
>
> diff --git a/tools/tracing/rtla/src/common.c b/tools/tracing/rtla/src/common.c
> index ceff76a62a30..e4cf30a65e82 100644
> --- a/tools/tracing/rtla/src/common.c
> +++ b/tools/tracing/rtla/src/common.c
> @@ -5,12 +5,14 @@
> #include <signal.h>
> #include <stdlib.h>
> #include <string.h>
> -#include <unistd.h>
> #include <getopt.h>
> +#include <sys/sysinfo.h>
> +
> #include "common.h"
>
> struct trace_instance *trace_inst;
> volatile int stop_tracing;
> +int nr_cpus;
>
> static void stop_trace(int sig)
> {
> @@ -135,7 +137,7 @@ common_apply_config(struct osnoise_tool *tool, struct common_params *params)
> }
>
> if (!params->cpus) {
> - for (i = 0; i < sysconf(_SC_NPROCESSORS_CONF); i++)
> + for (i = 0; i < nr_cpus; i++)
> CPU_SET(i, ¶ms->monitored_cpus);
> }
>
> @@ -183,6 +185,7 @@ int run_tool(struct tool_ops *ops, int argc, char *argv[])
> bool stopped;
> int retval;
>
> + nr_cpus = get_nprocs_conf();
> params = ops->parse_args(argc, argv);
> if (!params)
> exit(1);
> diff --git a/tools/tracing/rtla/src/common.h b/tools/tracing/rtla/src/common.h
> index 7602c5593ef5..32f9c1351209 100644
> --- a/tools/tracing/rtla/src/common.h
> +++ b/tools/tracing/rtla/src/common.h
> @@ -107,6 +107,8 @@ struct common_params {
> struct timerlat_u_params user;
> };
>
> +extern int nr_cpus;
> +
> #define for_each_monitored_cpu(cpu, nr_cpus, common) \
> for (cpu = 0; cpu < nr_cpus; cpu++) \
> if (!(common)->cpus || CPU_ISSET(cpu, &(common)->monitored_cpus))
> diff --git a/tools/tracing/rtla/src/osnoise_hist.c b/tools/tracing/rtla/src/osnoise_hist.c
> index 9d70ea34807f..03ebff34fff4 100644
> --- a/tools/tracing/rtla/src/osnoise_hist.c
> +++ b/tools/tracing/rtla/src/osnoise_hist.c
> @@ -647,9 +647,6 @@ static struct osnoise_tool
> *osnoise_init_hist(struct common_params *params)
> {
> struct osnoise_tool *tool;
> - int nr_cpus;
> -
> - nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
>
> tool = osnoise_init_tool("osnoise_hist");
> if (!tool)
> diff --git a/tools/tracing/rtla/src/osnoise_top.c b/tools/tracing/rtla/src/osnoise_top.c
> index d54d47947fb4..7dcd2e318205 100644
> --- a/tools/tracing/rtla/src/osnoise_top.c
> +++ b/tools/tracing/rtla/src/osnoise_top.c
> @@ -232,12 +232,8 @@ osnoise_print_stats(struct osnoise_tool *top)
> {
> struct osnoise_params *params = to_osnoise_params(top->params);
> struct trace_instance *trace = &top->trace;
> - static int nr_cpus = -1;
> int i;
>
> - if (nr_cpus == -1)
> - nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
> -
> if (!params->common.quiet)
> clear_terminal(trace->seq);
>
> @@ -495,9 +491,6 @@ osnoise_top_apply_config(struct osnoise_tool *tool)
> struct osnoise_tool *osnoise_init_top(struct common_params *params)
> {
> struct osnoise_tool *tool;
> - int nr_cpus;
> -
> - nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
>
> tool = osnoise_init_tool("osnoise_top");
> if (!tool)
> diff --git a/tools/tracing/rtla/src/timerlat.c b/tools/tracing/rtla/src/timerlat.c
> index 8f8811f7a13b..69856f677fce 100644
> --- a/tools/tracing/rtla/src/timerlat.c
> +++ b/tools/tracing/rtla/src/timerlat.c
> @@ -99,7 +99,7 @@ timerlat_apply_config(struct osnoise_tool *tool, struct timerlat_params *params)
> int timerlat_enable(struct osnoise_tool *tool)
> {
> struct timerlat_params *params = to_timerlat_params(tool->params);
> - int retval, nr_cpus, i;
> + int retval, i;
>
> if (params->dma_latency >= 0) {
> dma_latency_fd = set_cpu_dma_latency(params->dma_latency);
> @@ -115,8 +115,6 @@ int timerlat_enable(struct osnoise_tool *tool)
> return -1;
> }
>
> - nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
> -
> for_each_monitored_cpu(i, nr_cpus, ¶ms->common) {
> if (save_cpu_idle_disable_state(i) < 0) {
> err_msg("Could not save cpu idle state.\n");
> @@ -214,7 +212,6 @@ void timerlat_analyze(struct osnoise_tool *tool, bool stopped)
> void timerlat_free(struct osnoise_tool *tool)
> {
> struct timerlat_params *params = to_timerlat_params(tool->params);
> - int nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
> int i;
>
> timerlat_aa_destroy();
> diff --git a/tools/tracing/rtla/src/timerlat_aa.c b/tools/tracing/rtla/src/timerlat_aa.c
> index 31e66ea2b144..5766d58709eb 100644
> --- a/tools/tracing/rtla/src/timerlat_aa.c
> +++ b/tools/tracing/rtla/src/timerlat_aa.c
> @@ -1022,7 +1022,6 @@ void timerlat_aa_destroy(void)
> */
> int timerlat_aa_init(struct osnoise_tool *tool, int dump_tasks)
> {
> - int nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
> struct timerlat_aa_context *taa_ctx;
> int retval;
>
> diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c
> index 4e8c38a61197..841118ed84f2 100644
> --- a/tools/tracing/rtla/src/timerlat_hist.c
> +++ b/tools/tracing/rtla/src/timerlat_hist.c
> @@ -1031,9 +1031,6 @@ static struct osnoise_tool
> *timerlat_init_hist(struct common_params *params)
> {
> struct osnoise_tool *tool;
> - int nr_cpus;
> -
> - nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
>
> tool = osnoise_init_tool("timerlat_hist");
> if (!tool)
> diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c
> index 284b74773c2b..3e395ce4fa9f 100644
> --- a/tools/tracing/rtla/src/timerlat_top.c
> +++ b/tools/tracing/rtla/src/timerlat_top.c
> @@ -442,15 +442,11 @@ timerlat_print_stats(struct osnoise_tool *top)
> struct timerlat_params *params = to_timerlat_params(top->params);
> struct trace_instance *trace = &top->trace;
> struct timerlat_top_cpu summary;
> - static int nr_cpus = -1;
> int i;
>
> if (params->common.aa_only)
> return;
>
> - if (nr_cpus == -1)
> - nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
> -
> if (!params->common.quiet)
> clear_terminal(trace->seq);
>
> @@ -781,9 +777,6 @@ static struct osnoise_tool
> *timerlat_init_top(struct common_params *params)
> {
> struct osnoise_tool *top;
> - int nr_cpus;
> -
> - nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
>
> top = osnoise_init_tool("timerlat_top");
> if (!top)
> diff --git a/tools/tracing/rtla/src/timerlat_u.c b/tools/tracing/rtla/src/timerlat_u.c
> index ce68e39d25fd..a569fe7f93aa 100644
> --- a/tools/tracing/rtla/src/timerlat_u.c
> +++ b/tools/tracing/rtla/src/timerlat_u.c
> @@ -16,7 +16,7 @@
> #include <sys/wait.h>
> #include <sys/prctl.h>
>
> -#include "utils.h"
> +#include "common.h"
> #include "timerlat_u.h"
>
> /*
> @@ -131,7 +131,6 @@ static int timerlat_u_send_kill(pid_t *procs, int nr_cpus)
> */
> void *timerlat_u_dispatcher(void *data)
> {
> - int nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
> struct timerlat_u_params *params = data;
> char proc_name[128];
> int procs_count = 0;
> diff --git a/tools/tracing/rtla/src/timerlat_u.h b/tools/tracing/rtla/src/timerlat_u.h
> index 661511908957..a692331bd1c7 100644
> --- a/tools/tracing/rtla/src/timerlat_u.h
> +++ b/tools/tracing/rtla/src/timerlat_u.h
> @@ -1,4 +1,5 @@
> // SPDX-License-Identifier: GPL-2.0
> +#pragma once
> /*
> * Copyright (C) 2023 Red Hat Inc, Daniel Bristot de Oliveira <bristot@kernel.org>
> */
> diff --git a/tools/tracing/rtla/src/utils.c b/tools/tracing/rtla/src/utils.c
> index 0da3b2470c31..8cd1b374b035 100644
> --- a/tools/tracing/rtla/src/utils.c
> +++ b/tools/tracing/rtla/src/utils.c
> @@ -19,7 +19,7 @@
> #include <stdio.h>
> #include <limits.h>
>
> -#include "utils.h"
> +#include "common.h"
>
> #define MAX_MSG_LENGTH 1024
> int config_debug;
> @@ -119,14 +119,11 @@ int parse_cpu_set(char *cpu_list, cpu_set_t *set)
> {
> const char *p;
> int end_cpu;
> - int nr_cpus;
> int cpu;
> int i;
>
> CPU_ZERO(set);
>
> - nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
> -
> for (p = cpu_list; *p; ) {
> cpu = atoi(p);
> if (cpu < 0 || (!cpu && *p != '0') || cpu >= nr_cpus)
> @@ -559,7 +556,6 @@ int save_cpu_idle_disable_state(unsigned int cpu)
> unsigned int nr_states;
> unsigned int state;
> int disabled;
> - int nr_cpus;
>
> nr_states = cpuidle_state_count(cpu);
>
> @@ -567,7 +563,6 @@ int save_cpu_idle_disable_state(unsigned int cpu)
> return 0;
>
> if (saved_cpu_idle_disable_state == NULL) {
> - nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
> saved_cpu_idle_disable_state = calloc(nr_cpus, sizeof(unsigned int *));
> if (!saved_cpu_idle_disable_state)
> return -1;
> @@ -644,13 +639,10 @@ int restore_cpu_idle_disable_state(unsigned int cpu)
> void free_cpu_idle_disable_states(void)
> {
> int cpu;
> - int nr_cpus;
>
> if (!saved_cpu_idle_disable_state)
> return;
>
> - nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
> -
> for (cpu = 0; cpu < nr_cpus; cpu++) {
> free(saved_cpu_idle_disable_state[cpu]);
> saved_cpu_idle_disable_state[cpu] = NULL;
> --
> 2.52.0
>
^ permalink raw reply
* Re: [PATCH 1/2] selftests/tracing: Fix to make --logdir option work again
From: Gabriele Monaco @ 2026-02-11 8:16 UTC (permalink / raw)
To: Masami Hiramatsu (Google), Steven Rostedt, Shuah Khan
Cc: Mathieu Desnoyers, linux-kernel, linux-trace-kernel,
linux-kselftest
In-Reply-To: <177071725191.2369897.14781037901532893911.stgit@mhiramat.tok.corp.google.com>
On Tue, 2026-02-10 at 18:54 +0900, Masami Hiramatsu (Google) wrote:
> From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
>
> Since commit a0aa283c53a7 ("selftest/ftrace: Generalise ftracetest to
> use with RV") moved the default LOG_DIR setting after --logdir option
> parser, it overwrites the user given LOG_DIR.
> This fixes it to check the --logdir option parameter when setting new
> default LOG_DIR with a new TOP_DIR.
>
> Fixes: a0aa283c53a7 ("selftest/ftrace: Generalise ftracetest to use with RV")
> Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
> ---
Thanks for catching this! I should have tested all the options..
The fix works fine on my side.
Tested-by: Gabriele Monaco <gmonaco@redhat.com>
> tools/testing/selftests/ftrace/ftracetest | 18 ++++++++++++------
> 1 file changed, 12 insertions(+), 6 deletions(-)
>
> diff --git a/tools/testing/selftests/ftrace/ftracetest
> b/tools/testing/selftests/ftrace/ftracetest
> index 3230bd54dba8..0a56bf209f6c 100755
> --- a/tools/testing/selftests/ftrace/ftracetest
> +++ b/tools/testing/selftests/ftrace/ftracetest
> @@ -130,8 +130,7 @@ parse_opts() { # opts
> shift 1
> ;;
> --logdir|-l)
> - LOG_DIR=$2
> - LINK_PTR=
> + USER_LOG_DIR=$2
> shift 2
> ;;
> --rv)
> @@ -199,6 +198,7 @@ fi
> TOP_DIR=`absdir $0`
> TEST_DIR=$TOP_DIR/test.d
> TEST_CASES=`find_testcases $TEST_DIR`
> +USER_LOG_DIR=
> KEEP_LOG=0
> KTAP=0
> DEBUG=0
> @@ -210,12 +210,18 @@ RV_TEST=0
> # Parse command-line options
> parse_opts $*
>
> +[ $DEBUG -ne 0 ] && set -x
> +
> +# TOP_DIR can be changed for rv. Setting log directory.
> LOG_TOP_DIR=$TOP_DIR/logs
> LOG_DATE=`date +%Y%m%d-%H%M%S`
> -LOG_DIR=$LOG_TOP_DIR/$LOG_DATE/
> -LINK_PTR=$LOG_TOP_DIR/latest
> -
> -[ $DEBUG -ne 0 ] && set -x
> +if [ -n "$USER_LOG_DIR" ]; then
> + LOG_DIR=$USER_LOG_DIR
> + LINK_PTR=
> +else
> + LOG_DIR=$LOG_TOP_DIR/$LOG_DATE/
> + LINK_PTR=$LOG_TOP_DIR/latest
> +fi
>
> if [ $RV_TEST -ne 0 ]; then
> TRACING_DIR=$TRACING_DIR/rv
^ permalink raw reply
* Re: [RFC bpf-next 06/12] bpf: Add bpf_trampoline_multi_attach/detach functions
From: Menglong Dong @ 2026-02-11 8:04 UTC (permalink / raw)
To: Jiri Olsa
Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, bpf,
linux-trace-kernel, Martin KaFai Lau, Eduard Zingerman, Song Liu,
Yonghong Song, Menglong Dong, Steven Rostedt, Mark Rutland
In-Reply-To: <aYSfEy8Zf8bCs4-j@krava>
On 2026/2/5 21:45, Jiri Olsa wrote:
> On Thu, Feb 05, 2026 at 05:16:49PM +0800, Menglong Dong wrote:
> > On 2026/2/3 17:38 Jiri Olsa <jolsa@kernel.org> write:
> > > Adding bpf_trampoline_multi_attach/detach functions that allows
> > > to attach/detach multi tracing trampoline.
> > >
> > > The attachment is defined with bpf_program and array of BTF ids
> > > of functions to attach the bpf program to.
> > >
> > [...]
> > > @@ -367,7 +367,11 @@ static struct bpf_trampoline *bpf_trampoline_lookup(u64 key, unsigned long ip)
> > > head = &trampoline_ip_table[hash_64(tr->ip, TRAMPOLINE_HASH_BITS)];
> > > hlist_add_head(&tr->hlist_ip, head);
> > > refcount_set(&tr->refcnt, 1);
> > > +#ifdef CONFIG_LOCKDEP
> > > + mutex_init_with_key(&tr->mutex, &__lockdep_no_track__);
> > > +#else
> > > mutex_init(&tr->mutex);
> > > +#endif
> > > for (i = 0; i < BPF_TRAMP_MAX; i++)
> > > INIT_HLIST_HEAD(&tr->progs_hlist[i]);
> > > out:
> > > @@ -1400,6 +1404,188 @@ int __weak arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
> > > return -ENOTSUPP;
> > > }
> > >
> > > +#if defined(CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS) && defined(CONFIG_HAVE_SINGLE_FTRACE_DIRECT_OPS)
> >
> > Hi, Jiri. It's great to see your tracing_multi link finally. It looks great ;)
>
> heya, thanks ;-)
>
> >
> > After analyzing a little deeper on the SINGLE_FTRACE_DIRECT_OPS, I
> > understand why it is only supported on x86_64 for now. It seems that
> > it's a little hard to implement it in the other arch, as we need to
> > restructure the implement of ftrace direct call.
> >
> > So do we need some more ftrace API here to make the tracing multi-link
> > independent from SINGLE_FTRACE_DIRECT_OPS? Otherwise, we can only
> > use it on x86_64.
>
> I tried to describe it in commit [2] changelog:
>
> At the moment we can enable this only on x86 arch, because arm relies
> on ftrace_ops object representing just single trampoline image (stored
> in ftrace_ops::direct_call). Archs that do not support this will continue
> to use *_ftrace_direct api.
Ah, I didn't notice this part before. Thanks for the explain ;)
>
> >
> > Have you ever tried to implement the SINGLE_FTRACE_DIRECT_OPS on arm64?
> > The direct call on arm64 is so complex, and I didn't work it out :/
>
> yes, it seems to be difficult atm, Mark commented on that in [1],
> I don't know arm that good to be of much help in here, cc-ing Mark
>
> jirka
>
>
> [1] https://lore.kernel.org/bpf/aIyNOd18TRLu8EpY@J2N7QTR9R3/
> [2] 424f6a361096 ("bpf,x86: Use single ftrace_ops for direct calls")
>
> >
> > Thanks!
> > Menglong Dong
> >
> > > +
> > > +struct fentry_multi_data {
> > > + struct ftrace_hash *unreg;
> > > + struct ftrace_hash *modify;
> > > + struct ftrace_hash *reg;
> > > +};
> > > +
> > [...]
> > >
> > >
> > >
> >
> >
> >
> >
>
^ permalink raw reply
* Re: [PATCH v13 00/18] unwind_deferred: Implement sframe handling
From: Dylan Hatch @ 2026-02-11 1:47 UTC (permalink / raw)
To: Jens Remus
Cc: linux-kernel, linux-trace-kernel, bpf, x86, linux-mm,
Steven Rostedt, Josh Poimboeuf, Masami Hiramatsu,
Mathieu Desnoyers, Peter Zijlstra, Ingo Molnar, Jiri Olsa,
Arnaldo Carvalho de Melo, Namhyung Kim, Thomas Gleixner,
Andrii Nakryiko, Indu Bhagat, Jose E. Marchesi, Beau Belgrave,
Linus Torvalds, Andrew Morton, Florian Weimer, Kees Cook,
Carlos O'Donell, Sam James, Borislav Petkov, Dave Hansen,
David Hildenbrand, H. Peter Anvin, Liam R. Howlett,
Lorenzo Stoakes, Michal Hocko, Mike Rapoport, Suren Baghdasaryan,
Vlastimil Babka, Heiko Carstens, Vasily Gorbik
In-Reply-To: <20260127150554.2760964-1-jremus@linux.ibm.com>
On Tue, Jan 27, 2026 at 7:06 AM Jens Remus <jremus@linux.ibm.com> wrote:
>
> This is the implementation of parsing the SFrame V3 stack trace information
> from an .sframe section in an ELF file. It's a continuation of Josh's and
> Steve's work that can be found here:
>
> https://lore.kernel.org/all/cover.1737511963.git.jpoimboe@kernel.org/
> https://lore.kernel.org/all/20250827201548.448472904@kernel.org/
>
> Currently the only way to get a user space stack trace from a stack
> walk (and not just copying large amount of user stack into the kernel
> ring buffer) is to use frame pointers. This has a few issues. The biggest
> one is that compiling frame pointers into every application and library
> has been shown to cause performance overhead.
>
> Another issue is that the format of the frames may not always be consistent
> between different compilers and some architectures (s390) has no defined
> format to do a reliable stack walk. The only way to perform user space
> profiling on these architectures is to copy the user stack into the kernel
> buffer.
>
> SFrame [1] is now supported in binutils (x86-64, ARM64, and s390). There is
> discussions going on about supporting SFrame in LLVM. SFrame acts more like
> ORC, and lives in the ELF executable file as its own section. Like ORC it
> has two tables where the first table is sorted by instruction pointers (IP)
> and using the current IP and finding it's entry in the first table, it will
> take you to the second table which will tell you where the return address
> of the current function is located and then you can use that address to
> look it up in the first table to find the return address of that function,
> and so on. This performs a user space stack walk.
>
> Now because the .sframe section lives in the ELF file it needs to be faulted
> into memory when it is used. This means that walking the user space stack
> requires being in a faultable context. As profilers like perf request a stack
> trace in interrupt or NMI context, it cannot do the walking when it is
> requested. Instead it must be deferred until it is safe to fault in user
> space. One place this is known to be safe is when the task is about to return
> back to user space.
>
> This series makes the deferred unwind user code implement SFrame format V3
> and enables it on x86-64.
>
> [1]: https://sourceware.org/binutils/wiki/sframe
>
>
> This series applies on top of the tip perf/core branch:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core
>
> The to be stack-traced user space programs (and libraries) need to be
> built with the recent SFrame stack trace information format V3, as
> generated by the upcoming binutils 2.46 with assembler option --gsframe.
> It can be built from source from the binutils-2_46-branch branch:
>
> git://sourceware.org/git/binutils-gdb.git binutils-2_46-branch
>
> Namhyung Kim's related perf tools deferred callchain support can be used
> for testing ("perf record --call-graph fp,defer" and "perf report/script").
>
>
> Changes since v12 (see patch notes for details):
> - Rebase on tip perf/core branch (d55c571e4333).
> - Add support for SFrame V3, including its new flexible FDEs. SFrame V2
> is not supported.
>
> Changes since v11 (see patch notes for details):
> - Rebase on tip master branch (f8fdee44bf2f) with Namhyung Kim's
> perf/defer-callchain-v4 branch merged on top.
> - Adjust to Peter's latest undwind user enhancements.
> - Simplify logic by using an internal SFrame FDE representation, whose
> FDE function start address field is an address instead of a PC-relative
> offset (from FDE).
> - Rename struct sframe_fre to sframe_fre_internal to align with
> struct sframe_fde_internal.
> - Remove unused pt_regs from unwind_user_next_common() and its
> callers. (Peter)
> - Simplify unwind_user_next_sframe(). (Peter)
> - Fix a few checkpatch errors and warnings.
> - Minor cleanups (e.g. move includes, fix indentation).
>
> Changes since v10:
> - Support for SFrame V2 PC-relative FDE function start address.
> - Support for SFrame V2 representing RA undefined as indication for
> outermost frames.
>
>
> Patches 1, 4, 11, and 17 have been updated to exclusively support the
> latest SFrame V3 stack trace information format, that is generated by
> the upcoming binutils 2.46 release. Old SFrame V2 sections get rejected
> with dynamic debug message "bad/unsupported sframe header".
>
> Patches 7 and 8 add support to unwind user (sframe) for outermost frames.
>
> Patches 12-15 add support to unwind user (sframe) for the new SFrame V3
> flexible FDEs.
>
> Patch 16 improves the performance of searching the SFrame FRE for an IP.
>
> Regards,
> Jens
>
>
> Jens Remus (7):
> unwind_user: Stop when reaching an outermost frame
> unwind_user/sframe: Add support for outermost frame indication
> unwind_user: Enable archs that pass RA in a register
> unwind_user: Flexible FP/RA recovery rules
> unwind_user: Flexible CFA recovery rules
> unwind_user/sframe: Add support for SFrame V3 flexible FDEs
> unwind_user/sframe: Separate reading of FRE from reading of FRE data
> words
>
> Josh Poimboeuf (11):
> unwind_user/sframe: Add support for reading .sframe headers
> unwind_user/sframe: Store .sframe section data in per-mm maple tree
> x86/uaccess: Add unsafe_copy_from_user() implementation
> unwind_user/sframe: Add support for reading .sframe contents
> unwind_user/sframe: Detect .sframe sections in executables
> unwind_user/sframe: Wire up unwind_user to sframe
> unwind_user/sframe: Remove .sframe section on detected corruption
> unwind_user/sframe: Show file name in debug output
> unwind_user/sframe: Add .sframe validation option
> unwind_user/sframe/x86: Enable sframe unwinding on x86
> unwind_user/sframe: Add prctl() interface for registering .sframe
> sections
>
> MAINTAINERS | 1 +
> arch/Kconfig | 23 +
> arch/x86/Kconfig | 1 +
> arch/x86/include/asm/mmu.h | 2 +-
> arch/x86/include/asm/uaccess.h | 39 +-
> arch/x86/include/asm/unwind_user.h | 69 +-
> arch/x86/include/asm/unwind_user_sframe.h | 12 +
> fs/binfmt_elf.c | 48 +-
> include/linux/mm_types.h | 3 +
> include/linux/sframe.h | 60 ++
> include/linux/unwind_user.h | 18 +
> include/linux/unwind_user_types.h | 46 +-
> include/uapi/linux/elf.h | 1 +
> include/uapi/linux/prctl.h | 6 +-
> kernel/fork.c | 10 +
> kernel/sys.c | 9 +
> kernel/unwind/Makefile | 3 +-
> kernel/unwind/sframe.c | 840 ++++++++++++++++++++++
> kernel/unwind/sframe.h | 87 +++
> kernel/unwind/sframe_debug.h | 68 ++
> kernel/unwind/user.c | 105 ++-
> mm/init-mm.c | 2 +
> 22 files changed, 1414 insertions(+), 39 deletions(-)
> create mode 100644 arch/x86/include/asm/unwind_user_sframe.h
> create mode 100644 include/linux/sframe.h
> create mode 100644 kernel/unwind/sframe.c
> create mode 100644 kernel/unwind/sframe.h
> create mode 100644 kernel/unwind/sframe_debug.h
>
> --
> 2.51.0
>
Hi Jens,
Do you by chance have this work uploaded in a public branch somewhere?
I'd like to get a new version of the SFrame for reliable stacktrace on
arm64 patch series [1] working for SFrame V3, ideally with the SFrame
library in your patch series here.
https://lore.kernel.org/lkml/20250904223850.884188-1-dylanbhatch@google.com/
Thanks,
Dylan
^ permalink raw reply
* Re: [PATCH v13 00/18] unwind_deferred: Implement sframe handling
From: Namhyung Kim @ 2026-02-11 0:17 UTC (permalink / raw)
To: Jens Remus
Cc: Steven Rostedt, linux-kernel, linux-trace-kernel, bpf, x86,
linux-mm, Josh Poimboeuf, Masami Hiramatsu, Mathieu Desnoyers,
Peter Zijlstra, Ingo Molnar, Jiri Olsa, Arnaldo Carvalho de Melo,
Thomas Gleixner, Andrii Nakryiko, Indu Bhagat, Jose E. Marchesi,
Beau Belgrave, Linus Torvalds, Andrew Morton, Florian Weimer,
Kees Cook, Carlos O'Donell, Sam James, Dylan Hatch,
Borislav Petkov, Dave Hansen, David Hildenbrand, H. Peter Anvin,
Liam R. Howlett, Lorenzo Stoakes, Michal Hocko, Mike Rapoport,
Suren Baghdasaryan, Vlastimil Babka, Heiko Carstens,
Vasily Gorbik
In-Reply-To: <113e4e4d-8b7a-437d-a3a2-de74acc9ecaa@linux.ibm.com>
Hello,
On Mon, Feb 09, 2026 at 06:07:59PM +0100, Jens Remus wrote:
> On 2/5/2026 7:54 PM, Steven Rostedt wrote:
> > On Thu, 5 Feb 2026 10:26:10 -0800
> > Namhyung Kim <namhyung@kernel.org> wrote:
> >
> >>> Namhyung Kim's related perf tools deferred callchain support can be used
> >>> for testing ("perf record --call-graph fp,defer" and "perf report/script").
> >>
> >> Is it possible for users to choose the unwinder - frame pointer or
> >> SFrame at runtime? I feel like the option should be
> >> "--call-graph sframe,defer" or just "--call-graph sframe" if it always
> >> uses deferred unwinding.
> >
> > Currently no, and I'm not sure we want that do we? The idea is to use the
> > best option that is available. Why use frame pointers if sframe is
> > available and it's being called with defer?
> >
> > If there's no defer, then sframes are not available, so it defaults to the
> > best option available (which will likely be frame pointers).
Users (me, at least) may want to compare stacktraces from FP and SFrame?
>
> Maybe it would make sense not to "overload" the perf record option
> "--call-graph fp,defer" and use it for all deferred unwinding methods.
>
> What about "--call-graph defer", "--call-graph any,defer", or
> "--call-graph *,defer"?
Sounds better. But I think it cannot enforce "--call-graph fp,defer" to
use frame pointers when SFrame is available.. Hmm.
Thanks,
Namhyung
^ permalink raw reply
* Re: [PATCH v2 0/4] tools/rtla: Consolidate nr_cpus usage
From: Crystal Wood @ 2026-02-10 21:07 UTC (permalink / raw)
To: Costa Shulyupin, Steven Rostedt, Tomas Glozar,
Wander Lairson Costa, Ivan Pravdin, John Kacur, Tiezhu Yang,
linux-trace-kernel, linux-kernel, bpf
In-Reply-To: <20260209092436.2899888-1-costa.shul@redhat.com>
On Mon, 2026-02-09 at 11:24 +0200, Costa Shulyupin wrote:
> sysconf(_SC_NPROCESSORS_CONF) (via get_nprocs_conf) reflects
> cpu_possible_mask, which is fixed at boot time, so querying it
> repeatedly is unnecessary.
>
> Replace multiple calls to sysconf(_SC_NPROCESSORS_CONF) with a single
> global nr_cpus variable initialized once at startup.
>
> v2:
> - Add `#pragma once` in timerlat_u.h to avoid redefinition errors with
> pre-C23 compilers.
>
> Costa Shulyupin (4):
> tools/rtla: Consolidate nr_cpus usage across all tools
> tools/rtla: Remove unneeded nr_cpus arguments
> tools/rtla: Remove unneeded nr_cpus members
> tools/rtla: Remove unneeded nr_cpus from for_each_monitored_cpu
>
> tools/tracing/rtla/src/common.c | 7 ++-
> tools/tracing/rtla/src/common.h | 4 +-
> tools/tracing/rtla/src/osnoise_hist.c | 26 +++++------
> tools/tracing/rtla/src/osnoise_top.c | 16 ++-----
> tools/tracing/rtla/src/timerlat.c | 9 ++--
> tools/tracing/rtla/src/timerlat_aa.c | 11 ++---
> tools/tracing/rtla/src/timerlat_bpf.c | 5 +--
> tools/tracing/rtla/src/timerlat_bpf.h | 6 +--
> tools/tracing/rtla/src/timerlat_hist.c | 62 +++++++++++---------------
> tools/tracing/rtla/src/timerlat_top.c | 47 +++++++------------
> tools/tracing/rtla/src/timerlat_u.c | 9 ++--
> tools/tracing/rtla/src/timerlat_u.h | 1 +
> tools/tracing/rtla/src/utils.c | 10 +----
> 13 files changed, 80 insertions(+), 133 deletions(-)
Reviewed-by: Crystal Wood <crwood@redhat.com>
-Crystal
^ permalink raw reply
* Re: [PATCH 1/5] tracing: Fix checking of freed trace_event_file for hist files
From: kernel test robot @ 2026-02-10 18:57 UTC (permalink / raw)
To: Petr Pavlu, Steven Rostedt, Masami Hiramatsu
Cc: llvm, oe-kbuild-all, Mathieu Desnoyers, Tom Zanussi, linux-kernel,
linux-trace-kernel, Petr Pavlu
In-Reply-To: <20260210113427.1068932-2-petr.pavlu@suse.com>
Hi Petr,
kernel test robot noticed the following build errors:
[auto build test ERROR on 05f7e89ab9731565d8a62e3b5d1ec206485eeb0b]
url: https://github.com/intel-lab-lkp/linux/commits/Petr-Pavlu/tracing-Fix-checking-of-freed-trace_event_file-for-hist-files/20260210-194023
base: 05f7e89ab9731565d8a62e3b5d1ec206485eeb0b
patch link: https://lore.kernel.org/r/20260210113427.1068932-2-petr.pavlu%40suse.com
patch subject: [PATCH 1/5] tracing: Fix checking of freed trace_event_file for hist files
config: sparc64-defconfig (https://download.01.org/0day-ci/archive/20260211/202602110247.8HeuKXss-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/20260211/202602110247.8HeuKXss-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/202602110247.8HeuKXss-lkp@intel.com/
All errors (new ones prefixed by >>):
>> kernel/trace/trace_events.c:1300:2: error: call to undeclared function 'hist_poll_wakeup'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
1300 | hist_poll_wakeup();
| ^
1 error generated.
vim +/hist_poll_wakeup +1300 kernel/trace/trace_events.c
1289
1290 static void remove_event_file_dir(struct trace_event_file *file)
1291 {
1292 eventfs_remove_dir(file->ei);
1293 list_del(&file->list);
1294 remove_subsystem(file->system);
1295 free_event_filter(file->filter);
1296 file->flags |= EVENT_FILE_FL_FREED;
1297 event_file_put(file);
1298
1299 /* Wake up hist poll waiters to notice the EVENT_FILE_FL_FREED flag. */
> 1300 hist_poll_wakeup();
1301 }
1302
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH v8 6/6] x86/vdso: Enable sframe generation in VDSO
From: H. Peter Anvin @ 2026-02-10 18:49 UTC (permalink / raw)
To: Jens Remus, linux-kernel, linux-trace-kernel, bpf, x86, linux-mm,
Josh Poimboeuf, Steven Rostedt
Cc: Masami Hiramatsu, Mathieu Desnoyers, Peter Zijlstra, Ingo Molnar,
Jiri Olsa, Arnaldo Carvalho de Melo, Namhyung Kim,
Thomas Gleixner, Andrii Nakryiko, Indu Bhagat, Jose E. Marchesi,
Beau Belgrave, Linus Torvalds, Andrew Morton, Florian Weimer,
Kees Cook, Carlos O'Donell, Sam James, Dylan Hatch,
Borislav Petkov, Dave Hansen, David Hildenbrand, Liam R. Howlett,
Lorenzo Stoakes, Michal Hocko, Mike Rapoport, Suren Baghdasaryan,
Vlastimil Babka, Heiko Carstens, Vasily Gorbik,
Steven Rostedt (Google)
In-Reply-To: <15f2af3b-be33-46fc-b972-6b8e7e0aa52e@linux.ibm.com>
On February 10, 2026 8:46:33 AM PST, Jens Remus <jremus@linux.ibm.com> wrote:
>On 2/6/2026 8:36 PM, Jens Remus wrote:
>> From: Josh Poimboeuf <jpoimboe@kernel.org>
>>
>> Enable sframe generation in the VDSO library so kernel and user space
>> can unwind through it.
>>
>> SFrame isn't supported for x32 or x86-32. Discard .sframe sections for
>> those VDSOs.
>>
>> [ Jens Remus: Add support for SFrame V3. Prevent GNU_SFRAME program
>> table entry to empty .sframe section. ]
>>
>> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
>> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
>> Signed-off-by: Jens Remus <jremus@linux.ibm.com>
>
>> diff --git a/arch/Kconfig b/arch/Kconfig
>
>> @@ -479,6 +479,13 @@ config HAVE_HARDLOCKUP_DETECTOR_ARCH
>> It uses the same command line parameters, and sysctl interface,
>> as the generic hardlockup detectors.
>>
>> +config AS_SFRAME
>> + bool
>> +
>> +config AS_SFRAME3
>> + def_bool $(as-instr,.cfi_startproc\n.cfi_endproc,-Wa$(comma)--gsframe-3)
>
>Above tests whether the assembler supports --gsframe-3 to generate
>.sframe in SFrame V3 format. GNU assembler only supports to generate
>SFrame for x86-64. If the assembler is built for i386 (x86-32) the test
>will fail unless option --64 is specified. I wonder whether that could
>happen in (the rather hypothetical?) case, when the kernel is cross built
>for x86-64 on i386? Should this therefore be changed to the following?
>
>config AS_SFRAME_64
> def_bool $(as-instr,.cfi_startproc\n.cfi_endproc,$(m64-flag) -Wa$(comma)--gsframe)
>
>An alternative would be to enable as-instr64 to accept an optional flag
>operand, similar to as-instr, and use as-instr64 instead of as-instr.
>
>Or is this not required, as in a cross build for 64-bit on a 32-bit
>platform (or inverse) a respective cross toolchain is a prerequisite and
>the m64-flag (or m32-flag) is not used?
>
>I tried to simulate this using docker and an i386 image and then using
>the i386 tool in the container to switch "uname -m" to "i686". But both
>of my following attempts to build for x86-64 on i386 fail with fixdep
>not found:
>
>$ docker run -it --rm -v "$HOME/linux:$HOME/linux" --platform i386 public.ecr.aws/docker/library/debian:13.3
># sed -i -s 's/^Types: deb/& deb-src/' /etc/apt/sources.list.d/debian.sources
># apt update
># apt -y build-dep linux
>
># make mrproper
># i386 make ARCH=x86_64 defconfig
># i386 make ARCH=x86_64 arch/x86/entry/vdso/
>
># make mrproper
># apt -y install gcc-x86-64-linux-gnu
># i386 make ARCH=x86_64 CROSS_COMPILE=x86_64-linux-gnu- defconfig
># i386 make ARCH=x86_64 CROSS_COMPILE=x86_64-linux-gnu- arch/x86/entry/vdso/
>
>> + select AS_SFRAME
>> +
>> config UNWIND_USER
>> bool
>
>> diff --git a/arch/x86/entry/vdso/vdso64/Makefile b/arch/x86/entry/vdso/vdso64/Makefile
>
>> @@ -14,6 +14,7 @@ vobjs-$(CONFIG_X86_SGX) += vsgx.o
>>
>> # Compilation flags
>> flags-y := -DBUILD_VDSO64 -m64 -mcmodel=small
>> +flags-$(CONFIG_AS_SFRAME3) += -Wa,--gsframe-3
>
>flags-$(CONFIG_AS_SFRAME3_64) += -Wa,--gsframe-3
>
>>
>> # The location of this include matters!
>> include $(src)/../common/Makefile.include
>Thanks and regards,
>Jens
I think we can worry about that later.
^ permalink raw reply
* Re: [PATCH v8 6/6] x86/vdso: Enable sframe generation in VDSO
From: Josh Poimboeuf @ 2026-02-10 18:50 UTC (permalink / raw)
To: Jens Remus
Cc: H. Peter Anvin, linux-kernel, linux-trace-kernel, bpf, x86,
linux-mm, Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
Peter Zijlstra, Ingo Molnar, Jiri Olsa, Arnaldo Carvalho de Melo,
Namhyung Kim, Thomas Gleixner, Andrii Nakryiko, Indu Bhagat,
Jose E. Marchesi, Beau Belgrave, Linus Torvalds, Andrew Morton,
Florian Weimer, Kees Cook, Carlos O'Donell, Sam James,
Dylan Hatch, Borislav Petkov, Dave Hansen, David Hildenbrand,
Liam R. Howlett, Lorenzo Stoakes, Michal Hocko, Mike Rapoport,
Suren Baghdasaryan, Vlastimil Babka, Heiko Carstens,
Vasily Gorbik, Steven Rostedt (Google)
In-Reply-To: <15f2af3b-be33-46fc-b972-6b8e7e0aa52e@linux.ibm.com>
On Tue, Feb 10, 2026 at 05:46:33PM +0100, Jens Remus wrote:
> On 2/6/2026 8:36 PM, Jens Remus wrote:
> > From: Josh Poimboeuf <jpoimboe@kernel.org>
> >
> > Enable sframe generation in the VDSO library so kernel and user space
> > can unwind through it.
> >
> > SFrame isn't supported for x32 or x86-32. Discard .sframe sections for
> > those VDSOs.
> >
> > [ Jens Remus: Add support for SFrame V3. Prevent GNU_SFRAME program
> > table entry to empty .sframe section. ]
> >
> > Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
> > Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
> > Signed-off-by: Jens Remus <jremus@linux.ibm.com>
>
> > diff --git a/arch/Kconfig b/arch/Kconfig
>
> > @@ -479,6 +479,13 @@ config HAVE_HARDLOCKUP_DETECTOR_ARCH
> > It uses the same command line parameters, and sysctl interface,
> > as the generic hardlockup detectors.
> >
> > +config AS_SFRAME
> > + bool
> > +
> > +config AS_SFRAME3
> > + def_bool $(as-instr,.cfi_startproc\n.cfi_endproc,-Wa$(comma)--gsframe-3)
>
> Above tests whether the assembler supports --gsframe-3 to generate
> .sframe in SFrame V3 format. GNU assembler only supports to generate
> SFrame for x86-64. If the assembler is built for i386 (x86-32) the test
> will fail unless option --64 is specified. I wonder whether that could
> happen in (the rather hypothetical?) case, when the kernel is cross built
> for x86-64 on i386? Should this therefore be changed to the following?
>
> config AS_SFRAME_64
> def_bool $(as-instr,.cfi_startproc\n.cfi_endproc,$(m64-flag) -Wa$(comma)--gsframe)
>
> An alternative would be to enable as-instr64 to accept an optional flag
> operand, similar to as-instr, and use as-instr64 instead of as-instr.
>
> Or is this not required, as in a cross build for 64-bit on a 32-bit
> platform (or inverse) a respective cross toolchain is a prerequisite and
> the m64-flag (or m32-flag) is not used?
>
> I tried to simulate this using docker and an i386 image and then using
> the i386 tool in the container to switch "uname -m" to "i686". But both
> of my following attempts to build for x86-64 on i386 fail with fixdep
> not found:
>
> $ docker run -it --rm -v "$HOME/linux:$HOME/linux" --platform i386 public.ecr.aws/docker/library/debian:13.3
> # sed -i -s 's/^Types: deb/& deb-src/' /etc/apt/sources.list.d/debian.sources
> # apt update
> # apt -y build-dep linux
>
> # make mrproper
> # i386 make ARCH=x86_64 defconfig
> # i386 make ARCH=x86_64 arch/x86/entry/vdso/
>
> # make mrproper
> # apt -y install gcc-x86-64-linux-gnu
> # i386 make ARCH=x86_64 CROSS_COMPILE=x86_64-linux-gnu- defconfig
> # i386 make ARCH=x86_64 CROSS_COMPILE=x86_64-linux-gnu- arch/x86/entry/vdso/
Hm, I think I broke that with
a808a2b35f66 ("tools build: Fix fixdep dependencies")
... though it's been broken almost a year, maybe nobody cares.
Regardless, we do need to fix "make clean" and "make mrproper" for
objtool, which would be something like so:
diff --git a/Makefile b/Makefile
index d3a8482bdbd0..ed850044491d 100644
--- a/Makefile
+++ b/Makefile
@@ -1474,6 +1474,15 @@ ifneq ($(wildcard $(resolve_btfids_O)),)
$(Q)$(MAKE) -sC $(srctree)/tools/bpf/resolve_btfids O=$(resolve_btfids_O) clean
endif
+PHONY += objtool_clean
+
+objtool_O = $(abspath $(objtree))/tools/objtool
+
+objtool_clean:
+ifneq ($(wildcard $(objtool_O)),)
+ $(Q)$(MAKE) -sC $(abs_srctree)/tools/objtool O=$(objtool_O) srctree=$(abs_srctree) clean
+endif
+
tools/: FORCE
$(Q)mkdir -p $(objtree)/tools
$(Q)$(MAKE) O=$(abspath $(objtree)) subdir=tools -C $(srctree)/tools/
@@ -1637,7 +1646,7 @@ vmlinuxclean:
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/link-vmlinux.sh clean
$(Q)$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) clean)
-clean: archclean vmlinuxclean resolve_btfids_clean
+clean: archclean vmlinuxclean resolve_btfids_clean objtool_clean
# mrproper - Delete all generated files, including .config
#
diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
index a40f30232929..6964175abdfd 100644
--- a/tools/objtool/Makefile
+++ b/tools/objtool/Makefile
@@ -29,6 +29,8 @@ srctree := $(patsubst %/,%,$(dir $(CURDIR)))
srctree := $(patsubst %/,%,$(dir $(srctree)))
endif
+RM ?= rm -f
+
LIBSUBCMD_DIR = $(srctree)/tools/lib/subcmd/
ifneq ($(OUTPUT),)
LIBSUBCMD_OUTPUT = $(abspath $(OUTPUT))/libsubcmd
^ permalink raw reply related
* Re: [PATCH 1/5] tracing: Fix checking of freed trace_event_file for hist files
From: kernel test robot @ 2026-02-10 17:40 UTC (permalink / raw)
To: Petr Pavlu, Steven Rostedt, Masami Hiramatsu
Cc: oe-kbuild-all, Mathieu Desnoyers, Tom Zanussi, linux-kernel,
linux-trace-kernel, Petr Pavlu
In-Reply-To: <20260210113427.1068932-2-petr.pavlu@suse.com>
Hi Petr,
kernel test robot noticed the following build errors:
[auto build test ERROR on 05f7e89ab9731565d8a62e3b5d1ec206485eeb0b]
url: https://github.com/intel-lab-lkp/linux/commits/Petr-Pavlu/tracing-Fix-checking-of-freed-trace_event_file-for-hist-files/20260210-194023
base: 05f7e89ab9731565d8a62e3b5d1ec206485eeb0b
patch link: https://lore.kernel.org/r/20260210113427.1068932-2-petr.pavlu%40suse.com
patch subject: [PATCH 1/5] tracing: Fix checking of freed trace_event_file for hist files
config: x86_64-buildonly-randconfig-004-20260210 (https://download.01.org/0day-ci/archive/20260211/202602110125.71oIfNm0-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260211/202602110125.71oIfNm0-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/202602110125.71oIfNm0-lkp@intel.com/
All errors (new ones prefixed by >>):
kernel/trace/trace_events.c: In function 'remove_event_file_dir':
>> kernel/trace/trace_events.c:1300:9: error: implicit declaration of function 'hist_poll_wakeup' [-Wimplicit-function-declaration]
1300 | hist_poll_wakeup();
| ^~~~~~~~~~~~~~~~
vim +/hist_poll_wakeup +1300 kernel/trace/trace_events.c
1289
1290 static void remove_event_file_dir(struct trace_event_file *file)
1291 {
1292 eventfs_remove_dir(file->ei);
1293 list_del(&file->list);
1294 remove_subsystem(file->system);
1295 free_event_filter(file->filter);
1296 file->flags |= EVENT_FILE_FL_FREED;
1297 event_file_put(file);
1298
1299 /* Wake up hist poll waiters to notice the EVENT_FILE_FL_FREED flag. */
> 1300 hist_poll_wakeup();
1301 }
1302
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH v8 6/6] x86/vdso: Enable sframe generation in VDSO
From: Jens Remus @ 2026-02-10 16:46 UTC (permalink / raw)
To: H. Peter Anvin, linux-kernel, linux-trace-kernel, bpf, x86,
linux-mm, Josh Poimboeuf, Steven Rostedt
Cc: Masami Hiramatsu, Mathieu Desnoyers, Peter Zijlstra, Ingo Molnar,
Jiri Olsa, Arnaldo Carvalho de Melo, Namhyung Kim,
Thomas Gleixner, Andrii Nakryiko, Indu Bhagat, Jose E. Marchesi,
Beau Belgrave, Linus Torvalds, Andrew Morton, Florian Weimer,
Kees Cook, Carlos O'Donell, Sam James, Dylan Hatch,
Borislav Petkov, Dave Hansen, David Hildenbrand, Liam R. Howlett,
Lorenzo Stoakes, Michal Hocko, Mike Rapoport, Suren Baghdasaryan,
Vlastimil Babka, Heiko Carstens, Vasily Gorbik,
Steven Rostedt (Google)
In-Reply-To: <20260206193642.1580787-7-jremus@linux.ibm.com>
On 2/6/2026 8:36 PM, Jens Remus wrote:
> From: Josh Poimboeuf <jpoimboe@kernel.org>
>
> Enable sframe generation in the VDSO library so kernel and user space
> can unwind through it.
>
> SFrame isn't supported for x32 or x86-32. Discard .sframe sections for
> those VDSOs.
>
> [ Jens Remus: Add support for SFrame V3. Prevent GNU_SFRAME program
> table entry to empty .sframe section. ]
>
> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
> Signed-off-by: Jens Remus <jremus@linux.ibm.com>
> diff --git a/arch/Kconfig b/arch/Kconfig
> @@ -479,6 +479,13 @@ config HAVE_HARDLOCKUP_DETECTOR_ARCH
> It uses the same command line parameters, and sysctl interface,
> as the generic hardlockup detectors.
>
> +config AS_SFRAME
> + bool
> +
> +config AS_SFRAME3
> + def_bool $(as-instr,.cfi_startproc\n.cfi_endproc,-Wa$(comma)--gsframe-3)
Above tests whether the assembler supports --gsframe-3 to generate
.sframe in SFrame V3 format. GNU assembler only supports to generate
SFrame for x86-64. If the assembler is built for i386 (x86-32) the test
will fail unless option --64 is specified. I wonder whether that could
happen in (the rather hypothetical?) case, when the kernel is cross built
for x86-64 on i386? Should this therefore be changed to the following?
config AS_SFRAME_64
def_bool $(as-instr,.cfi_startproc\n.cfi_endproc,$(m64-flag) -Wa$(comma)--gsframe)
An alternative would be to enable as-instr64 to accept an optional flag
operand, similar to as-instr, and use as-instr64 instead of as-instr.
Or is this not required, as in a cross build for 64-bit on a 32-bit
platform (or inverse) a respective cross toolchain is a prerequisite and
the m64-flag (or m32-flag) is not used?
I tried to simulate this using docker and an i386 image and then using
the i386 tool in the container to switch "uname -m" to "i686". But both
of my following attempts to build for x86-64 on i386 fail with fixdep
not found:
$ docker run -it --rm -v "$HOME/linux:$HOME/linux" --platform i386 public.ecr.aws/docker/library/debian:13.3
# sed -i -s 's/^Types: deb/& deb-src/' /etc/apt/sources.list.d/debian.sources
# apt update
# apt -y build-dep linux
# make mrproper
# i386 make ARCH=x86_64 defconfig
# i386 make ARCH=x86_64 arch/x86/entry/vdso/
# make mrproper
# apt -y install gcc-x86-64-linux-gnu
# i386 make ARCH=x86_64 CROSS_COMPILE=x86_64-linux-gnu- defconfig
# i386 make ARCH=x86_64 CROSS_COMPILE=x86_64-linux-gnu- arch/x86/entry/vdso/
> + select AS_SFRAME
> +
> config UNWIND_USER
> bool
> diff --git a/arch/x86/entry/vdso/vdso64/Makefile b/arch/x86/entry/vdso/vdso64/Makefile
> @@ -14,6 +14,7 @@ vobjs-$(CONFIG_X86_SGX) += vsgx.o
>
> # Compilation flags
> flags-y := -DBUILD_VDSO64 -m64 -mcmodel=small
> +flags-$(CONFIG_AS_SFRAME3) += -Wa,--gsframe-3
flags-$(CONFIG_AS_SFRAME3_64) += -Wa,--gsframe-3
>
> # The location of this include matters!
> include $(src)/../common/Makefile.include
Thanks and regards,
Jens
--
Jens Remus
Linux on Z Development (D3303)
jremus@de.ibm.com / jremus@linux.ibm.com
IBM Deutschland Research & Development GmbH; Vorsitzender des Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der Gesellschaft: Ehningen; Registergericht: Amtsgericht Stuttgart, HRB 243294
IBM Data Privacy Statement: https://www.ibm.com/privacy/
^ permalink raw reply
* Re: [PATCH 1/5] tracing: Fix checking of freed trace_event_file for hist files
From: Masami Hiramatsu @ 2026-02-10 15:59 UTC (permalink / raw)
To: Petr Pavlu
Cc: Steven Rostedt, Mathieu Desnoyers, Tom Zanussi, linux-kernel,
linux-trace-kernel
In-Reply-To: <20260210113427.1068932-2-petr.pavlu@suse.com>
On Tue, 10 Feb 2026 12:28:16 +0100
Petr Pavlu <petr.pavlu@suse.com> wrote:
> The event_hist_open() and event_hist_poll() functions currently retrieve
> a trace_event_file pointer from a file struct by invoking
> event_file_data(), which simply returns file->f_inode->i_private. The
> functions then check if the pointer is NULL to determine whether the event
> is still valid. This approach is flawed because i_private is assigned when
> an eventfs inode is allocated and remains set throughout its lifetime.
> Instead, the code should call event_file_file(), which checks for
> EVENT_FILE_FL_FREED. Using the incorrect access function may result in the
> code potentially opening a hist file for an event that is being removed or
> becoming stuck while polling on this file.
>
> A related issue is that although event_hist_poll() attempts to verify
> whether an event file is being removed, this check may not occur or could
> be unnecessarily delayed. This happens because hist_poll_wakeup() is
> currently invoked only from event_hist_trigger() when a hist command is
> triggered. If the event file is being removed, no associated hist command
> will be triggered and a waiter will be woken up only after an unrelated
> hist command is triggered.
>
> Fix these issues by changing the access method to event_file_file() and
> adding a call to hist_poll_wakeup() in remove_event_file_dir() after
> setting the EVENT_FILE_FL_FREED flag. This ensures that a task polling on
> a hist file is woken up and receives EPOLLERR.
>
Thanks for fixing!
Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
> Fixes: 1bd13edbbed6 ("tracing/hist: Add poll(POLLIN) support on hist file")
> Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
> ---
> kernel/trace/trace_events.c | 3 +++
> kernel/trace/trace_events_hist.c | 4 ++--
> 2 files changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
> index 137b4d9bb116..e8ed6ba155cf 100644
> --- a/kernel/trace/trace_events.c
> +++ b/kernel/trace/trace_events.c
> @@ -1295,6 +1295,9 @@ static void remove_event_file_dir(struct trace_event_file *file)
> free_event_filter(file->filter);
> file->flags |= EVENT_FILE_FL_FREED;
> event_file_put(file);
> +
> + /* Wake up hist poll waiters to notice the EVENT_FILE_FL_FREED flag. */
> + hist_poll_wakeup();
> }
>
> /*
> diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
> index c97bb2fda5c0..744c2aa3d668 100644
> --- a/kernel/trace/trace_events_hist.c
> +++ b/kernel/trace/trace_events_hist.c
> @@ -5778,7 +5778,7 @@ static __poll_t event_hist_poll(struct file *file, struct poll_table_struct *wai
>
> guard(mutex)(&event_mutex);
>
> - event_file = event_file_data(file);
> + event_file = event_file_file(file);
> if (!event_file)
> return EPOLLERR;
>
> @@ -5816,7 +5816,7 @@ static int event_hist_open(struct inode *inode, struct file *file)
>
> guard(mutex)(&event_mutex);
>
> - event_file = event_file_data(file);
> + event_file = event_file_file(file);
> if (!event_file) {
> ret = -ENODEV;
> goto err;
> --
> 2.52.0
>
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply
* Re: [PATCH v11 15/30] tracing: selftests: Add trace remote tests
From: Vincent Donnefort @ 2026-02-10 15:54 UTC (permalink / raw)
To: Steven Rostedt
Cc: mhiramat, mathieu.desnoyers, linux-trace-kernel, maz,
oliver.upton, joey.gouly, suzuki.poulose, yuzenghui, kvmarm,
linux-arm-kernel, jstultz, qperret, will, aneesh.kumar,
kernel-team, linux-kernel, Shuah Khan, linux-kselftest
In-Reply-To: <20260205124208.2ed7cff8@gandalf.local.home>
On Thu, Feb 05, 2026 at 12:42:08PM -0500, Steven Rostedt wrote:
> On Sat, 31 Jan 2026 13:28:33 +0000
> Vincent Donnefort <vdonnefort@google.com> wrote:
>
> > Exercise the tracefs interface for trace remote with a set of tests to
> > check:
> >
> > * loading/unloading (unloading.tc)
> > * reset (reset.tc)
> > * size changes (buffer_size.tc)
> > * consuming read (trace_pipe.tc)
> > * non-consuming read (trace.tc)
> >
> > Cc: Shuah Khan <skhan@linuxfoundation.org>
> > Cc: linux-kselftest@vger.kernel.org
> > Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
>
> This still fails:
>
> === Ftrace unit tests ===
> [1] Test trace remote buffer size [PASS]
> [2] Test hypervisor trace buffer size [UNSUPPORTED]
> [3] Test hypervisor trace buffer reset [UNSUPPORTED]
> [4] Test hypervisor consuming trace read [UNSUPPORTED]
> [5] Test hypervisor non-consuming trace read [UNSUPPORTED]
> [6] Test hypervisor trace buffer unloading [UNSUPPORTED]
> [7] Test trace remote reset [PASS]
> [8] Test trace remote consuming read [FAIL]
> [9] Test trace remote non-consuming read [FAIL]
> [10] Test trace remote unloading [PASS]
>
> I added this patch and the two failed tests now pass:
>
> diff --git a/tools/testing/selftests/ftrace/test.d/remotes/trace.tc b/tools/testing/selftests/ftrace/test.d/remotes/trace.tc
> index 081133ec45ff..dfc954a6a380 100644
> --- a/tools/testing/selftests/ftrace/test.d/remotes/trace.tc
> +++ b/tools/testing/selftests/ftrace/test.d/remotes/trace.tc
> @@ -106,8 +106,10 @@ test_trace()
> echo 0 > trace
>
> for cpu in $(get_cpu_ids); do
> - echo 0 > /sys/devices/system/cpu/cpu$cpu/online
> - break
> + if [ -f /sys/devices/system/cpu/cpu$cpu/online ]; then
> + echo 0 > /sys/devices/system/cpu/cpu$cpu/online
> + break
> + fi
Hum weird, I have changed it in v11 to
echo 0 > /sys/devices/system/cpu/cpu$cpu/online || return 0
That doesn't work? Because I would simply stop the test there if we can't
offline the CPU.
> done
>
> for i in $(seq 1 8); do
> diff --git a/tools/testing/selftests/ftrace/test.d/remotes/trace_pipe.tc b/tools/testing/selftests/ftrace/test.d/remotes/trace_pipe.tc
> index d28eaee10c7c..146f0a9fe311 100644
> --- a/tools/testing/selftests/ftrace/test.d/remotes/trace_pipe.tc
> +++ b/tools/testing/selftests/ftrace/test.d/remotes/trace_pipe.tc
> @@ -102,8 +102,10 @@ test_trace_pipe()
> echo 0 > trace
>
> for cpu in $(get_cpu_ids); do
> - echo 0 > /sys/devices/system/cpu/cpu$cpu/online
> - break
> + if [ -f /sys/devices/system/cpu/cpu$cpu/online ]; then
> + echo 0 > /sys/devices/system/cpu/cpu$cpu/online
> + break
> + fi
> done
>
> for i in $(seq 1 8); do
>
> -- Steve
^ permalink raw reply
* [PATCH] tracing: Fix indentation of return statement in print_trace_fmt()
From: Haoyang LIU @ 2026-02-10 15:39 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
open list:TRACING, open list:TRACING
Cc: tttturtleruss, open list:TRACING, open list:TRACING
The return statement inside the nested if block in print_trace_fmt()
is not properly indented, making the code structure unclear. This was
flagged by smatch as a warning.
Add proper indentation to the return statement to match the kernel
coding style and improve readability.
Signed-off-by: Haoyang LIU <tttturtleruss@gmail.com>
Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
---
kernel/trace/trace.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 8bd4ec08fb36..bf0ce2aac177 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -4286,7 +4286,7 @@ static enum print_line_t print_trace_fmt(struct trace_iterator *iter)
/* ftrace and system call events are still OK */
if ((event->type > __TRACE_LAST_TYPE) &&
!is_syscall_event(event))
- return print_event_fields(iter, event);
+ return print_event_fields(iter, event);
}
return event->funcs->trace(iter, sym_flags, event);
}
--
2.25.1
^ permalink raw reply related
* Re: [PATCH v11 07/30] tracing: Add non-consuming read to trace remotes
From: Vincent Donnefort @ 2026-02-10 15:32 UTC (permalink / raw)
To: Steven Rostedt
Cc: mhiramat, mathieu.desnoyers, linux-trace-kernel, maz,
oliver.upton, joey.gouly, suzuki.poulose, yuzenghui, kvmarm,
linux-arm-kernel, jstultz, qperret, will, aneesh.kumar,
kernel-team, linux-kernel
In-Reply-To: <20260204185208.646a6d26@gandalf.local.home>
On Wed, Feb 04, 2026 at 06:52:08PM -0500, Steven Rostedt wrote:
> On Sat, 31 Jan 2026 13:28:25 +0000
> Vincent Donnefort <vdonnefort@google.com> wrote:
>
> > -static struct trace_remote_iterator *trace_remote_iter(struct trace_remote *remote, int cpu)
> > +static void __free_ring_buffer_iter(struct trace_remote_iterator *iter, int cpu)
> > +{
> > + if (!iter->rb_iter)
> > + return;
>
> Hmm, can't iter->rb_iter be NULL when iter->rb_iters[] is used?
Arg yes, I missed that when I removed the union. And actually I don't think this
can be called with iter->rb_iter or iter->rb_iter NULL anymore.
>
> > +
> > + if (cpu != RING_BUFFER_ALL_CPUS) {
> > + ring_buffer_read_finish(iter->rb_iter);
> > + return;
> > + }
> > +
> > + for_each_possible_cpu(cpu) {
> > + if (iter->rb_iters[cpu])
> > + ring_buffer_read_finish(iter->rb_iters[cpu]);
> > + }
> > +
> > + kfree(iter->rb_iters);
> > +}
> > +
> > +static int __alloc_ring_buffer_iter(struct trace_remote_iterator *iter, int cpu)
> > +{
> > + if (cpu != RING_BUFFER_ALL_CPUS) {
> > + iter->rb_iter = ring_buffer_read_start(iter->remote->trace_buffer, cpu, GFP_KERNEL);
> > +
> > + return iter->rb_iter ? 0 : -ENOMEM;
> > + }
> > +
> > + iter->rb_iters = kcalloc(nr_cpu_ids, sizeof(*iter->rb_iters), GFP_KERNEL);
> > + if (!iter->rb_iters)
> > + return -ENOMEM;
> > +
> > + for_each_possible_cpu(cpu) {
> > + iter->rb_iters[cpu] = ring_buffer_read_start(iter->remote->trace_buffer, cpu,
> > + GFP_KERNEL);
> > + if (!iter->rb_iters[cpu]) {
> > + __free_ring_buffer_iter(iter, RING_BUFFER_ALL_CPUS);
>
> For instance, we call __free_ring_buffer_iter() here, but I don't see
> iter->rb_iter being set.
>
> -- Steve
>
>
> > + return -ENOMEM;
> > + }
> > + }
> > +
> > + return 0;
> > +}
> > +
[...]
> > +static void *trace_next(struct seq_file *m, void *v, loff_t *pos)
> > +{
> > + struct trace_remote_iterator *iter = m->private;
> > +
> > + ++*pos;
> > +
> > + if (!iter || !trace_remote_iter_read_event(iter))
> > + return NULL;
> > +
> > + trace_remote_iter_move(iter);
> > + iter->pos++;
> > +
> > + return iter;
> > +}
> > +
> > +static void *trace_start(struct seq_file *m, loff_t *pos)
> > +{
> > + struct trace_remote_iterator *iter = m->private;
> > + loff_t i;
> > +
>
> FYI, this is where you take locks for iteration of files.
>
> > + if (!iter)
> > + return NULL;
> > +
> > + if (!*pos) {
> > + iter->pos = -1;
> > + return trace_next(m, NULL, &i);
> > + }
> > +
> > + i = iter->pos;
> > + while (i < *pos) {
> > + iter = trace_next(m, NULL, &i);
> > + if (!iter)
> > + return NULL;
> > + }
> > +
> > + return iter;
> > +}
> > +
> > +static int trace_show(struct seq_file *m, void *v)
> > +{
> > + struct trace_remote_iterator *iter = v;
> > +
> > + trace_seq_init(&iter->seq);
> > +
> > + if (trace_remote_iter_print_event(iter)) {
> > + seq_printf(m, "[EVENT %d PRINT TOO BIG]\n", iter->evt->id);
> > + return 0;
> > + }
> > +
> > + return trace_print_seq(m, &iter->seq);
> > +}
> > +
> > +static void trace_stop(struct seq_file *s, void *v) { }
>
> And stop is where you release the locks.
>
> > +
> > +static const struct seq_operations trace_sops = {
> > + .start = trace_start,
> > + .next = trace_next,
> > + .show = trace_show,
> > + .stop = trace_stop,
> > +};
> > +
> > +static int trace_open(struct inode *inode, struct file *filp)
> > +{
> > + struct trace_remote *remote = inode->i_private;
> > + struct trace_remote_iterator *iter = NULL;
> > + int cpu = tracing_get_cpu(inode);
> > + int ret;
> > +
> > + if (!(filp->f_mode & FMODE_READ))
> > + return 0;
> > +
> > + guard(mutex)(&remote->lock);
> > +
> > + iter = trace_remote_iter(remote, cpu, TRI_NONCONSUMING);
> > + if (IS_ERR(iter))
> > + return PTR_ERR(iter);
>
> So if iter is bad we exit out here.
>
> > +
> > + ret = seq_open(filp, &trace_sops);
> > + if (ret) {
> > + trace_remote_iter_free(iter);
> > + return ret;
> > + }
> > +
> > + if (iter)
>
> Why test if iter exists here?
We only test IS_ERR. iter will be NULL if the buffer isn't loaded and the
userspace output would be empty. But anyway if I move the locking into
start/stop this line will go away!
>
> > + trace_remote_iter_read_start(iter);
>
> But still, the above grabs locks in the open, where it can return to user
> space while still holding the locks? That's a no-no.
>
> You can use the seq file start and stop for locking.
>
> -- Steve
>
[...]
^ permalink raw reply
* Re: [PATCH v8 6/6] x86/vdso: Enable sframe generation in VDSO
From: Jens Remus @ 2026-02-10 14:36 UTC (permalink / raw)
To: H. Peter Anvin, linux-kernel, linux-trace-kernel, bpf, x86,
linux-mm, Josh Poimboeuf, Steven Rostedt, Indu Bhagat
Cc: Masami Hiramatsu, Mathieu Desnoyers, Peter Zijlstra, Ingo Molnar,
Jiri Olsa, Arnaldo Carvalho de Melo, Namhyung Kim,
Thomas Gleixner, Andrii Nakryiko, Jose E. Marchesi, Beau Belgrave,
Linus Torvalds, Andrew Morton, Florian Weimer, Kees Cook,
Carlos O'Donell, Sam James, Dylan Hatch, Borislav Petkov,
Dave Hansen, David Hildenbrand, Liam R. Howlett, Lorenzo Stoakes,
Michal Hocko, Mike Rapoport, Suren Baghdasaryan, Vlastimil Babka,
Heiko Carstens, Vasily Gorbik, Steven Rostedt (Google)
In-Reply-To: <b074b10e-6b3e-4c69-a986-6b2eb665e535@zytor.com>
On 2/9/2026 8:13 PM, H. Peter Anvin wrote:
> On 2026-02-09 08:45, Jens Remus wrote:
>> On 2/7/2026 12:08 AM, H. Peter Anvin wrote:
>>> On 2026-02-06 11:36, Jens Remus wrote:
>>>> From: Josh Poimboeuf <jpoimboe@kernel.org>
>>>>
>>>> Enable sframe generation in the VDSO library so kernel and user space
>>>> can unwind through it.
>>>>
>>>> SFrame isn't supported for x32 or x86-32. Discard .sframe sections for
>>>> those VDSOs.
>>>>
>>>> [ Jens Remus: Add support for SFrame V3. Prevent GNU_SFRAME program
>>>> table entry to empty .sframe section. ]
>>>>
>>>
>>> This will not break the x86-32 build if the assembler encounters .sframe?
>>
>> I cannot follow. Assembler option --gsframe-3 is only specified in
>> vdso64/Makefile if CONFIG_AS_SFRAME3, which affects the x86-64 and x32
>> VDSOs. The latter as the x32 VDSO is built from x86-64 objects
>> converted to x86-32 objects using the X32 build step. Assembler
>> directive ".cfi_sections .sframe" is no longer used in dwarf2.h, which
>> affected the x86-32 VDSO if cross build on x86-64 (so that
>> CONFIG_AS_SFRAME3=y).
>>
>> The reason to discard .sframe in the common VDSO linker script if
>> !KEEP_SFRAME is to remove it from x32 VDSO (built from x86-64 objects
>> having .sframe). It should also prevent linker errors from linkers that
>> do not support R_X86_64_PC64 in x32 mode, such as the meanwhile fixed
>> GNU linker:
>> https://www.sourceware.org/bugzilla/show_bug.cgi?id=33807
>>
>
> OK, the linker not handing R_X86_64_PC64 is probably a good enough reason to
> discard .sframe.
For clarification:
Binutils < 2.46 assembler generates SFrame V2, which uses PC32
relocations.
Binutils 2.46+ assembler will generate SFrame V3, which uses PC64
relocations, which the GNU linker will also support for x32.
The intent is to only support SFrame V3 in unwind user sframe and
therefore also only enable .sframe generation in VDSO using SFrame V3.
> The x32 ABI and object format is explicitly intended to be as close to the
> x86-64 as possible; it even uses the same architectural identifier. That's
> pretty much the reason we don't even bother recompiling the objects in the
> first place; the 64-bit objects can simply be downconverted from ELF64 to
> ELF32. This also means that the compiler doesn't need to support x32, although
> objcopy and ld does.
>
> This also means the DWARF data is the one generated for 64 bits.
>
> This works because the following is true for all vdso entrypoints:
> - No vdso entry point access pointers or explicit "long"s *in memory*.
> (The latter formally violates POSIX for struct timespec, but that
> was a deliberate decision imposed by Linus at the time the x32 API
> was defined: "no 32-bit time_t in a new ABI.")
> - No vdso entry point calls system calls that do, either.
> - No vdso entry point takes a *signed* long as an argument.
> - No vdso entry point calls system calls that differ in behavior
> between x86-64 and x32, making it OK to call the 64-bit system call
> from an x32 process.
>
> "unsigned long" and pointers *can* be safely passed in argument registers
> (because the architecture will zero-extend those registers), and in addition
> "signed long" *can* be safely passed as returns.
>
> If ANY of the constraints above were ever violated, OR the binary format would
> start diverging to the point that objcopy can't properly convert it, then we
> would need to start compiling the x32 binaries separately.
Thank you for the detailed explanation!
>> The following works and indeed looks nicer with #if KEEP_SFRAME. Will
>> wait for further feedback on whether or not to discard .sframe in x32
>> VDSO before sending a v9.
>
> I think ld tripping over a bug justifies dropping .sframe at this point. *Make
> sure* to document that in the checkin, and add a comment to vdso32.lds.S that
> that is the motivation, so that if x32 gains support for .sframe in the future
> (which should be simple enough, since the formats are so similar) we don't get
> stuck in some kind of cargo cult programming problem.
>
> It also will avoid issues on the off chance .sframe ends up being defined
> differently for x32 for some reason, perhaps for consistency with other 32-bit
> platforms.
>
>
> Include the version of binutils which fixed the problem in your comments.
Ok, will do.
>> diff --git a/arch/x86/entry/vdso/vdso64/vdso64.lds.S b/arch/x86/entry/vdso/vdso64/vdso64.lds.S
>> @@ -8,10 +8,7 @@
>> */
>>
>> #define BUILD_VDSO64
>> -
>> -#ifdef CONFIG_AS_SFRAME
>> -# define KEEP_SFRAME
>> -#endif
>> +#define KEEP_SFRAME (CONFIG_AS_SFRAME)
>
> This needs to be IS_ENABLED(CONFIG_AS_SFRAME). Otherwise you get either "y" or
> "CONFIG_AS_SFRAME", neither of which are what you want.
Good catch! Will fix.
>
>> #include "common/vdso-layout.lds.S"
>>
>> diff --git a/arch/x86/entry/vdso/vdso64/vdsox32.lds.S b/arch/x86/entry/vdso/vdso64/vdsox32.lds.S
>> @@ -8,6 +8,7 @@
>> */
>>
>> #define BUILD_VDSOX32
>> +#define KEEP_SFRAME false
>
> Is "false" supported by all appropriate cpp versions? "0" is probably a safer
> choice, and matches the IS_ENABLED() output anyway.
Will do. I assumed "true" / "false" would be supported, given there are
a few instances:
$ git grep "#define.*\(false\|true\)" -- arch/x86/
Regards,
Jens
--
Jens Remus
Linux on Z Development (D3303)
jremus@de.ibm.com / jremus@linux.ibm.com
IBM Deutschland Research & Development GmbH; Vorsitzender des Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der Gesellschaft: Ehningen; Registergericht: Amtsgericht Stuttgart, HRB 243294
IBM Data Privacy Statement: https://www.ibm.com/privacy/
^ permalink raw reply
* [PATCH] tracing: make tr->d_max_latency accessible without CONFIG_FSNOTIFY
From: Arnd Bergmann @ 2026-02-10 14:13 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu
Cc: Arnd Bergmann, Mathieu Desnoyers, Tom Zanussi, pengdonglin,
Shengming Hu, linux-kernel, linux-trace-kernel
From: Arnd Bergmann <arnd@arndb.de>
A recent change attempted to make the tracing_max_latency file visible
unconditionally, but this lead to a build failure:
kernel/trace/trace.c: In function 'trace_create_maxlat_file':
kernel/trace/trace.c:1543:13: error: 'struct trace_array' has no member named 'd_max_latency'; did you mean 'max_latency'?
1543 | tr->d_max_latency = trace_create_file("tracing_max_latency",
| ^~~~~~~~~~~~~
Make the corresponding change in the header file.
Fixes: ba73713da50e ("tracing: Clean up use of trace_create_maxlat_file()")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
kernel/trace/trace.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 3ebff304fe36..b8f3804586a0 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -351,8 +351,8 @@ struct trace_array {
unsigned int snapshot;
#ifdef CONFIG_TRACER_MAX_TRACE
unsigned long max_latency;
-#ifdef CONFIG_FSNOTIFY
struct dentry *d_max_latency;
+#ifdef CONFIG_FSNOTIFY
struct work_struct fsnotify_work;
struct irq_work fsnotify_irqwork;
#endif /* CONFIG_FSNOTIFY */
--
2.39.5
^ permalink raw reply related
* [PATCH 5/5] tracing: Free up file->private_data for use by individual events
From: Petr Pavlu @ 2026-02-10 11:28 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu
Cc: Mathieu Desnoyers, Tom Zanussi, linux-kernel, linux-trace-kernel,
Petr Pavlu
In-Reply-To: <20260210113427.1068932-1-petr.pavlu@suse.com>
The tracing_open_file_tr() function currently copies the trace_event_file
pointer from inode->i_private to file->private_data when the file is
successfully opened. This duplication is not particularly useful, as all
event code should utilize event_file_file() or event_file_data() to
retrieve a trace_event_file pointer from a file struct and these access
functions read file->f_inode->i_private. Moreover, this setup requires the
code for opening hist files to explicitly clear file->private_data before
calling single_open(), since this function expects the private_data member
to be set to NULL and uses it to store a pointer to a seq_file.
Remove the unnecessary setting of file->private_data in
tracing_open_file_tr() and simplify the hist code.
Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
---
kernel/trace/trace.c | 2 --
kernel/trace/trace_events_hist.c | 4 ----
2 files changed, 6 deletions(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 8bd4ec08fb36..7c9882e5ba22 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -4805,8 +4805,6 @@ int tracing_open_file_tr(struct inode *inode, struct file *filp)
event_file_get(file);
}
- filp->private_data = inode->i_private;
-
return 0;
}
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index 744c2aa3d668..1ca3e14d7531 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -5831,8 +5831,6 @@ static int event_hist_open(struct inode *inode, struct file *file)
hist_file->file = file;
hist_file->last_act = get_hist_hit_count(event_file);
- /* Clear private_data to avoid warning in single_open() */
- file->private_data = NULL;
ret = single_open(file, hist_show, hist_file);
if (ret) {
kfree(hist_file);
@@ -6114,8 +6112,6 @@ static int event_hist_debug_open(struct inode *inode, struct file *file)
if (ret)
return ret;
- /* Clear private_data to avoid warning in single_open() */
- file->private_data = NULL;
ret = single_open(file, hist_debug_show, file);
if (ret)
tracing_release_file_tr(inode, file);
--
2.52.0
^ permalink raw reply related
* [PATCH 4/5] tracing: Clean up access to trace_event_file from a file pointer
From: Petr Pavlu @ 2026-02-10 11:28 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu
Cc: Mathieu Desnoyers, Tom Zanussi, linux-kernel, linux-trace-kernel,
Petr Pavlu
In-Reply-To: <20260210113427.1068932-1-petr.pavlu@suse.com>
The tracing code provides two functions event_file_file() and
event_file_data() to obtain a trace_event_file pointer from a file struct.
The primary method to use is event_file_file(), as it checks for the
EVENT_FILE_FL_FREED flag to determine whether the event is being removed.
The second function event_file_data() is an optimization for retrieving the
same data when the event_mutex is still held.
In the past, when removing an event directory in remove_event_file_dir(),
the code set i_private to NULL for all event files and readers were
expected to check for this state to recognize that the event is being
removed. In the case of event_id_read(), the value was read using
event_file_data() without acquiring the event_mutex. This required
event_file_data() to use READ_ONCE() when retrieving the i_private data.
With the introduction of eventfs, i_private is assigned when an eventfs
inode is allocated and remains set throughout its lifetime. A previous fix
also modified event_id_read() to read i_private while holding the
event_mutex.
Remove the now unnecessary READ_ONCE() access to i_private in both
event_file_file() and event_file_data(). Add a check in event_file_data()
to ensure that the event_mutex is held and that file->flags doesn't have
the EVENT_FILE_FL_FREED flag set. Finally, move event_file_data()
immediately after event_file_code() since the latter provides a comment
explaining how both functions should be used together.
Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
---
kernel/trace/trace.h | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index c11edec5d8f5..c6b450de93bc 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -1739,11 +1739,6 @@ extern struct trace_event_file *find_event_file(struct trace_array *tr,
const char *system,
const char *event);
-static inline void *event_file_data(struct file *filp)
-{
- return READ_ONCE(file_inode(filp)->i_private);
-}
-
extern struct mutex event_mutex;
extern struct list_head ftrace_events;
@@ -1764,12 +1759,22 @@ static inline struct trace_event_file *event_file_file(struct file *filp)
struct trace_event_file *file;
lockdep_assert_held(&event_mutex);
- file = READ_ONCE(file_inode(filp)->i_private);
+ file = file_inode(filp)->i_private;
if (!file || file->flags & EVENT_FILE_FL_FREED)
return NULL;
return file;
}
+static inline void *event_file_data(struct file *filp)
+{
+ struct trace_event_file *file;
+
+ lockdep_assert_held(&event_mutex);
+ file = file_inode(filp)->i_private;
+ WARN_ON(!file || file->flags & EVENT_FILE_FL_FREED);
+ return file;
+}
+
extern const struct file_operations event_trigger_fops;
extern const struct file_operations event_hist_fops;
extern const struct file_operations event_hist_debug_fops;
--
2.52.0
^ permalink raw reply related
* [PATCH 3/5] tracing: Remove unnecessary check for EVENT_FILE_FL_FREED
From: Petr Pavlu @ 2026-02-10 11:28 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu
Cc: Mathieu Desnoyers, Tom Zanussi, linux-kernel, linux-trace-kernel,
Petr Pavlu
In-Reply-To: <20260210113427.1068932-1-petr.pavlu@suse.com>
The event_filter_write() function calls event_file_file() to retrieve
a trace_event_file associated with a given file struct. If a non-NULL
pointer is returned, the function then checks whether the trace_event_file
instance has the EVENT_FILE_FL_FREED flag set. This check is redundant
because event_file_file() already performs this validation and returns NULL
if the flag is set. The err value is also already initialized to -ENODEV.
Remove the unnecessary check for EVENT_FILE_FL_FREED in
event_filter_write().
Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
---
kernel/trace/trace_events.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 3d272b3cd688..401ab7ed869b 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -2160,12 +2160,8 @@ event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
mutex_lock(&event_mutex);
file = event_file_file(filp);
- if (file) {
- if (file->flags & EVENT_FILE_FL_FREED)
- err = -ENODEV;
- else
- err = apply_event_filter(file, buf);
- }
+ if (file)
+ err = apply_event_filter(file, buf);
mutex_unlock(&event_mutex);
kfree(buf);
--
2.52.0
^ permalink raw reply related
* [PATCH 2/5] tracing: Fix checking of freed trace_event_file for id files
From: Petr Pavlu @ 2026-02-10 11:28 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu
Cc: Mathieu Desnoyers, Tom Zanussi, linux-kernel, linux-trace-kernel,
Petr Pavlu
In-Reply-To: <20260210113427.1068932-1-petr.pavlu@suse.com>
The code for reading an event id currently uses file->f_inode->i_private to
store the value of trace_event_file->event_call->event.type, unlike all
other event files which use it to store a pointer to the associated
trace_event_file data. The event_id_read() function retrieves this id value
from i_private and checks if it is non-0/NULL to determine whether the
event is still valid. This approach worked in the past when
remove_event_file_dir() would set i_private to NULL for all files in an
event directory upon removal. However, with the introduction of eventfs,
i_private is assigned when an eventfs inode is allocated and remains set
throughout its lifetime. As a result, event_id_read() may fail to detect
that an event is being removed.
Fix this issue by changing the event id file to use i_private to store
a trace_event_file pointer and utilize event_file_file() to check for the
EVENT_FILE_FL_FREED flag.
Fixes: 6fdac58c560e ("tracing: Remove unused trace_event_file dir field")
Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
---
kernel/trace/trace_events.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index e8ed6ba155cf..3d272b3cd688 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -2090,11 +2090,18 @@ static int trace_format_open(struct inode *inode, struct file *file)
static ssize_t
event_id_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
{
- int id = (long)event_file_data(filp);
+ struct trace_event_file *file;
+ int id;
char buf[32];
int len;
- if (unlikely(!id))
+ mutex_lock(&event_mutex);
+ file = event_file_file(filp);
+ if (likely(file))
+ id = file->event_call->event.type;
+ mutex_unlock(&event_mutex);
+
+ if (!file)
return -ENODEV;
len = sprintf(buf, "%d\n", id);
@@ -2572,7 +2579,9 @@ static const struct file_operations ftrace_event_format_fops = {
#ifdef CONFIG_PERF_EVENTS
static const struct file_operations ftrace_event_id_fops = {
+ .open = tracing_open_file_tr,
.read = event_id_read,
+ .release = tracing_release_file_tr,
.llseek = default_llseek,
};
#endif
@@ -2936,7 +2945,6 @@ static int event_callback(const char *name, umode_t *mode, void **data,
if (call->event.type && call->class->reg &&
strcmp(name, "id") == 0) {
*mode = TRACE_MODE_READ;
- *data = (void *)(long)call->event.type;
*fops = &ftrace_event_id_fops;
return 1;
}
--
2.52.0
^ permalink raw reply related
* [PATCH 1/5] tracing: Fix checking of freed trace_event_file for hist files
From: Petr Pavlu @ 2026-02-10 11:28 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu
Cc: Mathieu Desnoyers, Tom Zanussi, linux-kernel, linux-trace-kernel,
Petr Pavlu
In-Reply-To: <20260210113427.1068932-1-petr.pavlu@suse.com>
The event_hist_open() and event_hist_poll() functions currently retrieve
a trace_event_file pointer from a file struct by invoking
event_file_data(), which simply returns file->f_inode->i_private. The
functions then check if the pointer is NULL to determine whether the event
is still valid. This approach is flawed because i_private is assigned when
an eventfs inode is allocated and remains set throughout its lifetime.
Instead, the code should call event_file_file(), which checks for
EVENT_FILE_FL_FREED. Using the incorrect access function may result in the
code potentially opening a hist file for an event that is being removed or
becoming stuck while polling on this file.
A related issue is that although event_hist_poll() attempts to verify
whether an event file is being removed, this check may not occur or could
be unnecessarily delayed. This happens because hist_poll_wakeup() is
currently invoked only from event_hist_trigger() when a hist command is
triggered. If the event file is being removed, no associated hist command
will be triggered and a waiter will be woken up only after an unrelated
hist command is triggered.
Fix these issues by changing the access method to event_file_file() and
adding a call to hist_poll_wakeup() in remove_event_file_dir() after
setting the EVENT_FILE_FL_FREED flag. This ensures that a task polling on
a hist file is woken up and receives EPOLLERR.
Fixes: 1bd13edbbed6 ("tracing/hist: Add poll(POLLIN) support on hist file")
Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
---
kernel/trace/trace_events.c | 3 +++
kernel/trace/trace_events_hist.c | 4 ++--
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 137b4d9bb116..e8ed6ba155cf 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -1295,6 +1295,9 @@ static void remove_event_file_dir(struct trace_event_file *file)
free_event_filter(file->filter);
file->flags |= EVENT_FILE_FL_FREED;
event_file_put(file);
+
+ /* Wake up hist poll waiters to notice the EVENT_FILE_FL_FREED flag. */
+ hist_poll_wakeup();
}
/*
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index c97bb2fda5c0..744c2aa3d668 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -5778,7 +5778,7 @@ static __poll_t event_hist_poll(struct file *file, struct poll_table_struct *wai
guard(mutex)(&event_mutex);
- event_file = event_file_data(file);
+ event_file = event_file_file(file);
if (!event_file)
return EPOLLERR;
@@ -5816,7 +5816,7 @@ static int event_hist_open(struct inode *inode, struct file *file)
guard(mutex)(&event_mutex);
- event_file = event_file_data(file);
+ event_file = event_file_file(file);
if (!event_file) {
ret = -ENODEV;
goto err;
--
2.52.0
^ 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