Skip to content

Commit 9fa48a2

Browse files
Daniel Bristot de Oliveirarostedt
authored andcommitted
rtla/timerlat: Add auto-analysis only option
Parsing and formating timerlat data might consume a reasonable amount of CPU time on very large systems, or when timerlat has a too short period. Add an option to run timerlat with auto-analysis enabled while skipping the statistics parsing. In this mode, rtla timerlat periodically checks if the tracing is on, going to sleep waiting for the stop tracing condition to stop tracing, or for the tracing session to finish. If the stop tracing condition is hit, the tool prints the auto analysis. Otherwise, the tool prints the max observed latency and exit. The max observed latency is captured via tracing_max_latency. Link: https://lore.kernel.org/linux-trace-devel/4dc514d1d5dc353c537a466a9b5af44c266b6da2.1680106912.git.bristot@kernel.org Cc: Jonathan Corbet <corbet@lwn.net> Signed-off-by: Daniel Bristot de Oliveira <bristot@kernel.org> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
1 parent 73e053c commit 9fa48a2

2 files changed

Lines changed: 51 additions & 5 deletions

File tree

Documentation/tools/rtla/common_timerlat_aa.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,10 @@
55
**--no-aa**
66

77
disable auto-analysis, reducing rtla timerlat cpu usage
8+
9+
**--aa-only** *us*
10+
11+
Set stop tracing conditions and run without collecting and displaying statistics.
12+
Print the auto-analysis if the system hits the stop tracing condition. This option
13+
is useful to reduce rtla timerlat CPU, enabling the debug without the overhead of
14+
collecting the statistics.

tools/tracing/rtla/src/timerlat_top.c

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ struct timerlat_top_params {
3333
int set_sched;
3434
int dma_latency;
3535
int no_aa;
36+
int aa_only;
3637
int dump_tasks;
3738
struct sched_attr sched_param;
3839
struct trace_events *events;
@@ -142,10 +143,12 @@ timerlat_top_handler(struct trace_seq *s, struct tep_record *record,
142143
top = container_of(trace, struct osnoise_tool, trace);
143144
params = top->params;
144145

145-
tep_get_field_val(s, event, "context", record, &thread, 1);
146-
tep_get_field_val(s, event, "timer_latency", record, &latency, 1);
146+
if (!params->aa_only) {
147+
tep_get_field_val(s, event, "context", record, &thread, 1);
148+
tep_get_field_val(s, event, "timer_latency", record, &latency, 1);
147149

148-
timerlat_top_update(top, cpu, thread, latency);
150+
timerlat_top_update(top, cpu, thread, latency);
151+
}
149152

150153
if (!params->no_aa)
151154
timerlat_aa_handler(s, record, event, context);
@@ -250,6 +253,9 @@ timerlat_print_stats(struct timerlat_top_params *params, struct osnoise_tool *to
250253
static int nr_cpus = -1;
251254
int i;
252255

256+
if (params->aa_only)
257+
return;
258+
253259
if (nr_cpus == -1)
254260
nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
255261

@@ -279,10 +285,11 @@ static void timerlat_top_usage(char *usage)
279285
"",
280286
" usage: rtla timerlat [top] [-h] [-q] [-a us] [-d s] [-D] [-n] [-p us] [-i us] [-T us] [-s us] \\",
281287
" [[-t[=file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] [-c cpu-list] \\",
282-
" [-P priority] [--dma-latency us]",
288+
" [-P priority] [--dma-latency us] [--aa-only us]",
283289
"",
284290
" -h/--help: print this menu",
285291
" -a/--auto: set automatic trace mode, stopping the session if argument in us latency is hit",
292+
" --aa-only us: stop if <us> latency is hit, only printing the auto analysis (reduces CPU usage)",
286293
" -p/--period us: timerlat period in us",
287294
" -i/--irq us: stop trace if the irq latency is higher than the argument in us",
288295
" -T/--thread us: stop trace if the thread latency is higher than the argument in us",
@@ -362,13 +369,14 @@ static struct timerlat_top_params
362369
{"dma-latency", required_argument, 0, '2'},
363370
{"no-aa", no_argument, 0, '3'},
364371
{"dump-tasks", no_argument, 0, '4'},
372+
{"aa-only", required_argument, 0, '5'},
365373
{0, 0, 0, 0}
366374
};
367375

368376
/* getopt_long stores the option index here. */
369377
int option_index = 0;
370378

371-
c = getopt_long(argc, argv, "a:c:d:De:hi:np:P:qs:t::T:0:1:2:34",
379+
c = getopt_long(argc, argv, "a:c:d:De:hi:np:P:qs:t::T:0:1:2:345:",
372380
long_options, &option_index);
373381

374382
/* detect the end of the options. */
@@ -389,6 +397,20 @@ static struct timerlat_top_params
389397
/* set trace */
390398
params->trace_output = "timerlat_trace.txt";
391399
break;
400+
case '5':
401+
/* it is here because it is similar to -a */
402+
auto_thresh = get_llong_from_str(optarg);
403+
404+
/* set thread stop to auto_thresh */
405+
params->stop_total_us = auto_thresh;
406+
params->stop_us = auto_thresh;
407+
408+
/* get stack trace */
409+
params->print_stack = auto_thresh;
410+
411+
/* set aa_only to avoid parsing the trace */
412+
params->aa_only = 1;
413+
break;
392414
case 'c':
393415
retval = parse_cpu_list(optarg, &params->monitored_cpus);
394416
if (retval)
@@ -503,6 +525,9 @@ static struct timerlat_top_params
503525
if (!params->stop_us && !params->stop_total_us)
504526
params->no_aa = 1;
505527

528+
if (params->no_aa && params->aa_only)
529+
timerlat_top_usage("--no-aa and --aa-only are mutually exclusive!");
530+
506531
return params;
507532
}
508533

@@ -634,6 +659,7 @@ int timerlat_top_main(int argc, char *argv[])
634659
struct trace_instance *trace;
635660
int dma_latency_fd = -1;
636661
int return_value = 1;
662+
char *max_lat;
637663
int retval;
638664

639665
params = timerlat_top_parse_args(argc, argv);
@@ -700,6 +726,9 @@ int timerlat_top_main(int argc, char *argv[])
700726
while (!stop_tracing) {
701727
sleep(params->sleep_time);
702728

729+
if (params->aa_only && !trace_is_off(&top->trace, &record->trace))
730+
continue;
731+
703732
retval = tracefs_iterate_raw_events(trace->tep,
704733
trace->inst,
705734
NULL,
@@ -733,6 +762,16 @@ int timerlat_top_main(int argc, char *argv[])
733762
printf(" Saving trace to %s\n", params->trace_output);
734763
save_trace_to_file(record->trace.inst, params->trace_output);
735764
}
765+
} else if (params->aa_only) {
766+
/*
767+
* If the trace did not stop with --aa-only, at least print the
768+
* max known latency.
769+
*/
770+
max_lat = tracefs_instance_file_read(trace->inst, "tracing_max_latency", NULL);
771+
if (max_lat) {
772+
printf(" Max latency was %s\n", max_lat);
773+
free(max_lat);
774+
}
736775
}
737776

738777
out_top:

0 commit comments

Comments
 (0)