* [PATCH v2 13/18] rtla: Fix buffer size for strncpy in timerlat_aa
From: Wander Lairson Costa @ 2026-01-06 11:49 UTC (permalink / raw)
To: Steven Rostedt, Tomas Glozar, Wander Lairson Costa, Crystal Wood,
Ivan Pravdin, Costa Shulyupin, John Kacur, Tiezhu Yang,
open list:Real-time Linux Analysis (RTLA) tools,
open list:Real-time Linux Analysis (RTLA) tools,
open list:BPF [MISC]:Keyword:(?:b|_)bpf(?:b|_)
In-Reply-To: <20260106133655.249887-1-wander@redhat.com>
The run_thread_comm and current_comm character arrays in struct
timerlat_aa_data are defined with size MAX_COMM (24 bytes), but
strncpy() is called with MAX_COMM as the size parameter. If the
source string is exactly MAX_COMM bytes or longer, strncpy() will
copy exactly MAX_COMM bytes without null termination, potentially
causing buffer overruns when these strings are later used.
Increase the buffer sizes to MAX_COMM+1 to ensure there is always
room for the null terminator. This guarantees that even when strncpy()
copies the maximum number of characters, the buffer remains properly
null-terminated and safe to use in subsequent string operations.
Signed-off-by: Wander Lairson Costa <wander@redhat.com>
---
tools/tracing/rtla/src/timerlat_aa.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/tracing/rtla/src/timerlat_aa.c b/tools/tracing/rtla/src/timerlat_aa.c
index 31e66ea2b144c..d310fe65abace 100644
--- a/tools/tracing/rtla/src/timerlat_aa.c
+++ b/tools/tracing/rtla/src/timerlat_aa.c
@@ -47,7 +47,7 @@ struct timerlat_aa_data {
* note: "unsigned long long" because they are fetch using tep_get_field_val();
*/
unsigned long long run_thread_pid;
- char run_thread_comm[MAX_COMM];
+ char run_thread_comm[MAX_COMM+1];
unsigned long long thread_blocking_duration;
unsigned long long max_exit_idle_latency;
@@ -88,7 +88,7 @@ struct timerlat_aa_data {
/*
* Current thread.
*/
- char current_comm[MAX_COMM];
+ char current_comm[MAX_COMM+1];
unsigned long long current_pid;
/*
--
2.52.0
^ permalink raw reply related
* [PATCH v2 12/18] rtla: Fix NULL pointer dereference in actions_parse
From: Wander Lairson Costa @ 2026-01-06 11:49 UTC (permalink / raw)
To: Steven Rostedt, Tomas Glozar, Wander Lairson Costa, Ivan Pravdin,
Crystal Wood, Costa Shulyupin, John Kacur, Tiezhu Yang,
open list:Real-time Linux Analysis (RTLA) tools,
open list:Real-time Linux Analysis (RTLA) tools,
open list:BPF [MISC]:Keyword:(?:b|_)bpf(?:b|_)
In-Reply-To: <20260106133655.249887-1-wander@redhat.com>
The actions_parse() function uses strtok() to tokenize the trigger
string, but does not check if the returned token is NULL before
passing it to strcmp(). If the trigger parameter is an empty string
or contains only delimiter characters, strtok() returns NULL, causing
strcmp() to dereference a NULL pointer and crash the program.
This issue can be triggered by malformed user input or edge cases in
trigger string parsing. Add a NULL check immediately after the strtok()
call to validate that a token was successfully extracted before using
it. If no token is found, the function now returns -1 to indicate a
parsing error.
Signed-off-by: Wander Lairson Costa <wander@redhat.com>
---
tools/tracing/rtla/src/actions.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tools/tracing/rtla/src/actions.c b/tools/tracing/rtla/src/actions.c
index 00bbc94dec1bd..b0d68b5de08db 100644
--- a/tools/tracing/rtla/src/actions.c
+++ b/tools/tracing/rtla/src/actions.c
@@ -153,6 +153,8 @@ actions_parse(struct actions *self, const char *trigger, const char *tracefn)
strcpy(trigger_c, trigger);
token = strtok(trigger_c, ",");
+ if (!token)
+ return -1;
if (strcmp(token, "trace") == 0)
type = ACTION_TRACE_OUTPUT;
--
2.52.0
^ permalink raw reply related
* [PATCH v2 11/18] rtla: Remove unused headers
From: Wander Lairson Costa @ 2026-01-06 11:49 UTC (permalink / raw)
To: Steven Rostedt, Tomas Glozar, Wander Lairson Costa, Crystal Wood,
Ivan Pravdin, Costa Shulyupin, John Kacur, Tiezhu Yang,
open list:Real-time Linux Analysis (RTLA) tools,
open list:Real-time Linux Analysis (RTLA) tools,
open list:BPF [MISC]:Keyword:(?:b|_)bpf(?:b|_)
In-Reply-To: <20260106133655.249887-1-wander@redhat.com>
Remove unused includes for <errno.h> and <signal.h> to clean up the
code and reduce unnecessary dependencies.
Signed-off-by: Wander Lairson Costa <wander@redhat.com>
---
tools/tracing/rtla/src/osnoise_hist.c | 1 -
tools/tracing/rtla/src/timerlat.c | 1 -
tools/tracing/rtla/src/timerlat_top.c | 1 -
tools/tracing/rtla/src/trace.c | 1 -
4 files changed, 4 deletions(-)
diff --git a/tools/tracing/rtla/src/osnoise_hist.c b/tools/tracing/rtla/src/osnoise_hist.c
index af7d8621dd9d7..c8e681f732315 100644
--- a/tools/tracing/rtla/src/osnoise_hist.c
+++ b/tools/tracing/rtla/src/osnoise_hist.c
@@ -9,7 +9,6 @@
#include <string.h>
#include <signal.h>
#include <unistd.h>
-#include <errno.h>
#include <stdio.h>
#include <time.h>
diff --git a/tools/tracing/rtla/src/timerlat.c b/tools/tracing/rtla/src/timerlat.c
index ac2ec89d3b6ba..b3d63506c4a62 100644
--- a/tools/tracing/rtla/src/timerlat.c
+++ b/tools/tracing/rtla/src/timerlat.c
@@ -9,7 +9,6 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <sched.h>
diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c
index f7e85dc918ef3..79ee66743bf1d 100644
--- a/tools/tracing/rtla/src/timerlat_top.c
+++ b/tools/tracing/rtla/src/timerlat_top.c
@@ -11,7 +11,6 @@
#include <unistd.h>
#include <stdio.h>
#include <time.h>
-#include <errno.h>
#include <sched.h>
#include <pthread.h>
diff --git a/tools/tracing/rtla/src/trace.c b/tools/tracing/rtla/src/trace.c
index 0a81a2e4667ef..092fcab77dc4c 100644
--- a/tools/tracing/rtla/src/trace.c
+++ b/tools/tracing/rtla/src/trace.c
@@ -2,7 +2,6 @@
#define _GNU_SOURCE
#include <sys/sendfile.h>
#include <tracefs.h>
-#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
--
2.52.0
^ permalink raw reply related
* [PATCH v2 10/18] rtla: Replace magic number with MAX_PATH
From: Wander Lairson Costa @ 2026-01-06 11:49 UTC (permalink / raw)
To: Steven Rostedt, Tomas Glozar, Wander Lairson Costa, Ivan Pravdin,
Crystal Wood, Costa Shulyupin, John Kacur, Tiezhu Yang,
open list:Real-time Linux Analysis (RTLA) tools,
open list:Real-time Linux Analysis (RTLA) tools,
open list:BPF [MISC]:Keyword:(?:b|_)bpf(?:b|_)
In-Reply-To: <20260106133655.249887-1-wander@redhat.com>
The trace functions use a buffer to manipulate strings that will be
written to tracefs files. These buffers are defined with a magic number
of 1024, which is a common source of vulnerabilities.
Replace the magic number 1024 with the MAX_PATH macro to make the code
safer and more readable. While at it, replace other instances of the
magic number with ARRAY_SIZE() when the buffer is locally defined.
Signed-off-by: Wander Lairson Costa <wander@redhat.com>
---
tools/tracing/rtla/src/osnoise.c | 4 ++--
tools/tracing/rtla/src/timerlat_u.c | 4 ++--
tools/tracing/rtla/src/trace.c | 20 ++++++++++----------
3 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/tools/tracing/rtla/src/osnoise.c b/tools/tracing/rtla/src/osnoise.c
index f2ec2da7b6d3a..68927d799dde5 100644
--- a/tools/tracing/rtla/src/osnoise.c
+++ b/tools/tracing/rtla/src/osnoise.c
@@ -52,7 +52,7 @@ char *osnoise_get_cpus(struct osnoise_context *context)
int osnoise_set_cpus(struct osnoise_context *context, char *cpus)
{
char *orig_cpus = osnoise_get_cpus(context);
- char buffer[1024];
+ char buffer[MAX_PATH];
int retval;
if (!orig_cpus)
@@ -62,7 +62,7 @@ int osnoise_set_cpus(struct osnoise_context *context, char *cpus)
if (!context->curr_cpus)
return -1;
- snprintf(buffer, 1024, "%s\n", cpus);
+ snprintf(buffer, ARRAY_SIZE(buffer), "%s\n", cpus);
debug_msg("setting cpus to %s from %s", cpus, context->orig_cpus);
diff --git a/tools/tracing/rtla/src/timerlat_u.c b/tools/tracing/rtla/src/timerlat_u.c
index ce68e39d25fde..efe2f72686486 100644
--- a/tools/tracing/rtla/src/timerlat_u.c
+++ b/tools/tracing/rtla/src/timerlat_u.c
@@ -32,7 +32,7 @@
static int timerlat_u_main(int cpu, struct timerlat_u_params *params)
{
struct sched_param sp = { .sched_priority = 95 };
- char buffer[1024];
+ char buffer[MAX_PATH];
int timerlat_fd;
cpu_set_t set;
int retval;
@@ -83,7 +83,7 @@ static int timerlat_u_main(int cpu, struct timerlat_u_params *params)
/* add should continue with a signal handler */
while (true) {
- retval = read(timerlat_fd, buffer, 1024);
+ retval = read(timerlat_fd, buffer, ARRAY_SIZE(buffer));
if (retval < 0)
break;
}
diff --git a/tools/tracing/rtla/src/trace.c b/tools/tracing/rtla/src/trace.c
index 45328c5121f79..0a81a2e4667ef 100644
--- a/tools/tracing/rtla/src/trace.c
+++ b/tools/tracing/rtla/src/trace.c
@@ -314,7 +314,7 @@ void trace_event_add_trigger(struct trace_events *event, char *trigger)
static void trace_event_disable_filter(struct trace_instance *instance,
struct trace_events *tevent)
{
- char filter[1024];
+ char filter[MAX_PATH];
int retval;
if (!tevent->filter)
@@ -326,7 +326,7 @@ static void trace_event_disable_filter(struct trace_instance *instance,
debug_msg("Disabling %s:%s filter %s\n", tevent->system,
tevent->event ? : "*", tevent->filter);
- snprintf(filter, 1024, "!%s\n", tevent->filter);
+ snprintf(filter, ARRAY_SIZE(filter), "!%s\n", tevent->filter);
retval = tracefs_event_file_write(instance->inst, tevent->system,
tevent->event, "filter", filter);
@@ -345,7 +345,7 @@ static void trace_event_save_hist(struct trace_instance *instance,
{
int retval, index, out_fd;
mode_t mode = 0644;
- char path[1024];
+ char path[MAX_PATH];
char *hist;
if (!tevent)
@@ -360,7 +360,7 @@ static void trace_event_save_hist(struct trace_instance *instance,
if (retval)
return;
- snprintf(path, 1024, "%s_%s_hist.txt", tevent->system, tevent->event);
+ snprintf(path, ARRAY_SIZE(path), "%s_%s_hist.txt", tevent->system, tevent->event);
printf(" Saving event %s:%s hist to %s\n", tevent->system, tevent->event, path);
@@ -392,7 +392,7 @@ static void trace_event_save_hist(struct trace_instance *instance,
static void trace_event_disable_trigger(struct trace_instance *instance,
struct trace_events *tevent)
{
- char trigger[1024];
+ char trigger[MAX_PATH];
int retval;
if (!tevent->trigger)
@@ -406,7 +406,7 @@ static void trace_event_disable_trigger(struct trace_instance *instance,
trace_event_save_hist(instance, tevent);
- snprintf(trigger, 1024, "!%s\n", tevent->trigger);
+ snprintf(trigger, ARRAY_SIZE(trigger), "!%s\n", tevent->trigger);
retval = tracefs_event_file_write(instance->inst, tevent->system,
tevent->event, "trigger", trigger);
@@ -445,7 +445,7 @@ void trace_events_disable(struct trace_instance *instance,
static int trace_event_enable_filter(struct trace_instance *instance,
struct trace_events *tevent)
{
- char filter[1024];
+ char filter[MAX_PATH];
int retval;
if (!tevent->filter)
@@ -457,7 +457,7 @@ static int trace_event_enable_filter(struct trace_instance *instance,
return 1;
}
- snprintf(filter, 1024, "%s\n", tevent->filter);
+ snprintf(filter, ARRAY_SIZE(filter), "%s\n", tevent->filter);
debug_msg("Enabling %s:%s filter %s\n", tevent->system,
tevent->event ? : "*", tevent->filter);
@@ -480,7 +480,7 @@ static int trace_event_enable_filter(struct trace_instance *instance,
static int trace_event_enable_trigger(struct trace_instance *instance,
struct trace_events *tevent)
{
- char trigger[1024];
+ char trigger[MAX_PATH];
int retval;
if (!tevent->trigger)
@@ -492,7 +492,7 @@ static int trace_event_enable_trigger(struct trace_instance *instance,
return 1;
}
- snprintf(trigger, 1024, "%s\n", tevent->trigger);
+ snprintf(trigger, ARRAY_SIZE(trigger), "%s\n", tevent->trigger);
debug_msg("Enabling %s:%s trigger %s\n", tevent->system,
tevent->event ? : "*", tevent->trigger);
--
2.52.0
^ permalink raw reply related
* [PATCH v2 09/18] rtla: Remove redundant memset after calloc
From: Wander Lairson Costa @ 2026-01-06 11:49 UTC (permalink / raw)
To: Steven Rostedt, Tomas Glozar, Wander Lairson Costa, Crystal Wood,
Ivan Pravdin, Costa Shulyupin, John Kacur, Tiezhu Yang,
open list:Real-time Linux Analysis (RTLA) tools,
open list:Real-time Linux Analysis (RTLA) tools,
open list:BPF [MISC]:Keyword:(?:b|_)bpf(?:b|_)
In-Reply-To: <20260106133655.249887-1-wander@redhat.com>
The actions struct is allocated using calloc, which already returns
zeroed memory. The subsequent memset call to zero the 'present' member
is therefore redundant.
Signed-off-by: Wander Lairson Costa <wander@redhat.com>
---
tools/tracing/rtla/src/actions.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/tools/tracing/rtla/src/actions.c b/tools/tracing/rtla/src/actions.c
index b50bf9f9adf28..00bbc94dec1bd 100644
--- a/tools/tracing/rtla/src/actions.c
+++ b/tools/tracing/rtla/src/actions.c
@@ -19,8 +19,6 @@ actions_init(struct actions *self)
self->len = 0;
self->continue_flag = false;
- memset(&self->present, 0, sizeof(self->present));
-
/* This has to be set by the user */
self->trace_output_inst = NULL;
}
--
2.52.0
^ permalink raw reply related
* [PATCH v2 08/18] rtla: Use standard exit codes for result enum
From: Wander Lairson Costa @ 2026-01-06 11:49 UTC (permalink / raw)
To: Steven Rostedt, Tomas Glozar, Wander Lairson Costa, Ivan Pravdin,
Crystal Wood, Costa Shulyupin, John Kacur, Tiezhu Yang,
open list:Real-time Linux Analysis (RTLA) tools,
open list:Real-time Linux Analysis (RTLA) tools,
open list:BPF [MISC]:Keyword:(?:b|_)bpf(?:b|_)
In-Reply-To: <20260106133655.249887-1-wander@redhat.com>
The result enum defines custom values for PASSED, ERROR, and FAILED.
These values correspond to standard exit codes EXIT_SUCCESS and
EXIT_FAILURE.
Update the enum to use the standard macros EXIT_SUCCESS and
EXIT_FAILURE to improve readability and adherence to standard C
practices.
The FAILED value is implicitly assigned EXIT_FAILURE + 1, so there
is no need to assign an explicit value.
Signed-off-by: Wander Lairson Costa <wander@redhat.com>
---
tools/tracing/rtla/src/utils.h | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/tools/tracing/rtla/src/utils.h b/tools/tracing/rtla/src/utils.h
index 7fa3ac5e0bfb6..5286a4c7165d3 100644
--- a/tools/tracing/rtla/src/utils.h
+++ b/tools/tracing/rtla/src/utils.h
@@ -4,6 +4,7 @@
#include <time.h>
#include <sched.h>
#include <stdbool.h>
+#include <stdlib.h>
/*
* '18446744073709551615\0'
@@ -102,7 +103,7 @@ __attribute__((__warn_unused_result__)) int strtoi(const char *s, int *res);
#define ns_to_per(total, part) ((part * 100) / (double)total)
enum result {
- PASSED = 0, /* same as EXIT_SUCCESS */
- ERROR = 1, /* same as EXIT_FAILURE, an error in arguments */
- FAILED = 2, /* test hit the stop tracing condition */
+ PASSED = EXIT_SUCCESS,
+ ERROR = EXIT_FAILURE,
+ FAILED, /* test hit the stop tracing condition */
};
--
2.52.0
^ permalink raw reply related
* [PATCH v2 07/18] rtla: Introduce common_restart() helper
From: Wander Lairson Costa @ 2026-01-06 11:49 UTC (permalink / raw)
To: Steven Rostedt, Tomas Glozar, Wander Lairson Costa, Crystal Wood,
Ivan Pravdin, Costa Shulyupin, John Kacur, Tiezhu Yang,
open list:Real-time Linux Analysis (RTLA) tools,
open list:Real-time Linux Analysis (RTLA) tools,
open list:BPF [MISC]:Keyword:(?:b|_)bpf(?:b|_)
In-Reply-To: <20260106133655.249887-1-wander@redhat.com>
A few functions duplicate the logic for handling threshold actions.
When a threshold is reached, these functions stop the trace, perform
actions, and restart the trace if configured to continue.
Create a new helper function, common_restart(), to centralize this
shared logic and avoid code duplication. This function now handles the
threshold actions and restarts the necessary trace instances.
Refactor the affected functions main loops to call the new helper.
This makes the code cleaner and more maintainable.
Signed-off-by: Wander Lairson Costa <wander@redhat.com>
---
tools/tracing/rtla/src/common.c | 65 +++++++++++++++++++-------
tools/tracing/rtla/src/common.h | 9 ++++
tools/tracing/rtla/src/timerlat_hist.c | 20 ++++----
tools/tracing/rtla/src/timerlat_top.c | 20 ++++----
4 files changed, 78 insertions(+), 36 deletions(-)
diff --git a/tools/tracing/rtla/src/common.c b/tools/tracing/rtla/src/common.c
index b197037fc58b3..d608ffe12e7b0 100644
--- a/tools/tracing/rtla/src/common.c
+++ b/tools/tracing/rtla/src/common.c
@@ -95,6 +95,37 @@ common_apply_config(struct osnoise_tool *tool, struct common_params *params)
}
+/**
+ * common_restart - handle threshold actions and optionally restart tracing
+ * @tool: pointer to the osnoise_tool instance containing trace contexts
+ * @params: timerlat parameters with threshold action configuration
+ *
+ * Return:
+ * RESTART_OK - Actions executed successfully and tracing restarted
+ * RESTART_STOP - Actions executed but 'continue' flag not set, stop tracing
+ * RESTART_ERROR - Failed to restart tracing after executing actions
+ */
+enum restart_result
+common_restart(const struct osnoise_tool *tool, struct common_params *params)
+{
+ actions_perform(¶ms->threshold_actions);
+
+ if (!params->threshold_actions.continue_flag)
+ /* continue flag not set, break */
+ return RESTART_STOP;
+
+ /* continue action reached, re-enable tracing */
+ if (tool->record && trace_instance_start(&tool->record->trace))
+ goto err;
+ if (tool->aa && trace_instance_start(&tool->aa->trace))
+ goto err;
+ return RESTART_OK;
+
+err:
+ err_msg("Error restarting trace\n");
+ return RESTART_ERROR;
+}
+
int run_tool(struct tool_ops *ops, int argc, char *argv[])
{
struct common_params *params;
@@ -272,17 +303,16 @@ int top_main_loop(struct osnoise_tool *tool)
/* stop tracing requested, do not perform actions */
return 0;
- actions_perform(¶ms->threshold_actions);
+ enum restart_result result;
+
+ result = common_restart(tool, params);
- if (!params->threshold_actions.continue_flag)
- /* continue flag not set, break */
+ if (result == RESTART_STOP)
return 0;
- /* continue action reached, re-enable tracing */
- if (record)
- trace_instance_start(&record->trace);
- if (tool->aa)
- trace_instance_start(&tool->aa->trace);
+ if (result == RESTART_ERROR)
+ return -1;
+
trace_instance_start(trace);
}
@@ -323,18 +353,17 @@ int hist_main_loop(struct osnoise_tool *tool)
/* stop tracing requested, do not perform actions */
break;
- actions_perform(¶ms->threshold_actions);
+ enum restart_result result;
- if (!params->threshold_actions.continue_flag)
- /* continue flag not set, break */
- break;
+ result = common_restart(tool, params);
+
+ if (result == RESTART_STOP)
+ return 0;
- /* continue action reached, re-enable tracing */
- if (tool->record)
- trace_instance_start(&tool->record->trace);
- if (tool->aa)
- trace_instance_start(&tool->aa->trace);
- trace_instance_start(&tool->trace);
+ if (result == RESTART_ERROR)
+ return -1;
+
+ trace_instance_start(trace);
}
/* is there still any user-threads ? */
diff --git a/tools/tracing/rtla/src/common.h b/tools/tracing/rtla/src/common.h
index 9ec2b7632c376..f2c9e21c03651 100644
--- a/tools/tracing/rtla/src/common.h
+++ b/tools/tracing/rtla/src/common.h
@@ -143,6 +143,15 @@ struct tool_ops {
void (*free)(struct osnoise_tool *tool);
};
+enum restart_result {
+ RESTART_OK,
+ RESTART_STOP,
+ RESTART_ERROR = -1,
+};
+
+enum restart_result
+common_restart(const struct osnoise_tool *tool, struct common_params *params);
+
int osnoise_set_cpus(struct osnoise_context *context, char *cpus);
void osnoise_restore_cpus(struct osnoise_context *context);
diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c
index 226167c88c8d6..27fc98270da59 100644
--- a/tools/tracing/rtla/src/timerlat_hist.c
+++ b/tools/tracing/rtla/src/timerlat_hist.c
@@ -17,6 +17,7 @@
#include "timerlat.h"
#include "timerlat_aa.h"
#include "timerlat_bpf.h"
+#include "common.h"
struct timerlat_hist_cpu {
int *irq;
@@ -1100,18 +1101,19 @@ static int timerlat_hist_bpf_main_loop(struct osnoise_tool *tool)
if (!stop_tracing) {
/* Threshold overflow, perform actions on threshold */
- actions_perform(¶ms->common.threshold_actions);
+ enum restart_result result;
- if (!params->common.threshold_actions.continue_flag)
- /* continue flag not set, break */
+ result = common_restart(tool, ¶ms->common);
+ if (result == RESTART_STOP)
break;
- /* continue action reached, re-enable tracing */
- if (tool->record)
- trace_instance_start(&tool->record->trace);
- if (tool->aa)
- trace_instance_start(&tool->aa->trace);
- timerlat_bpf_restart_tracing();
+ if (result == RESTART_ERROR)
+ return -1;
+
+ if (timerlat_bpf_restart_tracing()) {
+ err_msg("Error restarting BPF trace\n");
+ return -1;
+ }
}
}
timerlat_bpf_detach();
diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c
index 31e1514a2528d..f7e85dc918ef3 100644
--- a/tools/tracing/rtla/src/timerlat_top.c
+++ b/tools/tracing/rtla/src/timerlat_top.c
@@ -18,6 +18,7 @@
#include "timerlat.h"
#include "timerlat_aa.h"
#include "timerlat_bpf.h"
+#include "common.h"
struct timerlat_top_cpu {
unsigned long long irq_count;
@@ -869,18 +870,19 @@ timerlat_top_bpf_main_loop(struct osnoise_tool *tool)
if (wait_retval != 0) {
/* Stopping requested by tracer */
- actions_perform(¶ms->common.threshold_actions);
+ enum restart_result result;
- if (!params->common.threshold_actions.continue_flag)
- /* continue flag not set, break */
+ result = common_restart(tool, ¶ms->common);
+ if (result == RESTART_STOP)
break;
- /* continue action reached, re-enable tracing */
- if (tool->record)
- trace_instance_start(&tool->record->trace);
- if (tool->aa)
- trace_instance_start(&tool->aa->trace);
- timerlat_bpf_restart_tracing();
+ if (result == RESTART_ERROR)
+ return -1;
+
+ if (timerlat_bpf_restart_tracing()) {
+ err_msg("Error restarting BPF trace\n");
+ return -1;
+ }
}
/* is there still any user-threads ? */
--
2.52.0
^ permalink raw reply related
* [PATCH v2 06/18] rtla: Use strncmp_static() in more places
From: Wander Lairson Costa @ 2026-01-06 11:49 UTC (permalink / raw)
To: Steven Rostedt, Tomas Glozar, Wander Lairson Costa, Crystal Wood,
Ivan Pravdin, Costa Shulyupin, John Kacur, Tiezhu Yang,
open list:Real-time Linux Analysis (RTLA) tools,
open list:Real-time Linux Analysis (RTLA) tools,
open list:BPF [MISC]:Keyword:(?:b|_)bpf(?:b|_)
In-Reply-To: <20260106133655.249887-1-wander@redhat.com>
The recently introduced strncmp_static() helper provides a safer way
to compare strings with static strings by determining the length at
compile time.
Replace several open-coded strncmp() calls with strncmp_static() to
improve code readability and robustness. This change affects the
parsing of command-line arguments and environment variables.
Signed-off-by: Wander Lairson Costa <wander@redhat.com>
---
tools/tracing/rtla/src/osnoise.c | 2 +-
tools/tracing/rtla/src/timerlat.c | 4 ++--
tools/tracing/rtla/src/trace.c | 2 +-
tools/tracing/rtla/src/utils.c | 8 ++++----
4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/tools/tracing/rtla/src/osnoise.c b/tools/tracing/rtla/src/osnoise.c
index c5b41ec26b0a4..f2ec2da7b6d3a 100644
--- a/tools/tracing/rtla/src/osnoise.c
+++ b/tools/tracing/rtla/src/osnoise.c
@@ -1219,7 +1219,7 @@ int osnoise_main(int argc, char *argv[])
if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0)) {
osnoise_usage(0);
- } else if (strncmp(argv[1], "-", 1) == 0) {
+ } else if (strncmp_static(argv[1], "-") == 0) {
/* the user skipped the tool, call the default one */
run_tool(&osnoise_top_ops, argc, argv);
exit(0);
diff --git a/tools/tracing/rtla/src/timerlat.c b/tools/tracing/rtla/src/timerlat.c
index df4f9bfe34331..ac2ec89d3b6ba 100644
--- a/tools/tracing/rtla/src/timerlat.c
+++ b/tools/tracing/rtla/src/timerlat.c
@@ -34,7 +34,7 @@ timerlat_apply_config(struct osnoise_tool *tool, struct timerlat_params *params)
* Try to enable BPF, unless disabled explicitly.
* If BPF enablement fails, fall back to tracefs mode.
*/
- if (getenv("RTLA_NO_BPF") && strncmp(getenv("RTLA_NO_BPF"), "1", 2) == 0) {
+ if (getenv("RTLA_NO_BPF") && strncmp_static(getenv("RTLA_NO_BPF"), "1") == 0) {
debug_msg("RTLA_NO_BPF set, disabling BPF\n");
params->mode = TRACING_MODE_TRACEFS;
} else if (!tep_find_event_by_name(tool->trace.tep, "osnoise", "timerlat_sample")) {
@@ -271,7 +271,7 @@ int timerlat_main(int argc, char *argv[])
if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0)) {
timerlat_usage(0);
- } else if (strncmp(argv[1], "-", 1) == 0) {
+ } else if (strncmp_static(argv[1], "-") == 0) {
/* the user skipped the tool, call the default one */
run_tool(&timerlat_top_ops, argc, argv);
exit(0);
diff --git a/tools/tracing/rtla/src/trace.c b/tools/tracing/rtla/src/trace.c
index b22bb844b71f3..45328c5121f79 100644
--- a/tools/tracing/rtla/src/trace.c
+++ b/tools/tracing/rtla/src/trace.c
@@ -356,7 +356,7 @@ static void trace_event_save_hist(struct trace_instance *instance,
return;
/* is this a hist: trigger? */
- retval = strncmp(tevent->trigger, "hist:", strlen("hist:"));
+ retval = strncmp_static(tevent->trigger, "hist:");
if (retval)
return;
diff --git a/tools/tracing/rtla/src/utils.c b/tools/tracing/rtla/src/utils.c
index f3e129d17a82b..e0f31e5cae844 100644
--- a/tools/tracing/rtla/src/utils.c
+++ b/tools/tracing/rtla/src/utils.c
@@ -211,15 +211,15 @@ long parse_ns_duration(char *val)
t = strtol(val, &end, 10);
if (end) {
- if (!strncmp(end, "ns", 2)) {
+ if (!strncmp_static(end, "ns")) {
return t;
- } else if (!strncmp(end, "us", 2)) {
+ } else if (!strncmp_static(end, "us")) {
t *= 1000;
return t;
- } else if (!strncmp(end, "ms", 2)) {
+ } else if (!strncmp_static(end, "ms")) {
t *= 1000 * 1000;
return t;
- } else if (!strncmp(end, "s", 1)) {
+ } else if (!strncmp_static(end, "s")) {
t *= 1000 * 1000 * 1000;
return t;
}
--
2.52.0
^ permalink raw reply related
* [PATCH v2 05/18] rtla: Simplify argument parsing
From: Wander Lairson Costa @ 2026-01-06 11:49 UTC (permalink / raw)
To: Steven Rostedt, Tomas Glozar, Wander Lairson Costa, Ivan Pravdin,
Crystal Wood, Costa Shulyupin, John Kacur, Tiezhu Yang,
open list:Real-time Linux Analysis (RTLA) tools,
open list:Real-time Linux Analysis (RTLA) tools,
open list:BPF [MISC]:Keyword:(?:b|_)bpf(?:b|_)
In-Reply-To: <20260106133655.249887-1-wander@redhat.com>
The actions_parse() function uses open-coded logic to extract arguments
from a string. This includes manual length checks and strncmp() calls,
which can be verbose and error-prone.
To simplify and improve the robustness of argument parsing, introduce a
new extract_arg() helper macro. This macro extracts the value from a
"key=value" pair, making the code more concise and readable.
Also, introduce STRING_LENGTH() and strncmp_static() macros to
perform compile-time calculations of string lengths and safer string
comparisons.
Refactor actions_parse() to use these new helpers, resulting in
cleaner and more maintainable code.
Signed-off-by: Wander Lairson Costa <wander@redhat.com>
---
tools/tracing/rtla/src/actions.c | 57 +++++++++++++++++++++++---------
tools/tracing/rtla/src/utils.h | 14 ++++++--
2 files changed, 54 insertions(+), 17 deletions(-)
diff --git a/tools/tracing/rtla/src/actions.c b/tools/tracing/rtla/src/actions.c
index e933c2c68b208..b50bf9f9adf28 100644
--- a/tools/tracing/rtla/src/actions.c
+++ b/tools/tracing/rtla/src/actions.c
@@ -113,6 +113,29 @@ actions_add_continue(struct actions *self)
action->type = ACTION_CONTINUE;
}
+static inline const char *__extract_arg(const char *token, const char *opt, size_t opt_len)
+{
+ const size_t tok_len = strlen(token);
+
+ if (tok_len <= opt_len)
+ return NULL;
+
+ if (strncmp(token, opt, opt_len))
+ return NULL;
+
+ return token + opt_len;
+}
+
+/*
+ * extract_arg - extract argument value from option token
+ * @token: option token (e.g., "file=trace.txt")
+ * @opt: option name to match (e.g., "file")
+ *
+ * Returns pointer to argument value after "=" if token matches "opt=",
+ * otherwise returns NULL.
+ */
+#define extract_arg(token, opt) __extract_arg(token, opt "=", STRING_LENGTH(opt "="))
+
/*
* actions_parse - add an action based on text specification
*/
@@ -122,6 +145,7 @@ actions_parse(struct actions *self, const char *trigger, const char *tracefn)
enum action_type type = ACTION_NONE;
const char *token;
char trigger_c[strlen(trigger) + 1];
+ const char *arg_value;
/* For ACTION_SIGNAL */
int signal = 0, pid = 0;
@@ -152,12 +176,10 @@ actions_parse(struct actions *self, const char *trigger, const char *tracefn)
if (token == NULL)
trace_output = tracefn;
else {
- if (strlen(token) > 5 && strncmp(token, "file=", 5) == 0) {
- trace_output = token + 5;
- } else {
+ trace_output = extract_arg(token, "file");
+ if (!trace_output)
/* Invalid argument */
return -1;
- }
token = strtok(NULL, ",");
if (token != NULL)
@@ -169,17 +191,21 @@ actions_parse(struct actions *self, const char *trigger, const char *tracefn)
case ACTION_SIGNAL:
/* Takes two arguments, num (signal) and pid */
while (token != NULL) {
- if (strlen(token) > 4 && strncmp(token, "num=", 4) == 0) {
- if (strtoi(token + 4, &signal))
- return -1;
- } else if (strlen(token) > 4 && strncmp(token, "pid=", 4) == 0) {
- if (strncmp(token + 4, "parent", 7) == 0)
- pid = -1;
- else if (strtoi(token + 4, &pid))
+ arg_value = extract_arg(token, "num");
+ if (arg_value) {
+ if (strtoi(arg_value, &signal))
return -1;
} else {
- /* Invalid argument */
- return -1;
+ arg_value = extract_arg(token, "pid");
+ if (arg_value) {
+ if (strncmp_static(arg_value, "parent") == 0)
+ pid = -1;
+ else if (strtoi(arg_value, &pid))
+ return -1;
+ } else {
+ /* Invalid argument */
+ return -1;
+ }
}
token = strtok(NULL, ",");
@@ -194,9 +220,10 @@ actions_parse(struct actions *self, const char *trigger, const char *tracefn)
case ACTION_SHELL:
if (token == NULL)
return -1;
- if (strlen(token) > 8 && strncmp(token, "command=", 8))
+ arg_value = extract_arg(token, "command");
+ if (!arg_value)
return -1;
- actions_add_shell(self, token + 8);
+ actions_add_shell(self, arg_value);
break;
case ACTION_CONTINUE:
/* Takes no argument */
diff --git a/tools/tracing/rtla/src/utils.h b/tools/tracing/rtla/src/utils.h
index efbf798650306..7fa3ac5e0bfb6 100644
--- a/tools/tracing/rtla/src/utils.h
+++ b/tools/tracing/rtla/src/utils.h
@@ -13,8 +13,18 @@
#define MAX_NICE 20
#define MIN_NICE -19
-#define container_of(ptr, type, member)({ \
- const typeof(((type *)0)->member) *__mptr = (ptr); \
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
+#endif
+
+/* Calculate string length at compile time (excluding null terminator) */
+#define STRING_LENGTH(s) (ARRAY_SIZE(s) - sizeof(*(s)))
+
+/* Compare string with static string, length determined at compile time */
+#define strncmp_static(s1, s2) strncmp(s1, s2, STRING_LENGTH(s2))
+
+#define container_of(ptr, type, member)({ \
+ const typeof(((type *)0)->member) * __mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member)) ; })
extern int config_debug;
--
2.52.0
^ permalink raw reply related
* [PATCH v2 04/18] rtla: Replace atoi() with a robust strtoi()
From: Wander Lairson Costa @ 2026-01-06 11:49 UTC (permalink / raw)
To: Steven Rostedt, Tomas Glozar, Wander Lairson Costa, Ivan Pravdin,
Crystal Wood, Costa Shulyupin, John Kacur, Tiezhu Yang,
open list:Real-time Linux Analysis (RTLA) tools,
open list:Real-time Linux Analysis (RTLA) tools,
open list:BPF [MISC]:Keyword:(?:b|_)bpf(?:b|_)
In-Reply-To: <20260106133655.249887-1-wander@redhat.com>
The atoi() function does not perform error checking, which can lead to
undefined behavior when parsing invalid or out-of-range strings. This
can cause issues when parsing user-provided numerical inputs, such as
signal numbers, PIDs, or CPU lists.
To address this, introduce a new strtoi() helper function that safely
converts a string to an integer. This function validates the input and
checks for overflows, returning a negative value on failure.
Replace all calls to atoi() with the new strtoi() function and add
proper error handling to make the parsing more robust and prevent
potential issues.
Signed-off-by: Wander Lairson Costa <wander@redhat.com>
---
tools/tracing/rtla/src/actions.c | 7 +++---
tools/tracing/rtla/src/utils.c | 40 ++++++++++++++++++++++++++++----
tools/tracing/rtla/src/utils.h | 2 ++
3 files changed, 41 insertions(+), 8 deletions(-)
diff --git a/tools/tracing/rtla/src/actions.c b/tools/tracing/rtla/src/actions.c
index a4d0dc47e6aa1..e933c2c68b208 100644
--- a/tools/tracing/rtla/src/actions.c
+++ b/tools/tracing/rtla/src/actions.c
@@ -170,12 +170,13 @@ actions_parse(struct actions *self, const char *trigger, const char *tracefn)
/* Takes two arguments, num (signal) and pid */
while (token != NULL) {
if (strlen(token) > 4 && strncmp(token, "num=", 4) == 0) {
- signal = atoi(token + 4);
+ if (strtoi(token + 4, &signal))
+ return -1;
} else if (strlen(token) > 4 && strncmp(token, "pid=", 4) == 0) {
if (strncmp(token + 4, "parent", 7) == 0)
pid = -1;
- else
- pid = atoi(token + 4);
+ else if (strtoi(token + 4, &pid))
+ return -1;
} else {
/* Invalid argument */
return -1;
diff --git a/tools/tracing/rtla/src/utils.c b/tools/tracing/rtla/src/utils.c
index acf95afa25b5a..f3e129d17a82b 100644
--- a/tools/tracing/rtla/src/utils.c
+++ b/tools/tracing/rtla/src/utils.c
@@ -17,6 +17,7 @@
#include <fcntl.h>
#include <sched.h>
#include <stdio.h>
+#include <limits.h>
#include "utils.h"
@@ -127,16 +128,18 @@ int parse_cpu_set(char *cpu_list, cpu_set_t *set)
nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
for (p = cpu_list; *p; ) {
- cpu = atoi(p);
- if (cpu < 0 || (!cpu && *p != '0') || cpu >= nr_cpus)
+ if (strtoi(p, &cpu))
+ goto err;
+ if (cpu < 0 || cpu >= nr_cpus)
goto err;
while (isdigit(*p))
p++;
if (*p == '-') {
p++;
- end_cpu = atoi(p);
- if (end_cpu < cpu || (!end_cpu && *p != '0') || end_cpu >= nr_cpus)
+ if (strtoi(p, &end_cpu))
+ goto err;
+ if (end_cpu < cpu || end_cpu >= nr_cpus)
goto err;
while (isdigit(*p))
p++;
@@ -337,6 +340,7 @@ int set_comm_sched_attr(const char *comm_prefix, struct sched_attr *attr)
struct dirent *proc_entry;
DIR *procfs;
int retval;
+ int pid;
if (strlen(comm_prefix) >= MAX_PATH) {
err_msg("Command prefix is too long: %d < strlen(%s)\n",
@@ -356,8 +360,12 @@ int set_comm_sched_attr(const char *comm_prefix, struct sched_attr *attr)
if (!retval)
continue;
+ if (strtoi(proc_entry->d_name, &pid)) {
+ err_msg("'%s' is not a valid pid", proc_entry->d_name);
+ goto out_err;
+ }
/* procfs_is_workload_pid confirmed it is a pid */
- retval = __set_sched_attr(atoi(proc_entry->d_name), attr);
+ retval = __set_sched_attr(pid, attr);
if (retval) {
err_msg("Error setting sched attributes for pid:%s\n", proc_entry->d_name);
goto out_err;
@@ -1035,3 +1043,25 @@ char *strdup_fatal(const char *s)
return p;
}
+
+/*
+ * strtoi - convert string to integer with error checking
+ *
+ * Returns 0 on success, -1 if conversion fails or result is out of int range.
+ */
+int strtoi(const char *s, int *res)
+{
+ char *end_ptr;
+ long lres;
+
+ if (!*s)
+ return -1;
+
+ errno = 0;
+ lres = strtol(s, &end_ptr, 0);
+ if (errno || *end_ptr || lres > INT_MAX || lres < INT_MIN)
+ return -1;
+
+ *res = (int) lres;
+ return 0;
+}
diff --git a/tools/tracing/rtla/src/utils.h b/tools/tracing/rtla/src/utils.h
index 0ed2c7275f2c5..efbf798650306 100644
--- a/tools/tracing/rtla/src/utils.h
+++ b/tools/tracing/rtla/src/utils.h
@@ -3,6 +3,7 @@
#include <stdint.h>
#include <time.h>
#include <sched.h>
+#include <stdbool.h>
/*
* '18446744073709551615\0'
@@ -85,6 +86,7 @@ static inline int set_deepest_cpu_idle_state(unsigned int cpu, unsigned int stat
static inline int have_libcpupower_support(void) { return 0; }
#endif /* HAVE_LIBCPUPOWER_SUPPORT */
int auto_house_keeping(cpu_set_t *monitored_cpus);
+__attribute__((__warn_unused_result__)) int strtoi(const char *s, int *res);
#define ns_to_usf(x) (((double)x/1000))
#define ns_to_per(total, part) ((part * 100) / (double)total)
--
2.52.0
^ permalink raw reply related
* [PATCH v2 03/18] rtla: Introduce for_each_action() helper
From: Wander Lairson Costa @ 2026-01-06 11:49 UTC (permalink / raw)
To: Steven Rostedt, Tomas Glozar, Wander Lairson Costa, Crystal Wood,
Ivan Pravdin, Costa Shulyupin, John Kacur, Tiezhu Yang,
open list:Real-time Linux Analysis (RTLA) tools,
open list:Real-time Linux Analysis (RTLA) tools,
open list:BPF [MISC]:Keyword:(?:b|_)bpf(?:b|_)
In-Reply-To: <20260106133655.249887-1-wander@redhat.com>
The for loop to iterate over the list of actions is used in
more than one place. To avoid code duplication and improve
readability, introduce a for_each_action() helper macro.
Replace the open-coded for loops with the new helper.
Signed-off-by: Wander Lairson Costa <wander@redhat.com>
---
tools/tracing/rtla/src/actions.c | 6 ++++--
tools/tracing/rtla/src/actions.h | 5 +++++
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/tools/tracing/rtla/src/actions.c b/tools/tracing/rtla/src/actions.c
index 090d514fe4126..a4d0dc47e6aa1 100644
--- a/tools/tracing/rtla/src/actions.c
+++ b/tools/tracing/rtla/src/actions.c
@@ -32,7 +32,9 @@ void
actions_destroy(struct actions *self)
{
/* Free any action-specific data */
- for (struct action *action = self->list; action < self->list + self->len; action++) {
+ struct action *action;
+
+ for_each_action(self, action) {
if (action->type == ACTION_SHELL)
free(action->command);
if (action->type == ACTION_TRACE_OUTPUT)
@@ -217,7 +219,7 @@ actions_perform(struct actions *self)
int pid, retval;
const struct action *action;
- for (action = self->list; action < self->list + self->len; action++) {
+ for_each_action(self, action) {
switch (action->type) {
case ACTION_TRACE_OUTPUT:
retval = save_trace_to_file(self->trace_output_inst, action->trace_output);
diff --git a/tools/tracing/rtla/src/actions.h b/tools/tracing/rtla/src/actions.h
index fb366d6509b8b..034048682fefb 100644
--- a/tools/tracing/rtla/src/actions.h
+++ b/tools/tracing/rtla/src/actions.h
@@ -42,6 +42,11 @@ struct actions {
struct tracefs_instance *trace_output_inst;
};
+#define for_each_action(actions, action) \
+ for ((action) = (actions)->list; \
+ (action) < (actions)->list + (actions)->len; \
+ (action)++)
+
void actions_init(struct actions *self);
void actions_destroy(struct actions *self);
void actions_add_trace_output(struct actions *self, const char *trace_output);
--
2.52.0
^ permalink raw reply related
* [PATCH v2 02/18] rtla: Use strdup() to simplify code
From: Wander Lairson Costa @ 2026-01-06 11:49 UTC (permalink / raw)
To: Steven Rostedt, Tomas Glozar, Wander Lairson Costa, Ivan Pravdin,
Crystal Wood, Costa Shulyupin, John Kacur, Tiezhu Yang,
open list:Real-time Linux Analysis (RTLA) tools,
open list:Real-time Linux Analysis (RTLA) tools,
open list:BPF [MISC]:Keyword:(?:b|_)bpf(?:b|_)
In-Reply-To: <20260106133655.249887-1-wander@redhat.com>
The actions_add_trace_output() and actions_add_shell() functions were
using calloc() followed by strcpy() to allocate and copy a string.
This can be simplified by using strdup(), which allocates memory and
copies the string in a single step.
Replace the calloc() and strcpy() calls with strdup(), making the
code more concise and readable.
Signed-off-by: Wander Lairson Costa <wander@redhat.com>
---
tools/tracing/rtla/src/actions.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/tools/tracing/rtla/src/actions.c b/tools/tracing/rtla/src/actions.c
index ff7811e175930..090d514fe4126 100644
--- a/tools/tracing/rtla/src/actions.c
+++ b/tools/tracing/rtla/src/actions.c
@@ -69,8 +69,7 @@ actions_add_trace_output(struct actions *self, const char *trace_output)
self->present[ACTION_TRACE_OUTPUT] = true;
action->type = ACTION_TRACE_OUTPUT;
- action->trace_output = calloc_fatal(strlen(trace_output) + 1, sizeof(char));
- strcpy(action->trace_output, trace_output);
+ action->trace_output = strdup_fatal(trace_output);
}
/*
@@ -97,8 +96,7 @@ actions_add_shell(struct actions *self, const char *command)
self->present[ACTION_SHELL] = true;
action->type = ACTION_SHELL;
- action->command = calloc_fatal(strlen(command) + 1, sizeof(char));
- strcpy(action->command, command);
+ action->command = strdup_fatal(command);
}
/*
--
2.52.0
^ permalink raw reply related
* [PATCH v2 01/18] rtla: Exit on memory allocation failures during initialization
From: Wander Lairson Costa @ 2026-01-06 11:49 UTC (permalink / raw)
To: Steven Rostedt, Tomas Glozar, Wander Lairson Costa, Crystal Wood,
Ivan Pravdin, Costa Shulyupin, John Kacur, Tiezhu Yang,
open list:Real-time Linux Analysis (RTLA) tools,
open list:Real-time Linux Analysis (RTLA) tools,
open list:BPF [MISC]:Keyword:(?:b|_)bpf(?:b|_)
In-Reply-To: <20260106133655.249887-1-wander@redhat.com>
Most memory allocations in rtla happen during early initialization
before any resources are acquired that would require cleanup. In these
cases, propagating allocation errors just adds complexity without any
benefit. There's nothing to clean up, and the program must exit anyway.
This patch introduces fatal allocation wrappers (calloc_fatal,
reallocarray_fatal, strdup_fatal) that call fatal() on allocation
failure. These wrappers simplify the code by eliminating unnecessary
error propagation paths.
The patch converts early allocations to use these wrappers in
actions_init() and related action functions, osnoise_context_alloc()
and osnoise_init_tool(), trace_instance_init() and trace event
functions, and parameter structure allocations in main functions.
This simplifies the code while maintaining the same behavior: immediate
exit on allocation failure during initialization. Allocations that
require cleanup, such as those in histogram allocation functions with
goto cleanup paths, are left unchanged and continue to return errors.
Signed-off-by: Wander Lairson Costa <wander@redhat.com>
---
tools/tracing/rtla/src/actions.c | 50 ++++++++++++--------------
tools/tracing/rtla/src/actions.h | 8 ++---
tools/tracing/rtla/src/osnoise.c | 22 ++++--------
tools/tracing/rtla/src/osnoise_hist.c | 25 ++++---------
tools/tracing/rtla/src/osnoise_top.c | 25 ++++---------
tools/tracing/rtla/src/timerlat_hist.c | 24 ++++---------
tools/tracing/rtla/src/timerlat_top.c | 25 ++++---------
tools/tracing/rtla/src/trace.c | 30 ++++------------
tools/tracing/rtla/src/trace.h | 4 +--
tools/tracing/rtla/src/utils.c | 35 ++++++++++++++++++
tools/tracing/rtla/src/utils.h | 3 ++
11 files changed, 108 insertions(+), 143 deletions(-)
diff --git a/tools/tracing/rtla/src/actions.c b/tools/tracing/rtla/src/actions.c
index 8945aee58d511..ff7811e175930 100644
--- a/tools/tracing/rtla/src/actions.c
+++ b/tools/tracing/rtla/src/actions.c
@@ -15,7 +15,7 @@ void
actions_init(struct actions *self)
{
self->size = action_default_size;
- self->list = calloc(self->size, sizeof(struct action));
+ self->list = calloc_fatal(self->size, sizeof(struct action));
self->len = 0;
self->continue_flag = false;
@@ -50,8 +50,10 @@ static struct action *
actions_new(struct actions *self)
{
if (self->len >= self->size) {
- self->size *= 2;
- self->list = realloc(self->list, self->size * sizeof(struct action));
+ const size_t new_size = self->size * 2;
+
+ self->list = reallocarray_fatal(self->list, new_size, sizeof(struct action));
+ self->size = new_size;
}
return &self->list[self->len++];
@@ -60,25 +62,21 @@ actions_new(struct actions *self)
/*
* actions_add_trace_output - add an action to output trace
*/
-int
+void
actions_add_trace_output(struct actions *self, const char *trace_output)
{
struct action *action = actions_new(self);
self->present[ACTION_TRACE_OUTPUT] = true;
action->type = ACTION_TRACE_OUTPUT;
- action->trace_output = calloc(strlen(trace_output) + 1, sizeof(char));
- if (!action->trace_output)
- return -1;
+ action->trace_output = calloc_fatal(strlen(trace_output) + 1, sizeof(char));
strcpy(action->trace_output, trace_output);
-
- return 0;
}
/*
* actions_add_trace_output - add an action to send signal to a process
*/
-int
+void
actions_add_signal(struct actions *self, int signal, int pid)
{
struct action *action = actions_new(self);
@@ -87,40 +85,32 @@ actions_add_signal(struct actions *self, int signal, int pid)
action->type = ACTION_SIGNAL;
action->signal = signal;
action->pid = pid;
-
- return 0;
}
/*
* actions_add_shell - add an action to execute a shell command
*/
-int
+void
actions_add_shell(struct actions *self, const char *command)
{
struct action *action = actions_new(self);
self->present[ACTION_SHELL] = true;
action->type = ACTION_SHELL;
- action->command = calloc(strlen(command) + 1, sizeof(char));
- if (!action->command)
- return -1;
+ action->command = calloc_fatal(strlen(command) + 1, sizeof(char));
strcpy(action->command, command);
-
- return 0;
}
/*
* actions_add_continue - add an action to resume measurement
*/
-int
+void
actions_add_continue(struct actions *self)
{
struct action *action = actions_new(self);
self->present[ACTION_CONTINUE] = true;
action->type = ACTION_CONTINUE;
-
- return 0;
}
/*
@@ -174,7 +164,8 @@ actions_parse(struct actions *self, const char *trigger, const char *tracefn)
/* Only one argument allowed */
return -1;
}
- return actions_add_trace_output(self, trace_output);
+ actions_add_trace_output(self, trace_output);
+ break;
case ACTION_SIGNAL:
/* Takes two arguments, num (signal) and pid */
while (token != NULL) {
@@ -197,21 +188,26 @@ actions_parse(struct actions *self, const char *trigger, const char *tracefn)
/* Missing argument */
return -1;
- return actions_add_signal(self, signal, pid);
+ actions_add_signal(self, signal, pid);
+ break;
case ACTION_SHELL:
if (token == NULL)
return -1;
- if (strlen(token) > 8 && strncmp(token, "command=", 8) == 0)
- return actions_add_shell(self, token + 8);
- return -1;
+ if (strlen(token) > 8 && strncmp(token, "command=", 8))
+ return -1;
+ actions_add_shell(self, token + 8);
+ break;
case ACTION_CONTINUE:
/* Takes no argument */
if (token != NULL)
return -1;
- return actions_add_continue(self);
+ actions_add_continue(self);
+ break;
default:
return -1;
}
+
+ return 0;
}
/*
diff --git a/tools/tracing/rtla/src/actions.h b/tools/tracing/rtla/src/actions.h
index a4f9b570775b5..fb366d6509b8b 100644
--- a/tools/tracing/rtla/src/actions.h
+++ b/tools/tracing/rtla/src/actions.h
@@ -44,9 +44,9 @@ struct actions {
void actions_init(struct actions *self);
void actions_destroy(struct actions *self);
-int actions_add_trace_output(struct actions *self, const char *trace_output);
-int actions_add_signal(struct actions *self, int signal, int pid);
-int actions_add_shell(struct actions *self, const char *command);
-int actions_add_continue(struct actions *self);
+void actions_add_trace_output(struct actions *self, const char *trace_output);
+void actions_add_signal(struct actions *self, int signal, int pid);
+void actions_add_shell(struct actions *self, const char *command);
+void actions_add_continue(struct actions *self);
int actions_parse(struct actions *self, const char *trigger, const char *tracefn);
int actions_perform(struct actions *self);
diff --git a/tools/tracing/rtla/src/osnoise.c b/tools/tracing/rtla/src/osnoise.c
index 312c511fa0044..c5b41ec26b0a4 100644
--- a/tools/tracing/rtla/src/osnoise.c
+++ b/tools/tracing/rtla/src/osnoise.c
@@ -938,9 +938,7 @@ struct osnoise_context *osnoise_context_alloc(void)
{
struct osnoise_context *context;
- context = calloc(1, sizeof(*context));
- if (!context)
- return NULL;
+ context = calloc_fatal(1, sizeof(*context));
context->orig_stop_us = OSNOISE_OPTION_INIT_VAL;
context->stop_us = OSNOISE_OPTION_INIT_VAL;
@@ -1017,24 +1015,16 @@ void osnoise_destroy_tool(struct osnoise_tool *top)
struct osnoise_tool *osnoise_init_tool(char *tool_name)
{
struct osnoise_tool *top;
- int retval;
-
- top = calloc(1, sizeof(*top));
- if (!top)
- return NULL;
+ top = calloc_fatal(1, sizeof(*top));
top->context = osnoise_context_alloc();
- if (!top->context)
- goto out_err;
- retval = trace_instance_init(&top->trace, tool_name);
- if (retval)
- goto out_err;
+ if (trace_instance_init(&top->trace, tool_name)) {
+ osnoise_destroy_tool(top);
+ return NULL;
+ }
return top;
-out_err:
- osnoise_destroy_tool(top);
- return NULL;
}
/*
diff --git a/tools/tracing/rtla/src/osnoise_hist.c b/tools/tracing/rtla/src/osnoise_hist.c
index ff8c231e47c47..af7d8621dd9d7 100644
--- a/tools/tracing/rtla/src/osnoise_hist.c
+++ b/tools/tracing/rtla/src/osnoise_hist.c
@@ -474,9 +474,7 @@ static struct common_params
int c;
char *trace_output = NULL;
- params = calloc(1, sizeof(*params));
- if (!params)
- exit(1);
+ params = calloc_fatal(1, sizeof(*params));
actions_init(¶ms->common.threshold_actions);
actions_init(¶ms->common.end_actions);
@@ -564,9 +562,6 @@ static struct common_params
break;
case 'e':
tevent = trace_event_alloc(optarg);
- if (!tevent)
- fatal("Error alloc trace event");
-
if (params->common.events)
tevent->next = params->common.events;
@@ -631,22 +626,16 @@ static struct common_params
params->common.hist.with_zeros = 1;
break;
case '4': /* trigger */
- if (params->common.events) {
- retval = trace_event_add_trigger(params->common.events, optarg);
- if (retval)
- fatal("Error adding trigger %s", optarg);
- } else {
+ if (params->common.events)
+ trace_event_add_trigger(params->common.events, optarg);
+ else
fatal("--trigger requires a previous -e");
- }
break;
case '5': /* filter */
- if (params->common.events) {
- retval = trace_event_add_filter(params->common.events, optarg);
- if (retval)
- fatal("Error adding filter %s", optarg);
- } else {
+ if (params->common.events)
+ trace_event_add_filter(params->common.events, optarg);
+ else
fatal("--filter requires a previous -e");
- }
break;
case '6':
params->common.warmup = get_llong_from_str(optarg);
diff --git a/tools/tracing/rtla/src/osnoise_top.c b/tools/tracing/rtla/src/osnoise_top.c
index 04c699bdd7363..31b7e92d76fe4 100644
--- a/tools/tracing/rtla/src/osnoise_top.c
+++ b/tools/tracing/rtla/src/osnoise_top.c
@@ -327,9 +327,7 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
int c;
char *trace_output = NULL;
- params = calloc(1, sizeof(*params));
- if (!params)
- exit(1);
+ params = calloc_fatal(1, sizeof(*params));
actions_init(¶ms->common.threshold_actions);
actions_init(¶ms->common.end_actions);
@@ -410,9 +408,6 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
break;
case 'e':
tevent = trace_event_alloc(optarg);
- if (!tevent)
- fatal("Error alloc trace event");
-
if (params->common.events)
tevent->next = params->common.events;
params->common.events = tevent;
@@ -462,22 +457,16 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv)
params->threshold = get_llong_from_str(optarg);
break;
case '0': /* trigger */
- if (params->common.events) {
- retval = trace_event_add_trigger(params->common.events, optarg);
- if (retval)
- fatal("Error adding trigger %s", optarg);
- } else {
+ if (params->common.events)
+ trace_event_add_trigger(params->common.events, optarg);
+ else
fatal("--trigger requires a previous -e");
- }
break;
case '1': /* filter */
- if (params->common.events) {
- retval = trace_event_add_filter(params->common.events, optarg);
- if (retval)
- fatal("Error adding filter %s", optarg);
- } else {
+ if (params->common.events)
+ trace_event_add_filter(params->common.events, optarg);
+ else
fatal("--filter requires a previous -e");
- }
break;
case '2':
params->common.warmup = get_llong_from_str(optarg);
diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c
index 1fb471a787b79..226167c88c8d6 100644
--- a/tools/tracing/rtla/src/timerlat_hist.c
+++ b/tools/tracing/rtla/src/timerlat_hist.c
@@ -772,9 +772,7 @@ static struct common_params
int c;
char *trace_output = NULL;
- params = calloc(1, sizeof(*params));
- if (!params)
- exit(1);
+ params = calloc_fatal(1, sizeof(*params));
actions_init(¶ms->common.threshold_actions);
actions_init(¶ms->common.end_actions);
@@ -883,8 +881,6 @@ static struct common_params
break;
case 'e':
tevent = trace_event_alloc(optarg);
- if (!tevent)
- fatal("Error alloc trace event");
if (params->common.events)
tevent->next = params->common.events;
@@ -963,22 +959,16 @@ static struct common_params
params->common.hist.with_zeros = 1;
break;
case '6': /* trigger */
- if (params->common.events) {
- retval = trace_event_add_trigger(params->common.events, optarg);
- if (retval)
- fatal("Error adding trigger %s", optarg);
- } else {
+ if (params->common.events)
+ trace_event_add_trigger(params->common.events, optarg);
+ else
fatal("--trigger requires a previous -e");
- }
break;
case '7': /* filter */
- if (params->common.events) {
- retval = trace_event_add_filter(params->common.events, optarg);
- if (retval)
- fatal("Error adding filter %s", optarg);
- } else {
+ if (params->common.events)
+ trace_event_add_filter(params->common.events, optarg);
+ else
fatal("--filter requires a previous -e");
- }
break;
case '8':
params->dma_latency = get_llong_from_str(optarg);
diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c
index 29c2c1f717ed7..31e1514a2528d 100644
--- a/tools/tracing/rtla/src/timerlat_top.c
+++ b/tools/tracing/rtla/src/timerlat_top.c
@@ -544,9 +544,7 @@ static struct common_params
int c;
char *trace_output = NULL;
- params = calloc(1, sizeof(*params));
- if (!params)
- exit(1);
+ params = calloc_fatal(1, sizeof(*params));
actions_init(¶ms->common.threshold_actions);
actions_init(¶ms->common.end_actions);
@@ -655,9 +653,6 @@ static struct common_params
break;
case 'e':
tevent = trace_event_alloc(optarg);
- if (!tevent)
- fatal("Error alloc trace event");
-
if (params->common.events)
tevent->next = params->common.events;
params->common.events = tevent;
@@ -713,22 +708,16 @@ static struct common_params
params->common.user_data = true;
break;
case '0': /* trigger */
- if (params->common.events) {
- retval = trace_event_add_trigger(params->common.events, optarg);
- if (retval)
- fatal("Error adding trigger %s", optarg);
- } else {
+ if (params->common.events)
+ trace_event_add_trigger(params->common.events, optarg);
+ else
fatal("--trigger requires a previous -e");
- }
break;
case '1': /* filter */
- if (params->common.events) {
- retval = trace_event_add_filter(params->common.events, optarg);
- if (retval)
- fatal("Error adding filter %s", optarg);
- } else {
+ if (params->common.events)
+ trace_event_add_filter(params->common.events, optarg);
+ else
fatal("--filter requires a previous -e");
- }
break;
case '2': /* dma-latency */
params->dma_latency = get_llong_from_str(optarg);
diff --git a/tools/tracing/rtla/src/trace.c b/tools/tracing/rtla/src/trace.c
index 69cbc48d53d3a..b22bb844b71f3 100644
--- a/tools/tracing/rtla/src/trace.c
+++ b/tools/tracing/rtla/src/trace.c
@@ -192,9 +192,7 @@ void trace_instance_destroy(struct trace_instance *trace)
*/
int trace_instance_init(struct trace_instance *trace, char *tool_name)
{
- trace->seq = calloc(1, sizeof(*trace->seq));
- if (!trace->seq)
- goto out_err;
+ trace->seq = calloc_fatal(1, sizeof(*trace->seq));
trace_seq_init(trace->seq);
@@ -275,15 +273,9 @@ struct trace_events *trace_event_alloc(const char *event_string)
{
struct trace_events *tevent;
- tevent = calloc(1, sizeof(*tevent));
- if (!tevent)
- return NULL;
+ tevent = calloc_fatal(1, sizeof(*tevent));
- tevent->system = strdup(event_string);
- if (!tevent->system) {
- free(tevent);
- return NULL;
- }
+ tevent->system = strdup_fatal(event_string);
tevent->event = strstr(tevent->system, ":");
if (tevent->event) {
@@ -297,31 +289,23 @@ struct trace_events *trace_event_alloc(const char *event_string)
/*
* trace_event_add_filter - record an event filter
*/
-int trace_event_add_filter(struct trace_events *event, char *filter)
+void trace_event_add_filter(struct trace_events *event, char *filter)
{
if (event->filter)
free(event->filter);
- event->filter = strdup(filter);
- if (!event->filter)
- return 1;
-
- return 0;
+ event->filter = strdup_fatal(filter);
}
/*
* trace_event_add_trigger - record an event trigger action
*/
-int trace_event_add_trigger(struct trace_events *event, char *trigger)
+void trace_event_add_trigger(struct trace_events *event, char *trigger)
{
if (event->trigger)
free(event->trigger);
- event->trigger = strdup(trigger);
- if (!event->trigger)
- return 1;
-
- return 0;
+ event->trigger = strdup_fatal(trigger);
}
/*
diff --git a/tools/tracing/rtla/src/trace.h b/tools/tracing/rtla/src/trace.h
index 1e5aee4b828dd..95b911a2228b2 100644
--- a/tools/tracing/rtla/src/trace.h
+++ b/tools/tracing/rtla/src/trace.h
@@ -45,6 +45,6 @@ void trace_events_destroy(struct trace_instance *instance,
int trace_events_enable(struct trace_instance *instance,
struct trace_events *events);
-int trace_event_add_filter(struct trace_events *event, char *filter);
-int trace_event_add_trigger(struct trace_events *event, char *trigger);
+void trace_event_add_filter(struct trace_events *event, char *filter);
+void trace_event_add_trigger(struct trace_events *event, char *trigger);
int trace_set_buffer_size(struct trace_instance *trace, int size);
diff --git a/tools/tracing/rtla/src/utils.c b/tools/tracing/rtla/src/utils.c
index 9cf5a0098e9aa..acf95afa25b5a 100644
--- a/tools/tracing/rtla/src/utils.c
+++ b/tools/tracing/rtla/src/utils.c
@@ -1000,3 +1000,38 @@ char *parse_optional_arg(int argc, char **argv)
return NULL;
}
}
+
+static inline void fatal_alloc(void)
+{
+ fatal("Error allocating memory\n");
+}
+
+void *calloc_fatal(size_t n, size_t size)
+{
+ void *p = calloc(n, size);
+
+ if (!p)
+ fatal_alloc();
+
+ return p;
+}
+
+void *reallocarray_fatal(void *p, size_t n, size_t size)
+{
+ p = reallocarray(p, n, size);
+
+ if (!p)
+ fatal_alloc();
+
+ return p;
+}
+
+char *strdup_fatal(const char *s)
+{
+ char *p = strdup(s);
+
+ if (!p)
+ fatal_alloc();
+
+ return p;
+}
diff --git a/tools/tracing/rtla/src/utils.h b/tools/tracing/rtla/src/utils.h
index 091df4ba45877..0ed2c7275f2c5 100644
--- a/tools/tracing/rtla/src/utils.h
+++ b/tools/tracing/rtla/src/utils.h
@@ -68,6 +68,9 @@ int set_comm_sched_attr(const char *comm_prefix, struct sched_attr *attr);
int set_comm_cgroup(const char *comm_prefix, const char *cgroup);
int set_pid_cgroup(pid_t pid, const char *cgroup);
int set_cpu_dma_latency(int32_t latency);
+void *calloc_fatal(size_t n, size_t size);
+void *reallocarray_fatal(void *p, size_t n, size_t size);
+char *strdup_fatal(const char *s);
#ifdef HAVE_LIBCPUPOWER_SUPPORT
int save_cpu_idle_disable_state(unsigned int cpu);
int restore_cpu_idle_disable_state(unsigned int cpu);
--
2.52.0
^ permalink raw reply related
* [PATCH v2 00/18] rtla: Code quality and robustness improvements
From: Wander Lairson Costa @ 2026-01-06 11:49 UTC (permalink / raw)
To: Steven Rostedt, Tomas Glozar, Wander Lairson Costa, Ivan Pravdin,
Crystal Wood, Costa Shulyupin, John Kacur, Tiezhu Yang,
open list:Real-time Linux Analysis (RTLA) tools,
open list:Real-time Linux Analysis (RTLA) tools,
open list:BPF [MISC]:Keyword:(?:b|_)bpf(?:b|_)
This patch series addresses several code quality and robustness issues
in the rtla (Real-Time Linux Analysis) tool. The changes focus on
eliminating potential buffer overflows, fixing NULL pointer dereferences,
improving error handling, and simplifying code maintenance through better
abstractions and helper functions.
The series introduces safer string handling practices, including proper
null termination after read() operations, correct buffer sizing for
strncpy(), and volatile qualification for signal handler variables. It
replaces unsafe functions like atoi() with robust error-checking
alternatives, eliminates magic numbers in favor of named constants, and
adds compile-time string length calculations to prevent buffer overruns.
Additionally, the series reduces code duplication by introducing helper
macros and functions for common patterns like action iteration, argument
parsing, and threshold restart logic. It also includes minor cleanups
such as removing redundant operations, unused headers, and fixing
documentation inconsistencies. These improvements make the rtla codebase
safer, more maintainable, and more consistent with kernel coding
standards.
Changes:
v2:
- exit on memory allocation failure
- remove redundant strlen() calls
- fix possible race on condition on stop_tracing variable access
- ensure null termination on read() calls
- fix checkpatch reports
- make extract_args() an inline function
- add the usage of common_restart() in more places
Wander Lairson Costa (18):
rtla: Exit on memory allocation failures during initialization
rtla: Use strdup() to simplify code
rtla: Introduce for_each_action() helper
rtla: Replace atoi() with a robust strtoi()
rtla: Simplify argument parsing
rtla: Use strncmp_static() in more places
rtla: Introduce common_restart() helper
rtla: Use standard exit codes for result enum
rtla: Remove redundant memset after calloc
rtla: Replace magic number with MAX_PATH
rtla: Remove unused headers
rtla: Fix NULL pointer dereference in actions_parse
rtla: Fix buffer size for strncpy in timerlat_aa
rtla: Add generated output files to gitignore
rtla: Make stop_tracing variable volatile
rtla: Ensure null termination after read operations in utils.c
rtla: Fix parse_cpu_set() return value documentation
rtla: Simplify code by caching string lengths
tools/tracing/rtla/.gitignore | 4 +
tools/tracing/rtla/src/actions.c | 114 +++++++++++++++----------
tools/tracing/rtla/src/actions.h | 13 ++-
tools/tracing/rtla/src/common.c | 67 ++++++++++-----
tools/tracing/rtla/src/common.h | 11 ++-
tools/tracing/rtla/src/osnoise.c | 28 ++----
tools/tracing/rtla/src/osnoise_hist.c | 26 ++----
tools/tracing/rtla/src/osnoise_top.c | 25 ++----
tools/tracing/rtla/src/timerlat.c | 5 +-
tools/tracing/rtla/src/timerlat_aa.c | 4 +-
tools/tracing/rtla/src/timerlat_hist.c | 44 ++++------
tools/tracing/rtla/src/timerlat_top.c | 46 ++++------
tools/tracing/rtla/src/timerlat_u.c | 4 +-
tools/tracing/rtla/src/trace.c | 59 +++++--------
tools/tracing/rtla/src/trace.h | 4 +-
tools/tracing/rtla/src/utils.c | 99 ++++++++++++++++++---
tools/tracing/rtla/src/utils.h | 26 ++++--
17 files changed, 335 insertions(+), 244 deletions(-)
--
2.52.0
^ permalink raw reply
* Re: [PATCH v2] arm64: Disable branch profiling for all arm64 code
From: Mark Rutland @ 2026-01-06 12:24 UTC (permalink / raw)
To: Breno Leitao
Cc: Catalin Marinas, Will Deacon, Laura Abbott, linux-arm-kernel,
linux-kernel, linux-trace-kernel, Steven Rostedt,
Masami Hiramatsu, kernel-team, puranjay, stable
In-Reply-To: <aVz-NHMG7rSJ9u1N@J2N7QTR9R3>
On Tue, Jan 06, 2026 at 12:21:47PM +0000, Mark Rutland wrote:
> On Tue, Jan 06, 2026 at 02:16:35AM -0800, Breno Leitao wrote:
> > The arm64 kernel doesn't boot with annotated branches
> > (PROFILE_ANNOTATED_BRANCHES) enabled and CONFIG_DEBUG_VIRTUAL together.
> >
> > Bisecting it, I found that disabling branch profiling in arch/arm64/mm
> > solved the problem. Narrowing down a bit further, I found that
> > physaddr.c is the file that needs to have branch profiling disabled to
> > get the machine to boot.
> >
> > I suspect that it might invoke some ftrace helper very early in the boot
> > process and ftrace is still not enabled(!?).
> >
> > Rather than playing whack-a-mole with individual files, disable branch
> > profiling for the entire arch/arm64 tree, similar to what x86 already
> > does in arch/x86/Kbuild.
> >
> > Cc: stable@vger.kernel.org
> > Fixes: ec6d06efb0bac ("arm64: Add support for CONFIG_DEBUG_VIRTUAL")
> > Signed-off-by: Breno Leitao <leitao@debian.org>
>
> I don't think ec6d06efb0bac is to blame here, and CONFIG_DEBUG_VIRTUAL
> is unsound in a number of places, so I'd prefer to remove that Fixes tag
> and backport this for all stable trees.
>
> Regardless, I'm in favour of disabling CONFIG_DEBUG_VIRTUAL widely, so:
>
> Acked-by: Mark Rutland <mark.rutland@arm.com>
Whoops; s/CONFIG_DEBUG_VIRTUAL/PROFILE_ANNOTATED_BRANCHES/ in both
places in my reply.
Mark.
^ permalink raw reply
* Re: [PATCH v2] arm64: Disable branch profiling for all arm64 code
From: Mark Rutland @ 2026-01-06 12:21 UTC (permalink / raw)
To: Breno Leitao
Cc: Catalin Marinas, Will Deacon, Laura Abbott, linux-arm-kernel,
linux-kernel, linux-trace-kernel, Steven Rostedt,
Masami Hiramatsu, kernel-team, puranjay, stable
In-Reply-To: <20260106-annotated-v2-1-fb7600ebd47f@debian.org>
On Tue, Jan 06, 2026 at 02:16:35AM -0800, Breno Leitao wrote:
> The arm64 kernel doesn't boot with annotated branches
> (PROFILE_ANNOTATED_BRANCHES) enabled and CONFIG_DEBUG_VIRTUAL together.
>
> Bisecting it, I found that disabling branch profiling in arch/arm64/mm
> solved the problem. Narrowing down a bit further, I found that
> physaddr.c is the file that needs to have branch profiling disabled to
> get the machine to boot.
>
> I suspect that it might invoke some ftrace helper very early in the boot
> process and ftrace is still not enabled(!?).
>
> Rather than playing whack-a-mole with individual files, disable branch
> profiling for the entire arch/arm64 tree, similar to what x86 already
> does in arch/x86/Kbuild.
>
> Cc: stable@vger.kernel.org
> Fixes: ec6d06efb0bac ("arm64: Add support for CONFIG_DEBUG_VIRTUAL")
> Signed-off-by: Breno Leitao <leitao@debian.org>
I don't think ec6d06efb0bac is to blame here, and CONFIG_DEBUG_VIRTUAL
is unsound in a number of places, so I'd prefer to remove that Fixes tag
and backport this for all stable trees.
Regardless, I'm in favour of disabling CONFIG_DEBUG_VIRTUAL widely, so:
Acked-by: Mark Rutland <mark.rutland@arm.com>
Mark.
> ---
> Changes in v2:
> - Expand the scope to arch/arm64 instead of just physaddr.c
> - Link to v1: https://lore.kernel.org/all/20251231-annotated-v1-1-9db1c0d03062@debian.org/
> ---
> arch/arm64/Kbuild | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/arch/arm64/Kbuild b/arch/arm64/Kbuild
> index 5bfbf7d79c99..d876bc0e5421 100644
> --- a/arch/arm64/Kbuild
> +++ b/arch/arm64/Kbuild
> @@ -1,4 +1,8 @@
> # SPDX-License-Identifier: GPL-2.0-only
> +
> +# Branch profiling isn't noinstr-safe
> +subdir-ccflags-$(CONFIG_TRACE_BRANCH_PROFILING) += -DDISABLE_BRANCH_PROFILING
> +
> obj-y += kernel/ mm/ net/
> obj-$(CONFIG_KVM) += kvm/
> obj-$(CONFIG_XEN) += xen/
>
> ---
> base-commit: c8ebd433459bcbf068682b09544e830acd7ed222
> change-id: 20251231-annotated-75de3f33cd7b
>
> Best regards,
> --
> Breno Leitao <leitao@debian.org>
>
^ permalink raw reply
* [PATCH v2] arm64: Disable branch profiling for all arm64 code
From: Breno Leitao @ 2026-01-06 10:16 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Mark Rutland, Laura Abbott
Cc: linux-arm-kernel, linux-kernel, linux-trace-kernel,
Steven Rostedt, Masami Hiramatsu, kernel-team, puranjay, stable,
Breno Leitao
The arm64 kernel doesn't boot with annotated branches
(PROFILE_ANNOTATED_BRANCHES) enabled and CONFIG_DEBUG_VIRTUAL together.
Bisecting it, I found that disabling branch profiling in arch/arm64/mm
solved the problem. Narrowing down a bit further, I found that
physaddr.c is the file that needs to have branch profiling disabled to
get the machine to boot.
I suspect that it might invoke some ftrace helper very early in the boot
process and ftrace is still not enabled(!?).
Rather than playing whack-a-mole with individual files, disable branch
profiling for the entire arch/arm64 tree, similar to what x86 already
does in arch/x86/Kbuild.
Cc: stable@vger.kernel.org
Fixes: ec6d06efb0bac ("arm64: Add support for CONFIG_DEBUG_VIRTUAL")
Signed-off-by: Breno Leitao <leitao@debian.org>
---
Changes in v2:
- Expand the scope to arch/arm64 instead of just physaddr.c
- Link to v1: https://lore.kernel.org/all/20251231-annotated-v1-1-9db1c0d03062@debian.org/
---
arch/arm64/Kbuild | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm64/Kbuild b/arch/arm64/Kbuild
index 5bfbf7d79c99..d876bc0e5421 100644
--- a/arch/arm64/Kbuild
+++ b/arch/arm64/Kbuild
@@ -1,4 +1,8 @@
# SPDX-License-Identifier: GPL-2.0-only
+
+# Branch profiling isn't noinstr-safe
+subdir-ccflags-$(CONFIG_TRACE_BRANCH_PROFILING) += -DDISABLE_BRANCH_PROFILING
+
obj-y += kernel/ mm/ net/
obj-$(CONFIG_KVM) += kvm/
obj-$(CONFIG_XEN) += xen/
---
base-commit: c8ebd433459bcbf068682b09544e830acd7ed222
change-id: 20251231-annotated-75de3f33cd7b
Best regards,
--
Breno Leitao <leitao@debian.org>
^ permalink raw reply related
* [PATCH] ring-buffer: Use a housekeeping CPU to wake up waiters
From: Petr Tesarik @ 2026-01-06 9:10 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
Sebastian Andrzej Siewior, Clark Williams
Cc: linux-kernel, linux-trace-kernel, linux-rt-devel, Petr Tesarik
Avoid running the wakeup irq_work on an isolated CPU. Since the wakeup can
run on any CPU, let's pick a housekeeping CPU to do the job.
This change reduces additional noise when tracing isolated CPUs. For
example, the following ipi_send_cpu stack trace was captured with
nohz_full=2 on the isolated CPU:
<idle>-0 [002] d.h4. 1255.379293: ipi_send_cpu: cpu=2 callsite=irq_work_queue+0x2d/0x50 callback=rb_wake_up_waiters+0x0/0x80
<idle>-0 [002] d.h4. 1255.379329: <stack trace>
=> trace_event_raw_event_ipi_send_cpu
=> __irq_work_queue_local
=> irq_work_queue
=> ring_buffer_unlock_commit
=> trace_buffer_unlock_commit_regs
=> trace_event_buffer_commit
=> trace_event_raw_event_x86_irq_vector
=> __sysvec_apic_timer_interrupt
=> sysvec_apic_timer_interrupt
=> asm_sysvec_apic_timer_interrupt
=> pv_native_safe_halt
=> default_idle
=> default_idle_call
=> do_idle
=> cpu_startup_entry
=> start_secondary
=> common_startup_64
The IRQ work interrupt alone adds considerable noise, but the impact can
get even worse with PREEMPT_RT, because the IRQ work interrupt is then
handled by a separate kernel thread. This requires a task switch and makes
tracing useless for analyzing latency on an isolated CPU.
Signed-off-by: Petr Tesarik <ptesarik@suse.com>
---
kernel/trace/ring_buffer.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 41c9f5d079beb..ed9160599091d 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -4,6 +4,7 @@
*
* Copyright (C) 2008 Steven Rostedt <srostedt@redhat.com>
*/
+#include <linux/sched/isolation.h>
#include <linux/trace_recursion.h>
#include <linux/trace_events.h>
#include <linux/ring_buffer.h>
@@ -4011,19 +4012,31 @@ static void rb_commit(struct ring_buffer_per_cpu *cpu_buffer)
rb_end_commit(cpu_buffer);
}
+static inline bool
+rb_irq_work_queue(struct rb_irq_work *irq_work)
+{
+ int cpu = housekeeping_any_cpu(HK_TYPE_KERNEL_NOISE);
+
+ /*
+ * If CPU isolation is not active, cpu is always the current
+ * CPU, and the following is equivallent to irq_work_queue().
+ */
+ return irq_work_queue_on(&irq_work->work, cpu);
+}
+
static __always_inline void
rb_wakeups(struct trace_buffer *buffer, struct ring_buffer_per_cpu *cpu_buffer)
{
if (buffer->irq_work.waiters_pending) {
buffer->irq_work.waiters_pending = false;
/* irq_work_queue() supplies it's own memory barriers */
- irq_work_queue(&buffer->irq_work.work);
+ rb_irq_work_queue(&buffer->irq_work);
}
if (cpu_buffer->irq_work.waiters_pending) {
cpu_buffer->irq_work.waiters_pending = false;
/* irq_work_queue() supplies it's own memory barriers */
- irq_work_queue(&cpu_buffer->irq_work.work);
+ rb_irq_work_queue(&cpu_buffer->irq_work);
}
if (cpu_buffer->last_pages_touch == local_read(&cpu_buffer->pages_touched))
@@ -4043,7 +4056,7 @@ rb_wakeups(struct trace_buffer *buffer, struct ring_buffer_per_cpu *cpu_buffer)
cpu_buffer->irq_work.wakeup_full = true;
cpu_buffer->irq_work.full_waiters_pending = false;
/* irq_work_queue() supplies it's own memory barriers */
- irq_work_queue(&cpu_buffer->irq_work.work);
+ rb_irq_work_queue(&cpu_buffer->irq_work);
}
#ifdef CONFIG_RING_BUFFER_RECORD_RECURSION
--
2.52.0
^ permalink raw reply related
* Re: [v2 PATCH 2/2] tracing: Add show_event_triggers to expose active event triggers
From: Randy Dunlap @ 2026-01-06 6:10 UTC (permalink / raw)
To: Aaron Tomlin, rostedt, mhiramat, mark.rutland, mathieu.desnoyers,
corbet
Cc: neelx, sean, linux-kernel, linux-trace-kernel, linux-doc
In-Reply-To: <20260105142939.2655342-3-atomlin@atomlin.com>
Hi,
On 1/5/26 6:29 AM, Aaron Tomlin wrote:
> diff --git a/Documentation/trace/ftrace.rst b/Documentation/trace/ftrace.rst
> index 4ce01e726b09..b9efb148a5c2 100644
> --- a/Documentation/trace/ftrace.rst
> +++ b/Documentation/trace/ftrace.rst
> @@ -692,6 +692,14 @@ of ftrace. Here is a list of some of the key files:
>
> See events.rst for more information.
>
> + show_event_triggers:
> +
> + A list of events that have triggers. This shows the
> + system/event pair along with the trigger that is attached to
> + the event.
> +
> + See events.rst for more information.
> +
Isn't this the same chunk that was in patch 1/2?
> available_events:
>
> A list of events that can be enabled in tracing.
--
~Randy
^ permalink raw reply
* Re: [PATCH v3 0/2] mm: vmscan: add PID and cgroup ID to vmscan tracepoints
From: Steven Rostedt @ 2026-01-06 2:21 UTC (permalink / raw)
To: Andrew Morton; +Cc: Thomas Ballasi, linux-mm, linux-trace-kernel, mhiramat
In-Reply-To: <20260105180640.2072c151c9f1f56458cb2dd2@linux-foundation.org>
On Mon, 5 Jan 2026 18:06:40 -0800
Andrew Morton <akpm@linux-foundation.org> wrote:
> On Mon, 5 Jan 2026 08:04:21 -0800 Thomas Ballasi <tballasi@linux.microsoft.com> wrote:
>
> > Changes in v3:
> > - Swapped multiple field entries to prevent a hole in the ring buffer
> > - Replaced in_task() with __event_in_irq
> > - Replaced mem_cgroup_id(memcg) with cgroup_id(memcg->css.cgroup)
> > - Rebased the tree to latest 6.18
>
> x86_64 allmodconfig;
>
>
> In file included from ./include/trace/define_trace.h:132,
> from ./include/trace/events/vmscan.h:569,
> from mm/vmscan.c:73:
> ./include/trace/events/vmscan.h: In function 'trace_raw_output_mm_vmscan_direct_reclaim_begin_template':
> ./include/trace/events/vmscan.h:140:17: error: implicit declaration of function '__event_in_irq' [-Wimplicit-function-declaration]
> 140 | + __event_in_irq() ? "(in-irq)" : "")
> | ^~~~~~~~~~~~~~
> ./include/trace/trace_events.h:219:34: note: in definition of macro 'DECLARE_EVENT_CLASS'
> 219 | trace_event_printf(iter, print); \
> | ^~~~~
> ./include/trace/events/vmscan.h:135:9: note: in expansion of macro 'TP_printk'
> 135 | TP_printk("order=%d gfp_flags=%s pid=%d memcg_id=%u %s",
> | ^~~~~~~~~
> make[3]: *** [scripts/Makefile.build:287: mm/vmscan.o] Error 1
> make[2]: *** [scripts/Makefile.build:556: mm] Error 2
> make[1]: *** [/usr/src/25/Makefile:2054: .] Error 2
> make: *** [Makefile:248: __sub-make] Error 2
This is dependent on my patch:
https://lore.kernel.org/all/20251229163515.3d1b0bba@gandalf.local.home/
Where I said you can take this patch. But I don't see it as part of the
series.
https://lore.kernel.org/all/20251229163634.5aad205d@gandalf.local.home/
-- Steve
^ permalink raw reply
* Re: [PATCH v3 0/2] mm: vmscan: add PID and cgroup ID to vmscan tracepoints
From: Andrew Morton @ 2026-01-06 2:06 UTC (permalink / raw)
To: Thomas Ballasi; +Cc: linux-mm, linux-trace-kernel, mhiramat, rostedt
In-Reply-To: <20260105160423.23708-1-tballasi@linux.microsoft.com>
On Mon, 5 Jan 2026 08:04:21 -0800 Thomas Ballasi <tballasi@linux.microsoft.com> wrote:
> Changes in v3:
> - Swapped multiple field entries to prevent a hole in the ring buffer
> - Replaced in_task() with __event_in_irq
> - Replaced mem_cgroup_id(memcg) with cgroup_id(memcg->css.cgroup)
> - Rebased the tree to latest 6.18
x86_64 allmodconfig;
In file included from ./include/trace/define_trace.h:132,
from ./include/trace/events/vmscan.h:569,
from mm/vmscan.c:73:
./include/trace/events/vmscan.h: In function 'trace_raw_output_mm_vmscan_direct_reclaim_begin_template':
./include/trace/events/vmscan.h:140:17: error: implicit declaration of function '__event_in_irq' [-Wimplicit-function-declaration]
140 | + __event_in_irq() ? "(in-irq)" : "")
| ^~~~~~~~~~~~~~
./include/trace/trace_events.h:219:34: note: in definition of macro 'DECLARE_EVENT_CLASS'
219 | trace_event_printf(iter, print); \
| ^~~~~
./include/trace/events/vmscan.h:135:9: note: in expansion of macro 'TP_printk'
135 | TP_printk("order=%d gfp_flags=%s pid=%d memcg_id=%u %s",
| ^~~~~~~~~
make[3]: *** [scripts/Makefile.build:287: mm/vmscan.o] Error 1
make[2]: *** [scripts/Makefile.build:556: mm] Error 2
make[1]: *** [/usr/src/25/Makefile:2054: .] Error 2
make: *** [Makefile:248: __sub-make] Error 2
^ permalink raw reply
* [PATCH] tracing: Add recursion protection in kernel stack trace recording
From: Steven Rostedt @ 2026-01-06 1:31 UTC (permalink / raw)
To: LKML, Linux Trace Kernel
Cc: Masami Hiramatsu, Mathieu Desnoyers, Joel Fernandes,
Paul E. McKenney, Yao Kai, Boqun Feng
From: Steven Rostedt <rostedt@goodmis.org>
A bug was reported about an infinite recursion caused by tracing the rcu
events with the kernel stack trace trigger enabled. The stack trace code
called back into RCU which then called the stack trace again.
Expand the ftrace recursion protection to add a set of bits to protect
events from recursion. Each bit represents the context that the event is
in (normal, softirq, interrupt and NMI).
Have the stack trace code use the interrupt context to protect against
recursion.
Note, the bug showed an issue in both the RCU code as well as the tracing
stacktrace code. This only handles the tracing stack trace side of the
bug. The RCU fix will be handled separately.
Link: https://lore.kernel.org/all/20260102122807.7025fc87@gandalf.local.home/
Cc: stable@vger.kernel.org
Reported-by: Yao Kai <yaokai34@huawei.com>
Tested-by: Yao Kai <yaokai34@huawei.com>
Fixes: 5f5fa7ea89dc ("rcu: Don't use negative nesting depth in __rcu_read_unlock()")
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
include/linux/trace_recursion.h | 9 +++++++++
kernel/trace/trace.c | 6 ++++++
2 files changed, 15 insertions(+)
diff --git a/include/linux/trace_recursion.h b/include/linux/trace_recursion.h
index ae04054a1be3..e6ca052b2a85 100644
--- a/include/linux/trace_recursion.h
+++ b/include/linux/trace_recursion.h
@@ -34,6 +34,13 @@ enum {
TRACE_INTERNAL_SIRQ_BIT,
TRACE_INTERNAL_TRANSITION_BIT,
+ /* Internal event use recursion bits */
+ TRACE_INTERNAL_EVENT_BIT,
+ TRACE_INTERNAL_EVENT_NMI_BIT,
+ TRACE_INTERNAL_EVENT_IRQ_BIT,
+ TRACE_INTERNAL_EVENT_SIRQ_BIT,
+ TRACE_INTERNAL_EVENT_TRANSITION_BIT,
+
TRACE_BRANCH_BIT,
/*
* Abuse of the trace_recursion.
@@ -58,6 +65,8 @@ enum {
#define TRACE_LIST_START TRACE_INTERNAL_BIT
+#define TRACE_EVENT_START TRACE_INTERNAL_EVENT_BIT
+
#define TRACE_CONTEXT_MASK ((1 << (TRACE_LIST_START + TRACE_CONTEXT_BITS)) - 1)
/*
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 6f2148df14d9..aef9058537d5 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -3012,6 +3012,11 @@ static void __ftrace_trace_stack(struct trace_array *tr,
struct ftrace_stack *fstack;
struct stack_entry *entry;
int stackidx;
+ int bit;
+
+ bit = trace_test_and_set_recursion(_THIS_IP_, _RET_IP_, TRACE_EVENT_START);
+ if (bit < 0)
+ return;
/*
* Add one, for this function and the call to save_stack_trace()
@@ -3080,6 +3085,7 @@ static void __ftrace_trace_stack(struct trace_array *tr,
/* Again, don't let gcc optimize things here */
barrier();
__this_cpu_dec(ftrace_stack_reserve);
+ trace_clear_recursion(bit);
}
static inline void ftrace_trace_stack(struct trace_array *tr,
--
2.51.0
^ permalink raw reply related
* Re: [PATCH] ring-buffer: Avoid softlockup in ring_buffer_resize() during memory free
From: Masami Hiramatsu @ 2026-01-06 0:52 UTC (permalink / raw)
To: Wupeng Ma; +Cc: rostedt, mathieu.desnoyers, linux-kernel, linux-trace-kernel
In-Reply-To: <20251228065008.2396573-1-mawupeng1@huawei.com>
On Sun, 28 Dec 2025 14:50:07 +0800
Wupeng Ma <mawupeng1@huawei.com> wrote:
> When user resize all trace ring buffer through file 'buffer_size_kb',
> then in ring_buffer_resize(), kernel allocates buffer pages for each
> cpu in a loop.
>
> If the kernel preemption model is PREEMPT_NONE and there are many cpus
> and there are many buffer pages to be freed, it may not give up cpu
> for a long time and finally cause a softlockup.
>
> To avoid it, call cond_resched() after each cpu buffer free as Commit
> f6bd2c92488c ("ring-buffer: Avoid softlockup in ring_buffer_resize()")
> does.
>
> Detailed call trace as follow:
>
> rcu: INFO: rcu_sched self-detected stall on CPU
> rcu: 24-....: (14837 ticks this GP) idle=521c/1/0x4000000000000000 softirq=230597/230597 fqs=5329
> rcu: (t=15004 jiffies g=26003221 q=211022 ncpus=96)
> CPU: 24 UID: 0 PID: 11253 Comm: bash Kdump: loaded Tainted: G EL 6.18.2+ #278 NONE
> pc : arch_local_irq_restore+0x8/0x20
> arch_local_irq_restore+0x8/0x20 (P)
> free_frozen_page_commit+0x28c/0x3b0
> __free_frozen_pages+0x1c0/0x678
> ___free_pages+0xc0/0xe0
> free_pages+0x3c/0x50
> ring_buffer_resize.part.0+0x6a8/0x880
> ring_buffer_resize+0x3c/0x58
> __tracing_resize_ring_buffer.part.0+0x34/0xd8
> tracing_resize_ring_buffer+0x8c/0xd0
> tracing_entries_write+0x74/0xd8
> vfs_write+0xcc/0x288
> ksys_write+0x74/0x118
> __arm64_sys_write+0x24/0x38
>
> Signed-off-by: Wupeng Ma <mawupeng1@huawei.com>
Looks good to me.
Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Thanks!
> ---
> kernel/trace/ring_buffer.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
> index afcd3747264d2..3ba08fc1b7d05 100644
> --- a/kernel/trace/ring_buffer.c
> +++ b/kernel/trace/ring_buffer.c
> @@ -3121,6 +3121,8 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size,
> list) {
> list_del_init(&bpage->list);
> free_buffer_page(bpage);
> +
> + cond_resched();
> }
> }
> out_err_unlock:
> --
> 2.43.0
>
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply
* Re: [PATCH] arm64: simplify arch_uprobe_xol_was_trapped return
From: Will Deacon @ 2026-01-05 22:58 UTC (permalink / raw)
To: mhiramat, oleg, peterz, catalin.marinas, Osama Abdelkader
Cc: kernel-team, Will Deacon, linux-arm-kernel, linux-kernel,
linux-trace-kernel
In-Reply-To: <20251126223130.216302-1-osama.abdelkader@gmail.com>
On Thu, 27 Nov 2025 00:31:30 +0200, Osama Abdelkader wrote:
> convert arch_uprobe_xol_was_trapped() from explicit if/return true
> return false pattern to direct boolean expression return in
> arch/arm64/kernel/probes/uprobes.c
>
>
Applied to arm64 (for-next/misc), thanks!
[1/1] arm64: simplify arch_uprobe_xol_was_trapped return
https://git.kernel.org/arm64/c/484626209600
Cheers,
--
Will
https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev
^ permalink raw reply
* Re: [PATCH v3 1/2] mm: vmscan: add cgroup IDs to vmscan tracepoints
From: Shakeel Butt @ 2026-01-05 22:46 UTC (permalink / raw)
To: Thomas Ballasi; +Cc: akpm, linux-mm, linux-trace-kernel, mhiramat, rostedt
In-Reply-To: <20260105160423.23708-2-tballasi@linux.microsoft.com>
On Mon, Jan 05, 2026 at 08:04:22AM -0800, Thomas Ballasi wrote:
> Memory reclaim events are currently difficult to attribute to
> specific cgroups, making debugging memory pressure issues
> challenging. This patch adds memory cgroup ID (memcg_id) to key
> vmscan tracepoints to enable better correlation and analysis.
>
> For operations not associated with a specific cgroup, the field
> is defaulted to 0.
>
> Signed-off-by: Thomas Ballasi <tballasi@linux.microsoft.com>
Couple of comments:
1. memcg_id is u64 but the patch is using 'unsigned short'.
2. I would prefer memcg pointer be passed in tracepoint and then in
trace header file cgroup_id() be used similar to other users in
include/trace/events/ folder.
Orthogonally I am cleaning up memcg id usage and after that cleanup,
mem_cgroup_id() would be preferred way to get the ID. No need to do
anything now as I will cleanup this usage later as well.
^ permalink raw reply
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