Skip to content

Commit 7d0dc95

Browse files
Daniel Bristot de Oliveirarostedt
authored andcommitted
rtla/timerlat: Add --dma-latency option
Add the --dma-latency to set /dev/cpu_dma_latency to the specified value, this aims to avoid having exit from idle states latencies that could be influencing the analysis. Link: https://lkml.kernel.org/r/72ddb0d913459f13217086dadafad88a7c46dd28.1646247211.git.bristot@kernel.org Cc: Daniel Bristot de Oliveira <bristot@kernel.org> Cc: Clark Williams <williams@redhat.com> Cc: Juri Lelli <juri.lelli@redhat.com> 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 7d38c35 commit 7d0dc95

5 files changed

Lines changed: 91 additions & 4 deletions

File tree

Documentation/tools/rtla/common_timerlat_options.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,8 @@
2121

2222
Save the stack trace at the *IRQ* if a *Thread* latency is higher than the
2323
argument in us.
24+
25+
**--dma-latency** *us*
26+
Set the /dev/cpu_dma_latency to *us*, aiming to bound exit from idle latencies.
27+
*cyclictest* sets this value to *0* by default, use **--dma-latency** *0* to have
28+
similar results.

tools/tracing/rtla/src/timerlat_hist.c

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ struct timerlat_hist_params {
2828
int output_divisor;
2929
int duration;
3030
int set_sched;
31+
int dma_latency;
3132
struct sched_attr sched_param;
3233
struct trace_events *events;
3334

@@ -432,7 +433,7 @@ static void timerlat_hist_usage(char *usage)
432433
" usage: [rtla] timerlat hist [-h] [-q] [-d s] [-D] [-n] [-a us] [-p us] [-i us] [-T us] [-s us] \\",
433434
" [-t[=file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] [-c cpu-list] \\",
434435
" [-P priority] [-E N] [-b N] [--no-irq] [--no-thread] [--no-header] [--no-summary] \\",
435-
" [--no-index] [--with-zeros]",
436+
" [--no-index] [--with-zeros] [--dma-latency us]",
436437
"",
437438
" -h/--help: print this menu",
438439
" -a/--auto: set automatic trace mode, stopping the session if argument in us latency is hit",
@@ -456,6 +457,7 @@ static void timerlat_hist_usage(char *usage)
456457
" --no-summary: do not print summary",
457458
" --no-index: do not print index",
458459
" --with-zeros: print zero only entries",
460+
" --dma-latency us: set /dev/cpu_dma_latency latency <us> to reduce exit from idle latency",
459461
" -P/--priority o:prio|r:prio|f:prio|d:runtime:period : set scheduling parameters",
460462
" o:prio - use SCHED_OTHER with prio",
461463
" r:prio - use SCHED_RR with prio",
@@ -492,6 +494,9 @@ static struct timerlat_hist_params
492494
if (!params)
493495
exit(1);
494496

497+
/* disabled by default */
498+
params->dma_latency = -1;
499+
495500
/* display data in microseconds */
496501
params->output_divisor = 1000;
497502
params->bucket_size = 1;
@@ -522,13 +527,14 @@ static struct timerlat_hist_params
522527
{"with-zeros", no_argument, 0, '5'},
523528
{"trigger", required_argument, 0, '6'},
524529
{"filter", required_argument, 0, '7'},
530+
{"dma-latency", required_argument, 0, '8'},
525531
{0, 0, 0, 0}
526532
};
527533

528534
/* getopt_long stores the option index here. */
529535
int option_index = 0;
530536

