Skip to content

Commit cdbf719

Browse files
author
Daniel Bristot de Oliveira
committed
rtla: Add the --warm-up option
On many cases, the results right after the startup are different from the rest of the execution, biasing the results. For example, on osnoise, the scheduler might take some time to adapt to the new busy-loop workload. Add the --warm-up <seconds> option, adding a warm-up phase (in seconds) where the workload is set, but the results are discarded. Link: https://lkml.kernel.org/r/e682d5ce5af90f123bd13220f63d5c3d118a92be.1713968967.git.bristot@kernel.org Cc: Jonathan Corbet <[email protected]> Cc: Juri Lelli <[email protected]> Signed-off-by: Daniel Bristot de Oliveira <[email protected]>
1 parent 1462501 commit cdbf719

File tree

5 files changed

+119
-40
lines changed

5 files changed

+119
-40
lines changed

Documentation/tools/rtla/common_options.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@
5050

5151
Set a *cgroup* to the tracer's threads. If the **-C** option is passed without arguments, the tracer's thread will inherit **rtla**'s *cgroup*. Otherwise, the threads will be placed on the *cgroup* passed to the option.
5252

53+
**--warm-up** *s*
54+
55+
After starting the workload, let it run for *s* seconds before starting collecting the data, allowing the system to warm-up. Statistical data generated during warm-up is discarded.
56+
5357
**-h**, **--help**
5458

5559
Print help menu.

tools/tracing/rtla/src/osnoise_hist.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ struct osnoise_hist_params {
3636
cpu_set_t hk_cpu_set;
3737
struct sched_attr sched_param;
3838
struct trace_events *events;
39-
4039
char no_header;
4140
char no_summary;
4241
char no_index;
4342
char with_zeros;
4443
int bucket_size;
4544
int entries;
45+
int warmup;
4646
};
4747

4848
struct osnoise_hist_cpu {
@@ -438,7 +438,7 @@ static void osnoise_hist_usage(char *usage)
438438
" usage: rtla osnoise hist [-h] [-D] [-d s] [-a us] [-p us] [-r us] [-s us] [-S us] \\",
439439
" [-T us] [-t[=file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] \\",
440440
" [-c cpu-list] [-H cpu-list] [-P priority] [-b N] [-E N] [--no-header] [--no-summary] \\",
441-
" [--no-index] [--with-zeros] [-C[=cgroup_name]]",
441+
" [--no-index] [--with-zeros] [-C[=cgroup_name]] [--warm-up]",
442442
"",
443443
" -h/--help: print this menu",
444444
" -a/--auto: set automatic trace mode, stopping the session if argument in us sample is hit",
@@ -468,6 +468,7 @@ static void osnoise_hist_usage(char *usage)
468468
" f:prio - use SCHED_FIFO with prio",
469469
" d:runtime[us|ms|s]:period[us|ms|s] - use SCHED_DEADLINE with runtime and period",
470470
" in nanoseconds",
471+
" --warm-up: let the workload run for s seconds before collecting data",
471472
NULL,
472473
};
473474

@@ -531,13 +532,14 @@ static struct osnoise_hist_params
531532
{"with-zeros", no_argument, 0, '3'},
532533
{"trigger", required_argument, 0, '4'},
533534
{"filter", required_argument, 0, '5'},
535+
{"warm-up", required_argument, 0, '6'},
534536
{0, 0, 0, 0}
535537
};
536538

537539
/* getopt_long stores the option index here. */
538540
int option_index = 0;
539541

540-
c = getopt_long(argc, argv, "a:c:C::b:d:e:E:DhH:p:P:r:s:S:t::T:01234:5:",
542+
c = getopt_long(argc, argv, "a:c:C::b:d:e:E:DhH:p:P:r:s:S:t::T:01234:5:6:",
541543
long_options, &option_index);
542544

543545
/* detect the end of the options. */
@@ -680,6 +682,9 @@ static struct osnoise_hist_params
680682
osnoise_hist_usage("--filter requires a previous -e\n");
681683
}
682684
break;
685+
case '6':
686+
params->warmup = get_llong_from_str(optarg);
687+
break;
683688
default:
684689
osnoise_hist_usage("Invalid option");
685690
}
@@ -899,6 +904,25 @@ int osnoise_hist_main(int argc, char *argv[])
899904
trace_instance_start(&record->trace);
900905
trace_instance_start(trace);
901906

