From: Steven Rostedt <rostedt@kernel.org>
To: linux-kernel@vger.kernel.org
Cc: Tomas Glozar <tglozar@redhat.com>, John Kacur <jkacur@redhat.com>,
Luis Goncalves <lgoncalv@redhat.com>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Chang Yin <cyin@redhat.com>,
Costa Shulyupin <costa.shul@redhat.com>,
Crystal Wood <crwood@redhat.com>,
Gabriele Monaco <gmonaco@redhat.com>
Subject: [for-next][PATCH 4/9] rtla/timerlat: Add continue action
Date: Mon, 21 Jul 2025 19:12:08 -0400 [thread overview]
Message-ID: <20250721231222.797319180@kernel.org> (raw)
In-Reply-To: 20250721231204.100737734@kernel.org
From: Tomas Glozar <tglozar@redhat.com>
Introduce option to resume tracing after a latency threshold overflow.
The option is implemented as an action named "continue".
Example:
$ rtla timerlat top -q -T 200 -d 1s --on-threshold \
exec,command="echo Threshold" --on-threshold continue
Threshold
Threshold
Threshold
Timer Latency
...
The feature is supported for both hist and top. After the continue
action is executed, processing of the list of actions is stopped and
tracing is resumed.
Cc: John Kacur <jkacur@redhat.com>
Cc: Luis Goncalves <lgoncalv@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Chang Yin <cyin@redhat.com>
Cc: Costa Shulyupin <costa.shul@redhat.com>
Cc: Crystal Wood <crwood@redhat.com>
Cc: Gabriele Monaco <gmonaco@redhat.com>
Link: https://lore.kernel.org/20250626123405.1496931-5-tglozar@redhat.com
Signed-off-by: Tomas Glozar <tglozar@redhat.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
tools/tracing/rtla/src/actions.c | 27 +++++++++++-
tools/tracing/rtla/src/actions.h | 5 ++-
tools/tracing/rtla/src/timerlat_hist.c | 40 +++++++++++++++---
tools/tracing/rtla/src/timerlat_top.c | 57 ++++++++++++++++----------
4 files changed, 100 insertions(+), 29 deletions(-)
diff --git a/tools/tracing/rtla/src/actions.c b/tools/tracing/rtla/src/actions.c
index 63bee5bdabfd..aaf0808125d7 100644
--- a/tools/tracing/rtla/src/actions.c
+++ b/tools/tracing/rtla/src/actions.c
@@ -17,6 +17,7 @@ actions_init(struct actions *self)
self->size = action_default_size;
self->list = calloc(self->size, sizeof(struct action));
self->len = 0;
+ self->continue_flag = false;
memset(&self->present, 0, sizeof(self->present));
@@ -108,6 +109,20 @@ actions_add_shell(struct actions *self, const char *command)
return 0;
}
+/*
+ * actions_add_continue - add an action to resume measurement
+ */
+int
+actions_add_continue(struct actions *self)
+{
+ struct action *action = actions_new(self);
+
+ self->present[ACTION_CONTINUE] = true;
+ action->type = ACTION_CONTINUE;
+
+ return 0;
+}
+
/*
* actions_parse - add an action based on text specification
*/
@@ -133,6 +148,8 @@ actions_parse(struct actions *self, const char *trigger)
type = ACTION_SIGNAL;
else if (strcmp(token, "shell") == 0)
type = ACTION_SHELL;
+ else if (strcmp(token, "continue") == 0)
+ type = ACTION_CONTINUE;
else
/* Invalid trigger type */
return -1;
@@ -187,6 +204,11 @@ actions_parse(struct actions *self, const char *trigger)
if (strlen(token) > 8 && strncmp(token, "command=", 8) == 0)
return actions_add_shell(self, token + 8);
return -1;
+ case ACTION_CONTINUE:
+ /* Takes no argument */
+ if (token != NULL)
+ return -1;
+ return actions_add_continue(self);
default:
return -1;
}
@@ -196,7 +218,7 @@ actions_parse(struct actions *self, const char *trigger)
* actions_perform - perform all actions
*/
int
-actions_perform(const struct actions *self)
+actions_perform(struct actions *self)
{
int pid, retval;
const struct action *action;
@@ -226,6 +248,9 @@ actions_perform(const struct actions *self)
if (retval)
return retval;
break;
+ case ACTION_CONTINUE:
+ self->continue_flag = true;
+ return 0;
default:
break;
}
diff --git a/tools/tracing/rtla/src/actions.h b/tools/tracing/rtla/src/actions.h
index 076bbff8519e..b10a19d55c49 100644
--- a/tools/tracing/rtla/src/actions.h
+++ b/tools/tracing/rtla/src/actions.h
@@ -7,6 +7,7 @@ enum action_type {
ACTION_TRACE_OUTPUT,
ACTION_SIGNAL,
ACTION_SHELL,
+ ACTION_CONTINUE,
ACTION_FIELD_N
};
@@ -35,6 +36,7 @@ struct actions {
struct action *list;
int len, size;
bool present[ACTION_FIELD_N];
+ bool continue_flag;
/* External dependencies */
struct tracefs_instance *trace_output_inst;
@@ -45,5 +47,6 @@ 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);
int actions_parse(struct actions *self, const char *trigger);
-int actions_perform(const struct actions *self);
+int actions_perform(struct actions *self);
diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c
index d975d2cd6604..4f13a8f92711 100644
--- a/tools/tracing/rtla/src/timerlat_hist.c
+++ b/tools/tracing/rtla/src/timerlat_hist.c
@@ -1374,8 +1374,20 @@ int timerlat_hist_main(int argc, char *argv[])
goto out_hist;
}
- if (osnoise_trace_is_off(tool, record))
- break;
+ if (osnoise_trace_is_off(tool, record)) {
+ actions_perform(¶ms->actions);
+
+ if (!params->actions.continue_flag)
+ /* continue flag not set, break */
+ break;
+
+ /* continue action reached, re-enable tracing */
+ if (params->actions.present[ACTION_TRACE_OUTPUT])
+ trace_instance_start(&record->trace);
+ if (!params->no_aa)
+ trace_instance_start(&aa->trace);
+ trace_instance_start(trace);
+ }
/* is there still any user-threads ? */
if (params->user_workload) {
@@ -1385,8 +1397,27 @@ int timerlat_hist_main(int argc, char *argv[])
}
}
}
- } else
- timerlat_bpf_wait(-1);
+ } else {
+ while (!stop_tracing) {
+ timerlat_bpf_wait(-1);
+
+ if (!stop_tracing) {
+ /* Threshold overflow, perform actions on threshold */
+ actions_perform(¶ms->actions);
+
+ if (!params->actions.continue_flag)
+ /* continue flag not set, break */
+ break;
+
+ /* continue action reached, re-enable tracing */
+ if (params->actions.present[ACTION_TRACE_OUTPUT])
+ trace_instance_start(&record->trace);
+ if (!params->no_aa)
+ trace_instance_start(&aa->trace);
+ timerlat_bpf_restart_tracing();
+ }
+ }
+ }
if (params->mode != TRACING_MODE_TRACEFS) {
timerlat_bpf_detach();
@@ -1412,7 +1443,6 @@ int timerlat_hist_main(int argc, char *argv[])
if (!params->no_aa)
timerlat_auto_analysis(params->stop_us, params->stop_total_us);
- actions_perform(¶ms->actions);
return_value = FAILED;
}
diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c
index cdbfda009974..60f9c78cb272 100644
--- a/tools/tracing/rtla/src/timerlat_top.c
+++ b/tools/tracing/rtla/src/timerlat_top.c
@@ -906,6 +906,7 @@ timerlat_top_set_signals(struct timerlat_params *params)
static int
timerlat_top_main_loop(struct osnoise_tool *top,
struct osnoise_tool *record,
+ struct osnoise_tool *aa,
struct timerlat_params *params,
struct timerlat_u_params *params_u)
{
@@ -932,8 +933,20 @@ timerlat_top_main_loop(struct osnoise_tool *top,
if (!params->quiet)
timerlat_print_stats(params, top);
- if (osnoise_trace_is_off(top, record))
- break;
+ if (osnoise_trace_is_off(top, record)) {
+ actions_perform(¶ms->actions);
+
+ if (!params->actions.continue_flag)
+ /* continue flag not set, break */
+ break;
+
+ /* continue action reached, re-enable tracing */
+ if (params->actions.present[ACTION_TRACE_OUTPUT])
+ trace_instance_start(&record->trace);
+ if (!params->no_aa)
+ trace_instance_start(&aa->trace);
+ trace_instance_start(trace);
+ }
/* is there still any user-threads ? */
if (params->user_workload) {
@@ -953,6 +966,7 @@ timerlat_top_main_loop(struct osnoise_tool *top,
static int
timerlat_top_bpf_main_loop(struct osnoise_tool *top,
struct osnoise_tool *record,
+ struct osnoise_tool *aa,
struct timerlat_params *params,
struct timerlat_u_params *params_u)
{
@@ -964,22 +978,9 @@ timerlat_top_bpf_main_loop(struct osnoise_tool *top,
return 0;
}
- if (params->quiet) {
- /* Quiet mode: wait for stop and then, print results */
- timerlat_bpf_wait(-1);
-
- retval = timerlat_top_bpf_pull_data(top);
- if (retval) {
- err_msg("Error pulling BPF data\n");
- return retval;
- }
-
- return 0;
- }
-
/* Pull and display data in a loop */
while (!stop_tracing) {
- wait_retval = timerlat_bpf_wait(params->sleep_time);
+ wait_retval = timerlat_bpf_wait(params->quiet ? -1 : params->sleep_time);
retval = timerlat_top_bpf_pull_data(top);
if (retval) {
@@ -987,11 +988,24 @@ timerlat_top_bpf_main_loop(struct osnoise_tool *top,
return retval;
}
- timerlat_print_stats(params, top);
+ if (!params->quiet)
+ timerlat_print_stats(params, top);
- if (wait_retval == 1)
+ if (wait_retval == 1) {
/* Stopping requested by tracer */
- break;
+ actions_perform(¶ms->actions);
+
+ if (!params->actions.continue_flag)
+ /* continue flag not set, break */
+ break;
+
+ /* continue action reached, re-enable tracing */
+ if (params->actions.present[ACTION_TRACE_OUTPUT])
+ trace_instance_start(&record->trace);
+ if (!params->no_aa)
+ trace_instance_start(&aa->trace);
+ timerlat_bpf_restart_tracing();
+ }
/* is there still any user-threads ? */
if (params->user_workload) {
@@ -1205,9 +1219,9 @@ int timerlat_top_main(int argc, char *argv[])
timerlat_top_set_signals(params);
if (params->mode == TRACING_MODE_TRACEFS)
- retval = timerlat_top_main_loop(top, record, params, ¶ms_u);
+ retval = timerlat_top_main_loop(top, record, aa, params, ¶ms_u);
else
- retval = timerlat_top_bpf_main_loop(top, record, params, ¶ms_u);
+ retval = timerlat_top_bpf_main_loop(top, record, aa, params, ¶ms_u);
if (retval)
goto out_top;
@@ -1230,7 +1244,6 @@ int timerlat_top_main(int argc, char *argv[])
if (!params->no_aa)
timerlat_auto_analysis(params->stop_us, params->stop_total_us);
- actions_perform(¶ms->actions);
return_value = FAILED;
} else if (params->aa_only) {
/*
--
2.47.2
next prev parent reply other threads:[~2025-07-21 23:11 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-21 23:12 [for-next][PATCH 0/9] tracing/tools: Updates for v6.17 Steven Rostedt
2025-07-21 23:12 ` [for-next][PATCH 1/9] rtla/timerlat: Introduce enum timerlat_tracing_mode Steven Rostedt
2025-07-21 23:12 ` [for-next][PATCH 2/9] rtla/timerlat: Add action on threshold feature Steven Rostedt
2025-07-21 23:12 ` [for-next][PATCH 3/9] rtla/timerlat_bpf: Allow resuming tracing Steven Rostedt
2025-07-21 23:12 ` Steven Rostedt [this message]
2025-07-21 23:12 ` [for-next][PATCH 5/9] rtla/timerlat: Add action on end feature Steven Rostedt
2025-07-21 23:12 ` [for-next][PATCH 6/9] rtla/tests: Check rtla output with grep Steven Rostedt
2025-07-21 23:12 ` [for-next][PATCH 7/9] rtla/tests: Add tests for actions Steven Rostedt
2025-07-21 23:12 ` [for-next][PATCH 8/9] rtla/tests: Limit duration to maximum of 10s Steven Rostedt
2025-07-21 23:12 ` [for-next][PATCH 9/9] Documentation/rtla: Add actions feature Steven Rostedt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250721231222.797319180@kernel.org \
--to=rostedt@kernel.org \
--cc=acme@kernel.org \
--cc=costa.shul@redhat.com \
--cc=crwood@redhat.com \
--cc=cyin@redhat.com \
--cc=gmonaco@redhat.com \
--cc=jkacur@redhat.com \
--cc=lgoncalv@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=tglozar@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.