531-
c = getopt_long(argc, argv, "a:c:b:d:e:E:Dhi:np:P:s:t::T:0123456:7:",
537+
c = getopt_long(argc, argv, "a:c:b:d:e:E:Dhi:np:P:s:t::T:0123456:7:8:",
532538
long_options, &option_index);
533539

534540
/* detect the end of the options. */
@@ -659,6 +665,13 @@ static struct timerlat_hist_params
659665
timerlat_hist_usage("--filter requires a previous -e\n");
660666
}
661667
break;
668+
case '8':
669+
params->dma_latency = get_llong_from_str(optarg);
670+
if (params->dma_latency < 0 || params->dma_latency > 10000) {
671+
err_msg("--dma-latency needs to be >= 0 and < 10000");
672+
exit(EXIT_FAILURE);
673+
}
674+
break;
662675
default:
663676
timerlat_hist_usage("Invalid option");
664677
}
@@ -791,6 +804,7 @@ int timerlat_hist_main(int argc, char *argv[])
791804
struct osnoise_tool *record = NULL;
792805
struct osnoise_tool *tool = NULL;
793806
struct trace_instance *trace;
807+
int dma_latency_fd = -1;
794808
int return_value = 1;
795809
int retval;
796810

@@ -826,6 +840,14 @@ int timerlat_hist_main(int argc, char *argv[])
826840
}
827841
}
828842

843+
if (params->dma_latency >= 0) {
844+
dma_latency_fd = set_cpu_dma_latency(params->dma_latency);
845+
if (dma_latency_fd < 0) {
846+
err_msg("Could not set /dev/cpu_dma_latency.\n");
847+
goto out_hist;
848+
}
849+
}
850+
829851
trace_instance_start(trace);
830852

831853
if (params->trace_output) {
@@ -878,6 +900,8 @@ int timerlat_hist_main(int argc, char *argv[])
878900
}
879901

880902
out_hist:
903+
if (dma_latency_fd >= 0)
904+
close(dma_latency_fd);
881905
trace_events_destroy(&record->trace, params->events);
882906
params->events = NULL;
883907
timerlat_free_histogram(tool->data);

tools/tracing/rtla/src/timerlat_top.c

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ struct timerlat_top_params {
2929
int duration;
3030
int quiet;
3131
int set_sched;
32+
int dma_latency;
3233
struct sched_attr sched_param;
3334
struct trace_events *events;
3435
};
@@ -269,7 +270,7 @@ static void timerlat_top_usage(char *usage)
269270
"",
270271
" usage: rtla timerlat [top] [-h] [-q] [-a us] [-d s] [-D] [-n] [-p us] [-i us] [-T us] [-s us] \\",
271272
" [[-t[=file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] [-c cpu-list] \\",
272-
" [-P priority]",
273+
" [-P priority] [--dma-latency us]",
273274
"",
274275
" -h/--help: print this menu",
275276
" -a/--auto: set automatic trace mode, stopping the session if argument in us latency is hit",
@@ -286,6 +287,7 @@ static void timerlat_top_usage(char *usage)
286287
" --trigger <command>: enable a trace event trigger to the previous -e event",
287288
" -n/--nano: display data in nanoseconds",
288289
" -q/--quiet print only a summary at the end",
290+
" --dma-latency us: set /dev/cpu_dma_latency latency <us> to reduce exit from idle latency",
289291
" -P/--priority o:prio|r:prio|f:prio|d:runtime:period : set scheduling parameters",
290292
" o:prio - use SCHED_OTHER with prio",
291293
" r:prio - use SCHED_RR with prio",
@@ -322,6 +324,9 @@ static struct timerlat_top_params
322324
if (!params)
323325
exit(1);
324326

327+
/* disabled by default */
328+
params->dma_latency = -1;
329+
325330
/* display data in microseconds */
326331
params->output_divisor = 1000;
327332

@@ -343,13 +348,14 @@ static struct timerlat_top_params
343348
{"trace", optional_argument, 0, 't'},
344349
{"trigger", required_argument, 0, '0'},
345350
{"filter", required_argument, 0, '1'},
351+
{"dma-latency", required_argument, 0, '2'},
346352
{0, 0, 0, 0}
347353
};
348354

349355
/* getopt_long stores the option index here. */
350356
int option_index = 0;
351357