907+
if (params->warmup > 0) {
908+
debug_msg("Warming up for %d seconds\n", params->warmup);
909+
sleep(params->warmup);
910+
if (stop_tracing)
911+
goto out_hist;
912+
913+
/*
914+
* Clean up the buffer. The osnoise workload do not run
915+
* with tracing off to avoid creating a performance penalty
916+
* when not needed.
917+
*/
918+
retval = tracefs_instance_file_write(trace->inst, "trace", "");
919+
if (retval < 0) {
920+
debug_msg("Error cleaning up the buffer");
921+
goto out_hist;
922+
}
923+
924+
}
925+
902926
tool->start_time = time(NULL);
903927
osnoise_hist_set_signals(params);
904928

tools/tracing/rtla/src/osnoise_top.c

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ struct osnoise_top_params {
4040
int set_sched;
4141
int cgroup;
4242
int hk_cpus;
43+
int warmup;
4344
cpu_set_t hk_cpu_set;
4445
struct sched_attr sched_param;
4546
struct trace_events *events;
@@ -282,7 +283,7 @@ static void osnoise_top_usage(struct osnoise_top_params *params, char *usage)
282283
static const char * const msg[] = {
283284
" [-h] [-q] [-D] [-d s] [-a us] [-p us] [-r us] [-s us] [-S us] \\",
284285
" [-T us] [-t[=file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] \\",
285-
" [-c cpu-list] [-H cpu-list] [-P priority] [-C[=cgroup_name]]",
286+
" [-c cpu-list] [-H cpu-list] [-P priority] [-C[=cgroup_name]] [--warm-up s]",
286287
"",
287288
" -h/--help: print this menu",
288289
" -a/--auto: set automatic trace mode, stopping the session if argument in us sample is hit",
@@ -307,6 +308,7 @@ static void osnoise_top_usage(struct osnoise_top_params *params, char *usage)
307308
" f:prio - use SCHED_FIFO with prio",
308309
" d:runtime[us|ms|s]:period[us|ms|s] - use SCHED_DEADLINE with runtime and period",
309310
" in nanoseconds",
311+
" --warm-up s: let the workload run for s seconds before collecting data",
310312
NULL,
311313
};
312314

@@ -381,13 +383,14 @@ struct osnoise_top_params *osnoise_top_parse_args(int argc, char **argv)
381383
{"trace", optional_argument, 0, 't'},
382384
{"trigger", required_argument, 0, '0'},
383385
{"filter", required_argument, 0, '1'},
386+
{"warm-up", required_argument, 0, '2'},
384387
{0, 0, 0, 0}
385388
};
386389

387390
/* getopt_long stores the option index here. */
388391
int option_index = 0;
389392

390-
c = getopt_long(argc, argv, "a:c:C::d:De:hH:p:P:qr:s:S:t::T:0:1:",
393+
c = getopt_long(argc, argv, "a:c:C::d:De:hH:p:P:qr:s:S:t::T:0:1:2:",
391394
long_options, &option_index);
392395

393396
/* Detect the end of the options. */
@@ -511,6 +514,9 @@ struct osnoise_top_params *osnoise_top_parse_args(int argc, char **argv)
511514
osnoise_top_usage(params, "--filter requires a previous -e\n");
512515
}
513516
break;
517+
case '2':
518+
params->warmup = get_llong_from_str(optarg);
519+
break;
514520
default:
515521
osnoise_top_usage(params, "Invalid option");
516522
}
@@ -732,6 +738,25 @@ int osnoise_top_main(int argc, char **argv)
732738
trace_instance_start(&record->trace);
733739
trace_instance_start(trace);
734740

741+
if (params->warmup > 0) {
742+
debug_msg("Warming up for %d seconds\n", params->warmup);
743+
sleep(params->warmup);
744+
if (stop_tracing)
745+
goto out_top;
746+
747+
/*
748+
* Clean up the buffer. The osnoise workload do not run
749+
* with tracing off to avoid creating a performance penalty
750+
* when not needed.
751+
*/
752+
retval = tracefs_instance_file_write(trace->inst, "trace", "");
753+
if (retval < 0) {
754+
debug_msg("Error cleaning up the buffer");
755+
goto out_top;
756+
}
757+
758+
}
759+
735760
tool->start_time = time(NULL);
736761
osnoise_top_set_signals(params);
737762

tools/tracing/rtla/src/timerlat_hist.c

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ struct timerlat_hist_params {
5252
char with_zeros;
5353
int bucket_size;
5454
int entries;
55+
int warmup;
5556
};
5657

