rtla/timerlat: Add action on end feature
Implement actions on end next to actions on threshold. A new option, --on-end is added, parallel to --on-threshold. Instead of being executed whenever a latency threshold is reached, it is executed at the end of the measurement. For example: $ rtla timerlat hist -d 5s --on-end trace will save the trace output at the end. All actions supported by --on-threshold are also supported by --on-end, except for continue, which does nothing with --on-end. 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-6-tglozar@redhat.com Signed-off-by: Tomas Glozar <tglozar@redhat.com> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>pull/1320/head
parent
8d933d5c89
commit
3aadb65db5
|
|
@ -48,7 +48,10 @@ struct timerlat_params {
|
|||
struct sched_attr sched_param;
|
||||
struct trace_events *events;
|
||||
enum timerlat_tracing_mode mode;
|
||||
struct actions actions;
|
||||
|
||||
struct actions threshold_actions;
|
||||
struct actions end_actions;
|
||||
|
||||
union {
|
||||
struct {
|
||||
/* top only */
|
||||
|
|
|
|||
|
|
@ -758,6 +758,7 @@ static void timerlat_hist_usage(char *usage)
|
|||
" --trace-buffer-size kB: set the per-cpu trace buffer size in kB",
|
||||
" --deepest-idle-state n: only go down to idle state n on cpus used by timerlat to reduce exit from idle latency",
|
||||
" --on-threshold <action>: define action to be executed at latency threshold, multiple are allowed",
|
||||
" --on-end <action>: define action to be executed at measurement end, multiple are allowed",
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
@ -793,7 +794,8 @@ static struct timerlat_params
|
|||
if (!params)
|
||||
exit(1);
|
||||
|
||||
actions_init(¶ms->actions);
|
||||
actions_init(¶ms->threshold_actions);
|
||||
actions_init(¶ms->end_actions);
|
||||
|
||||
/* disabled by default */
|
||||
params->dma_latency = -1;
|
||||
|
|
@ -846,6 +848,7 @@ static struct timerlat_params
|
|||
{"trace-buffer-size", required_argument, 0, '\3'},
|
||||
{"deepest-idle-state", required_argument, 0, '\4'},
|
||||
{"on-threshold", required_argument, 0, '\5'},
|
||||
{"on-end", required_argument, 0, '\6'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
|
@ -1038,7 +1041,14 @@ static struct timerlat_params
|
|||
params->deepest_idle_state = get_llong_from_str(optarg);
|
||||
break;
|
||||
case '\5':
|
||||
retval = actions_parse(¶ms->actions, optarg);
|
||||
retval = actions_parse(¶ms->threshold_actions, optarg);
|
||||
if (retval) {
|
||||
err_msg("Invalid action %s\n", optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case '\6':
|
||||
retval = actions_parse(¶ms->end_actions, optarg);
|
||||
if (retval) {
|
||||
err_msg("Invalid action %s\n", optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
@ -1050,7 +1060,7 @@ static struct timerlat_params
|
|||
}
|
||||
|
||||
if (trace_output)
|
||||
actions_add_trace_output(¶ms->actions, trace_output);
|
||||
actions_add_trace_output(¶ms->threshold_actions, trace_output);
|
||||
|
||||
if (geteuid()) {
|
||||
err_msg("rtla needs root permission\n");
|
||||
|
|
@ -1077,7 +1087,8 @@ static struct timerlat_params
|
|||
* mixed mode
|
||||
*/
|
||||
if (params->mode == TRACING_MODE_BPF &&
|
||||
(params->actions.present[ACTION_TRACE_OUTPUT] || !params->no_aa))
|
||||
(params->threshold_actions.present[ACTION_TRACE_OUTPUT] ||
|
||||
params->end_actions.present[ACTION_TRACE_OUTPUT] || !params->no_aa))
|
||||
params->mode = TRACING_MODE_MIXED;
|
||||
|
||||
return params;
|
||||
|
|
@ -1270,13 +1281,15 @@ int timerlat_hist_main(int argc, char *argv[])
|
|||
}
|
||||
}
|
||||
|
||||
if (params->actions.present[ACTION_TRACE_OUTPUT]) {
|
||||
if (params->threshold_actions.present[ACTION_TRACE_OUTPUT] ||
|
||||
params->end_actions.present[ACTION_TRACE_OUTPUT]) {
|
||||
record = osnoise_init_trace_tool("timerlat");
|
||||
if (!record) {
|
||||
err_msg("Failed to enable the trace instance\n");
|
||||
goto out_free;
|
||||
}
|
||||
params->actions.trace_output_inst = record->trace.inst;
|
||||
params->threshold_actions.trace_output_inst = record->trace.inst;
|
||||
params->end_actions.trace_output_inst = record->trace.inst;
|
||||
|
||||
if (params->events) {
|
||||
retval = trace_events_enable(&record->trace, params->events);
|
||||
|
|
@ -1342,7 +1355,7 @@ int timerlat_hist_main(int argc, char *argv[])
|
|||
* tracing while enabling other instances. The trace instance is the
|
||||
* one with most valuable information.
|
||||
*/
|
||||
if (params->actions.present[ACTION_TRACE_OUTPUT])
|
||||
if (record)
|
||||
trace_instance_start(&record->trace);
|
||||
if (!params->no_aa)
|
||||
trace_instance_start(&aa->trace);
|
||||
|
|
@ -1375,14 +1388,14 @@ int timerlat_hist_main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
if (osnoise_trace_is_off(tool, record)) {
|
||||
actions_perform(¶ms->actions);
|
||||
actions_perform(¶ms->threshold_actions);
|
||||
|
||||
if (!params->actions.continue_flag)
|
||||
if (!params->threshold_actions.continue_flag)
|
||||
/* continue flag not set, break */
|
||||
break;
|
||||
|
||||
/* continue action reached, re-enable tracing */
|
||||
if (params->actions.present[ACTION_TRACE_OUTPUT])
|
||||
if (record)
|
||||
trace_instance_start(&record->trace);
|
||||
if (!params->no_aa)
|
||||
trace_instance_start(&aa->trace);
|
||||
|
|
@ -1403,14 +1416,14 @@ int timerlat_hist_main(int argc, char *argv[])
|
|||
|
||||
if (!stop_tracing) {
|
||||
/* Threshold overflow, perform actions on threshold */
|
||||
actions_perform(¶ms->actions);
|
||||
actions_perform(¶ms->threshold_actions);
|
||||
|
||||
if (!params->actions.continue_flag)
|
||||
if (!params->threshold_actions.continue_flag)
|
||||
/* continue flag not set, break */
|
||||
break;
|
||||
|
||||
/* continue action reached, re-enable tracing */
|
||||
if (params->actions.present[ACTION_TRACE_OUTPUT])
|
||||
if (record)
|
||||
trace_instance_start(&record->trace);
|
||||
if (!params->no_aa)
|
||||
trace_instance_start(&aa->trace);
|
||||
|
|
@ -1435,6 +1448,8 @@ int timerlat_hist_main(int argc, char *argv[])
|
|||
|
||||
timerlat_print_stats(params, tool);
|
||||
|
||||
actions_perform(¶ms->end_actions);
|
||||
|
||||
return_value = PASSED;
|
||||
|
||||
if (osnoise_trace_is_off(tool, record) && !stop_tracing) {
|
||||
|
|
@ -1464,7 +1479,8 @@ out_free:
|
|||
osnoise_destroy_tool(aa);
|
||||
osnoise_destroy_tool(record);
|
||||
osnoise_destroy_tool(tool);
|
||||
actions_destroy(¶ms->actions);
|
||||
actions_destroy(¶ms->threshold_actions);
|
||||
actions_destroy(¶ms->end_actions);
|
||||
if (params->mode != TRACING_MODE_TRACEFS)
|
||||
timerlat_bpf_destroy();
|
||||
free(params);
|
||||
|
|
|
|||
|
|
@ -517,6 +517,7 @@ static void timerlat_top_usage(char *usage)
|
|||
" --trace-buffer-size kB: set the per-cpu trace buffer size in kB",
|
||||
" --deepest-idle-state n: only go down to idle state n on cpus used by timerlat to reduce exit from idle latency",
|
||||
" --on-threshold <action>: define action to be executed at latency threshold, multiple are allowed",
|
||||
" --on-end: define action to be executed at measurement end, multiple are allowed",
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
@ -552,7 +553,8 @@ static struct timerlat_params
|
|||
if (!params)
|
||||
exit(1);
|
||||
|
||||
actions_init(¶ms->actions);
|
||||
actions_init(¶ms->threshold_actions);
|
||||
actions_init(¶ms->end_actions);
|
||||
|
||||
/* disabled by default */
|
||||
params->dma_latency = -1;
|
||||
|
|
@ -597,6 +599,7 @@ static struct timerlat_params
|
|||
{"trace-buffer-size", required_argument, 0, '7'},
|
||||
{"deepest-idle-state", required_argument, 0, '8'},
|
||||
{"on-threshold", required_argument, 0, '9'},
|
||||
{"on-end", required_argument, 0, '\1'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
|
@ -623,6 +626,7 @@ static struct timerlat_params
|
|||
|
||||
/* set trace */
|
||||
trace_output = "timerlat_trace.txt";
|
||||
|
||||
break;
|
||||
case '5':
|
||||
/* it is here because it is similar to -a */
|
||||
|
|
@ -776,7 +780,14 @@ static struct timerlat_params
|
|||
params->deepest_idle_state = get_llong_from_str(optarg);
|
||||
break;
|
||||
case '9':
|
||||
retval = actions_parse(¶ms->actions, optarg);
|
||||
retval = actions_parse(¶ms->threshold_actions, optarg);
|
||||
if (retval) {
|
||||
err_msg("Invalid action %s\n", optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case '\1':
|
||||
retval = actions_parse(¶ms->end_actions, optarg);
|
||||
if (retval) {
|
||||
err_msg("Invalid action %s\n", optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
@ -788,7 +799,7 @@ static struct timerlat_params
|
|||
}
|
||||
|
||||
if (trace_output)
|
||||
actions_add_trace_output(¶ms->actions, trace_output);
|
||||
actions_add_trace_output(¶ms->threshold_actions, trace_output);
|
||||
|
||||
if (geteuid()) {
|
||||
err_msg("rtla needs root permission\n");
|
||||
|
|
@ -812,7 +823,8 @@ static struct timerlat_params
|
|||
* mixed mode
|
||||
*/
|
||||
if (params->mode == TRACING_MODE_BPF &&
|
||||
(params->actions.present[ACTION_TRACE_OUTPUT] || !params->no_aa))
|
||||
(params->threshold_actions.present[ACTION_TRACE_OUTPUT] ||
|
||||
params->end_actions.present[ACTION_TRACE_OUTPUT] || !params->no_aa))
|
||||
params->mode = TRACING_MODE_MIXED;
|
||||
|
||||
return params;
|
||||
|
|
@ -934,14 +946,14 @@ timerlat_top_main_loop(struct osnoise_tool *top,
|
|||
timerlat_print_stats(params, top);
|
||||
|
||||
if (osnoise_trace_is_off(top, record)) {
|
||||
actions_perform(¶ms->actions);
|
||||
actions_perform(¶ms->threshold_actions);
|
||||
|
||||
if (!params->actions.continue_flag)
|
||||
if (!params->threshold_actions.continue_flag)
|
||||
/* continue flag not set, break */
|
||||
break;
|
||||
|
||||
/* continue action reached, re-enable tracing */
|
||||
if (params->actions.present[ACTION_TRACE_OUTPUT])
|
||||
if (record)
|
||||
trace_instance_start(&record->trace);
|
||||
if (!params->no_aa)
|
||||
trace_instance_start(&aa->trace);
|
||||
|
|
@ -993,14 +1005,14 @@ timerlat_top_bpf_main_loop(struct osnoise_tool *top,
|
|||
|
||||
if (wait_retval == 1) {
|
||||
/* Stopping requested by tracer */
|
||||
actions_perform(¶ms->actions);
|
||||
actions_perform(¶ms->threshold_actions);
|
||||
|
||||
if (!params->actions.continue_flag)
|
||||
if (!params->threshold_actions.continue_flag)
|
||||
/* continue flag not set, break */
|
||||
break;
|
||||
|
||||
/* continue action reached, re-enable tracing */
|
||||
if (params->actions.present[ACTION_TRACE_OUTPUT])
|
||||
if (record)
|
||||
trace_instance_start(&record->trace);
|
||||
if (!params->no_aa)
|
||||
trace_instance_start(&aa->trace);
|
||||
|
|
@ -1128,13 +1140,15 @@ int timerlat_top_main(int argc, char *argv[])
|
|||
}
|
||||
}
|
||||
|
||||
if (params->actions.present[ACTION_TRACE_OUTPUT]) {
|
||||
if (params->threshold_actions.present[ACTION_TRACE_OUTPUT] ||
|
||||
params->end_actions.present[ACTION_TRACE_OUTPUT]) {
|
||||
record = osnoise_init_trace_tool("timerlat");
|
||||
if (!record) {
|
||||
err_msg("Failed to enable the trace instance\n");
|
||||
goto out_free;
|
||||
}
|
||||
params->actions.trace_output_inst = record->trace.inst;
|
||||
params->threshold_actions.trace_output_inst = record->trace.inst;
|
||||
params->end_actions.trace_output_inst = record->trace.inst;
|
||||
|
||||
if (params->events) {
|
||||
retval = trace_events_enable(&record->trace, params->events);
|
||||
|
|
@ -1201,7 +1215,7 @@ int timerlat_top_main(int argc, char *argv[])
|
|||
* tracing while enabling other instances. The trace instance is the
|
||||
* one with most valuable information.
|
||||
*/
|
||||
if (params->actions.present[ACTION_TRACE_OUTPUT])
|
||||
if (record)
|
||||
trace_instance_start(&record->trace);
|
||||
if (!params->no_aa)
|
||||
trace_instance_start(&aa->trace);
|
||||
|
|
@ -1236,6 +1250,8 @@ int timerlat_top_main(int argc, char *argv[])
|
|||
|
||||
timerlat_print_stats(params, top);
|
||||
|
||||
actions_perform(¶ms->end_actions);
|
||||
|
||||
return_value = PASSED;
|
||||
|
||||
if (osnoise_trace_is_off(top, record) && !stop_tracing) {
|
||||
|
|
@ -1276,7 +1292,8 @@ out_free:
|
|||
osnoise_destroy_tool(aa);
|
||||
osnoise_destroy_tool(record);
|
||||
osnoise_destroy_tool(top);
|
||||
actions_destroy(¶ms->actions);
|
||||
actions_destroy(¶ms->threshold_actions);
|
||||
actions_destroy(¶ms->end_actions);
|
||||
if (params->mode != TRACING_MODE_TRACEFS)
|
||||
timerlat_bpf_destroy();
|
||||
free(params);
|
||||
|
|
|
|||
Loading…
Reference in New Issue