352-
c = getopt_long(argc, argv, "a:c:d:De:hi:np:P:qs:t::T:0:1:",
358+
c = getopt_long(argc, argv, "a:c:d:De:hi:np:P:qs:t::T:0:1:2:",
353359
long_options, &option_index);
354360

355361
/* detect the end of the options. */
@@ -454,6 +460,13 @@ static struct timerlat_top_params
454460
timerlat_top_usage("--filter requires a previous -e\n");
455461
}
456462
break;
463+
case '2': /* dma-latency */
464+
params->dma_latency = get_llong_from_str(optarg);
465+
if (params->dma_latency < 0 || params->dma_latency > 10000) {
466+
err_msg("--dma-latency needs to be >= 0 and < 10000");
467+
exit(EXIT_FAILURE);
468+
}
469+
break;
457470
default:
458471
timerlat_top_usage("Invalid option");
459472
}
@@ -582,6 +595,7 @@ int timerlat_top_main(int argc, char *argv[])
582595
struct osnoise_tool *record = NULL;
583596
struct osnoise_tool *top = NULL;
584597
struct trace_instance *trace;
598+
int dma_latency_fd = -1;
585599
int return_value = 1;
586600
int retval;
587601

@@ -617,6 +631,14 @@ int timerlat_top_main(int argc, char *argv[])
617631
}
618632
}
619633

634+
if (params->dma_latency >= 0) {
635+
dma_latency_fd = set_cpu_dma_latency(params->dma_latency);
636+
if (dma_latency_fd < 0) {
637+
err_msg("Could not set /dev/cpu_dma_latency.\n");
638+
goto out_top;
639+
}
640+
}
641+
620642
trace_instance_start(trace);
621643

622644
if (params->trace_output) {
@@ -673,6 +695,8 @@ int timerlat_top_main(int argc, char *argv[])
673695
}
674696

675697
out_top:
698+
if (dma_latency_fd >= 0)
699+
close(dma_latency_fd);
676700
trace_events_destroy(&record->trace, params->events);
677701
params->events = NULL;
678702
timerlat_free_top(top->data);

tools/tracing/rtla/src/utils.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <unistd.h>
1111
#include <ctype.h>
1212
#include <errno.h>
13+
#include <fcntl.h>
1314
#include <sched.h>
1415
#include <stdio.h>
1516

@@ -431,3 +432,35 @@ int parse_prio(char *arg, struct sched_attr *sched_param)
431432
}
432433
return 0;
433434
}
435+
436+
/*
437+
* set_cpu_dma_latency - set the /dev/cpu_dma_latecy
438+
*
439+
* This is used to reduce the exit from idle latency. The value
440+
* will be reset once the file descriptor of /dev/cpu_dma_latecy
441+
* is closed.
442+
*
443+
* Return: the /dev/cpu_dma_latecy file descriptor
444+
*/
445+
int set_cpu_dma_latency(int32_t latency)
446+
{
447+
int retval;
448+
int fd;
449+
450+
fd = open("/dev/cpu_dma_latency", O_RDWR);
451+
if (fd < 0) {
452+
err_msg("Error opening /dev/cpu_dma_latency\n");
453+
return -1;
454+
}
455+
456+
retval = write(fd, &latency, 4);
457+
if (retval < 1) {
458+
err_msg("Error setting /dev/cpu_dma_latency\n");
459+
close(fd);
460+
return -1;
461+
}
462+
463+
debug_msg("Set /dev/cpu_dma_latency to %d\n", latency);
464+
465+
return fd;
466+
}

tools/tracing/rtla/src/utils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,4 @@ struct sched_attr {
5454

5555
int parse_prio(char *arg, struct sched_attr *sched_param);
5656
int set_comm_sched_attr(const char *comm, struct sched_attr *attr);
57+
int set_cpu_dma_latency(int32_t latency);

0 commit comments

Comments
 (0)