5758
struct timerlat_hist_cpu {
@@ -628,6 +629,7 @@ static void timerlat_hist_usage(char *usage)
628629
" [-t[=file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] [-c cpu-list] [-H cpu-list]\\",
629630
" [-P priority] [-E N] [-b N] [--no-irq] [--no-thread] [--no-header] [--no-summary] \\",
630631
" [--no-index] [--with-zeros] [--dma-latency us] [-C[=cgroup_name]] [--no-aa] [--dump-task] [-u]",
632+
" [--warm-up s]",
631633
"",
632634
" -h/--help: print this menu",
633635
" -a/--auto: set automatic trace mode, stopping the session if argument in us latency is hit",
@@ -664,6 +666,7 @@ static void timerlat_hist_usage(char *usage)
664666
" in nanoseconds",
665667
" -u/--user-threads: use rtla user-space threads instead of in-kernel timerlat threads",
666668
" -U/--user-load: enable timerlat for user-defined user-space workload",
669+
" --warm-up s: let the workload run for s seconds before collecting data",
667670
NULL,
668671
};
669672

@@ -738,13 +741,14 @@ static struct timerlat_hist_params
738741
{"dma-latency", required_argument, 0, '8'},
739742
{"no-aa", no_argument, 0, '9'},
740743
{"dump-task", no_argument, 0, '\1'},
744+
{"warm-up", required_argument, 0, '\2'},
741745
{0, 0, 0, 0}
742746
};
743747

744748
/* getopt_long stores the option index here. */
745749
int option_index = 0;
746750

747-
c = getopt_long(argc, argv, "a:c:C::b:d:e:E:DhH:i:np:P:s:t::T:uU0123456:7:8:9\1",
751+
c = getopt_long(argc, argv, "a:c:C::b:d:e:E:DhH:i:np:P:s:t::T:uU0123456:7:8:9\1\2:",
748752
long_options, &option_index);
749753

750754
/* detect the end of the options. */
@@ -913,6 +917,9 @@ static struct timerlat_hist_params
913917
case '\1':
914918
params->dump_tasks = 1;
915919
break;
920+
case '\2':
921+
params->warmup = get_llong_from_str(optarg);
922+
break;
916923
default:
917924
timerlat_hist_usage("Invalid option");
918925
}
@@ -1167,22 +1174,6 @@ int timerlat_hist_main(int argc, char *argv[])
11671174
}
11681175
}
11691176

1170-
/*
1171-
* Start the tracers here, after having set all instances.
1172-
*
1173-
* Let the trace instance start first for the case of hitting a stop
1174-
* tracing while enabling other instances. The trace instance is the
1175-
* one with most valuable information.
1176-
*/
1177-
if (params->trace_output)
1178-
trace_instance_start(&record->trace);
1179-
if (!params->no_aa)
1180-
trace_instance_start(&aa->trace);
1181-
trace_instance_start(trace);
1182-
1183-
tool->start_time = time(NULL);
1184-
timerlat_hist_set_signals(params);
1185-
11861177
if (params->user_workload) {
11871178
/* rtla asked to stop */
11881179
params_u.should_run = 1;
@@ -1202,6 +1193,29 @@ int timerlat_hist_main(int argc, char *argv[])
12021193
err_msg("Error creating timerlat user-space threads\n");
12031194
}
12041195

1196+
if (params->warmup > 0) {
1197+
debug_msg("Warming up for %d seconds\n", params->warmup);
1198+
sleep(params->warmup);
1199+
if (stop_tracing)
1200+
goto out_hist;
1201+
}
1202+
1203+
/*
1204+
* Start the tracers here, after having set all instances.
1205+
*
1206+
* Let the trace instance start first for the case of hitting a stop
1207+
* tracing while enabling other instances. The trace instance is the
1208+
* one with most valuable information.
1209+
*/
1210+
if (params->trace_output)
1211+
trace_instance_start(&record->trace);
1212+
if (!params->no_aa)
1213+
trace_instance_start(&aa->trace);
1214+
trace_instance_start(trace);
1215+
1216+
tool->start_time = time(NULL);
1217+
timerlat_hist_set_signals(params);
1218+
12051219
while (!stop_tracing) {
12061220
sleep(params->sleep_time);
12071221

@@ -1227,6 +1241,7 @@ int timerlat_hist_main(int argc, char *argv[])
12271241
}
12281242
}
12291243
}
1244+
12301245
if (params->user_workload && !params_u.stopped_running) {
12311246
params_u.should_run = 0;
12321247
sleep(1);

tools/tracing/rtla/src/timerlat_top.c

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ struct timerlat_top_params {
4545
int user_top;
4646
int user_workload;
4747
int pretty_output;
48+
int warmup;
4849
cpu_set_t hk_cpu_set;
4950
struct sched_attr sched_param;
5051
struct trace_events *events;
@@ -444,7 +445,7 @@ static void timerlat_top_usage(char *usage)
444445
"",
445446
" usage: rtla timerlat [top] [-h] [-q] [-a us] [-d s] [-D] [-n] [-p us] [-i us] [-T us] [-s us] \\",
446447
" [[-t[=file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] [-c cpu-list] [-H cpu-list]\\",
447-
" [-P priority] [--dma-latency us] [--aa-only us] [-C[=cgroup_name]] [-u]",
448+
" [-P priority] [--dma-latency us] [--aa-only us] [-C[=cgroup_name]] [-u] [--warm-up s]",
448449
"",
449450
" -h/--help: print this menu",
450451
" -a/--auto: set automatic trace mode, stopping the session if argument in us latency is hit",
@@ -475,6 +476,7 @@ static void timerlat_top_usage(char *usage)
475476
" in nanoseconds",
476477
" -u/--user-threads: use rtla user-space threads instead of in-kernel timerlat threads",
477478
" -U/--user-load: enable timerlat for user-defined user-space workload",
479+
" --warm-up s: let the workload run for s seconds before collecting data",
478480
NULL,
479481
};
480482

@@ -541,13 +543,14 @@ static struct timerlat_top_params
541543
{"no-aa", no_argument, 0, '3'},
542544
{"dump-tasks", no_argument, 0, '4'},
543545
{"aa-only", required_argument, 0, '5'},
546+
{"warm-up", required_argument, 0, '6'},
544547
{0, 0, 0, 0}
545548
};
546549

547550
/* getopt_long stores the option index here. */
548551
int option_index = 0;
549552

550-
c = getopt_long(argc, argv, "a:c:C::d:De:hH:i:np:P:qs:t::T:uU0:1:2:345:",
553+
c = getopt_long(argc, argv, "a:c:C::d:De:hH:i:np:P:qs:t::T:uU0:1:2:345:6:",
551554
long_options, &option_index);
552555

553556
/* detect the end of the options. */
@@ -704,6 +707,9 @@ static struct timerlat_top_params
704707
case '4':
705708
params->dump_tasks = 1;
706709
break;
710+
case '6':
711+
params->warmup = get_llong_from_str(optarg);
712+
break;
707713
default:
708714
timerlat_top_usage("Invalid option");
709715
}
@@ -971,22 +977,6 @@ int timerlat_top_main(int argc, char *argv[])
971977
}
972978
}
973979

974-
/*
975-
* Start the tracers here, after having set all instances.
976-
*
977-
* Let the trace instance start first for the case of hitting a stop
978-
* tracing while enabling other instances. The trace instance is the
979-
* one with most valuable information.
980-
*/
981-
if (params->trace_output)
982-
trace_instance_start(&record->trace);
983-
if (!params->no_aa && aa != top)
984-
trace_instance_start(&aa->trace);
985-
trace_instance_start(trace);
986-
987-
top->start_time = time(NULL);
988-
timerlat_top_set_signals(params);
989-
990980
if (params->user_workload) {
991981
/* rtla asked to stop */
992982
params_u.should_run = 1;
@@ -1006,6 +996,27 @@ int timerlat_top_main(int argc, char *argv[])
1006996
err_msg("Error creating timerlat user-space threads\n");
1007997
}
1008998

999+
if (params->warmup > 0) {
1000+
debug_msg("Warming up for %d seconds\n", params->warmup);
1001+
sleep(params->warmup);
1002+
}
1003+
1004+
/*
1005+
* Start the tracers here, after having set all instances.
1006+
*
1007+
* Let the trace instance start first for the case of hitting a stop
1008+
* tracing while enabling other instances. The trace instance is the
1009+
* one with most valuable information.
1010+
*/
1011+
if (params->trace_output)
1012+
trace_instance_start(&record->trace);
1013+
if (!params->no_aa && aa != top)
1014+
trace_instance_start(&aa->trace);
1015+
trace_instance_start(trace);
1016+
1017+
top->start_time = time(NULL);
1018+
timerlat_top_set_signals(params);
1019+
10091020
while (!stop_tracing) {
10101021
sleep(params->sleep_time);
10111022

0 commit comments

Comments
 (0)