Skip to content

Commit

Permalink
rtla: Add the --warm-up option
Browse files Browse the repository at this point in the history
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 <corbet@lwn.net>
Cc: Juri Lelli <juri.lelli@redhat.com>
Signed-off-by: Daniel Bristot de Oliveira <bristot@kernel.org>
  • Loading branch information
Daniel Bristot de Oliveira committed May 15, 2024
1 parent 1462501 commit cdbf719
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 40 deletions.
4 changes: 4 additions & 0 deletions Documentation/tools/rtla/common_options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@

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.

**--warm-up** *s*

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.

**-h**, **--help**

Print help menu.
30 changes: 27 additions & 3 deletions tools/tracing/rtla/src/osnoise_hist.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ struct osnoise_hist_params {
cpu_set_t hk_cpu_set;
struct sched_attr sched_param;
struct trace_events *events;

char no_header;
char no_summary;
char no_index;
char with_zeros;
int bucket_size;
int entries;
int warmup;
};

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

Expand Down Expand Up @@ -531,13 +532,14 @@ static struct osnoise_hist_params
{"with-zeros", no_argument, 0, '3'},
{"trigger", required_argument, 0, '4'},
{"filter", required_argument, 0, '5'},
{"warm-up", required_argument, 0, '6'},
{0, 0, 0, 0}
};

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

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

/* detect the end of the options. */
Expand Down Expand Up @@ -680,6 +682,9 @@ static struct osnoise_hist_params
osnoise_hist_usage("--filter requires a previous -e\n");
}
break;
case '6':
params->warmup = get_llong_from_str(optarg);
break;
default:
osnoise_hist_usage("Invalid option");
}
Expand Down Expand Up @@ -899,6 +904,25 @@ int osnoise_hist_main(int argc, char *argv[])
trace_instance_start(&record->trace);
trace_instance_start(trace);

if (params->warmup > 0) {
debug_msg("Warming up for %d seconds\n", params->warmup);
sleep(params->warmup);
if (stop_tracing)
goto out_hist;

/*
* Clean up the buffer. The osnoise workload do not run
* with tracing off to avoid creating a performance penalty
* when not needed.
*/
retval = tracefs_instance_file_write(trace->inst, "trace", "");
if (retval < 0) {
debug_msg("Error cleaning up the buffer");
goto out_hist;
}

}

tool->start_time = time(NULL);
osnoise_hist_set_signals(params);

Expand Down
29 changes: 27 additions & 2 deletions tools/tracing/rtla/src/osnoise_top.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ struct osnoise_top_params {
int set_sched;
int cgroup;
int hk_cpus;
int warmup;
cpu_set_t hk_cpu_set;
struct sched_attr sched_param;
struct trace_events *events;
Expand Down Expand Up @@ -282,7 +283,7 @@ static void osnoise_top_usage(struct osnoise_top_params *params, char *usage)
static const char * const msg[] = {
" [-h] [-q] [-D] [-d s] [-a us] [-p us] [-r us] [-s us] [-S us] \\",
" [-T us] [-t[=file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] \\",
" [-c cpu-list] [-H cpu-list] [-P priority] [-C[=cgroup_name]]",
" [-c cpu-list] [-H cpu-list] [-P priority] [-C[=cgroup_name]] [--warm-up s]",
"",
" -h/--help: print this menu",
" -a/--auto: set automatic trace mode, stopping the session if argument in us sample is hit",
Expand All @@ -307,6 +308,7 @@ static void osnoise_top_usage(struct osnoise_top_params *params, char *usage)
" f:prio - use SCHED_FIFO with prio",
" d:runtime[us|ms|s]:period[us|ms|s] - use SCHED_DEADLINE with runtime and period",
" in nanoseconds",
" --warm-up s: let the workload run for s seconds before collecting data",
NULL,
};

Expand Down Expand Up @@ -381,13 +383,14 @@ struct osnoise_top_params *osnoise_top_parse_args(int argc, char **argv)
{"trace", optional_argument, 0, 't'},
{"trigger", required_argument, 0, '0'},
{"filter", required_argument, 0, '1'},
{"warm-up", required_argument, 0, '2'},
{0, 0, 0, 0}
};

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

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

/* Detect the end of the options. */
Expand Down Expand Up @@ -511,6 +514,9 @@ struct osnoise_top_params *osnoise_top_parse_args(int argc, char **argv)
osnoise_top_usage(params, "--filter requires a previous -e\n");
}
break;
case '2':
params->warmup = get_llong_from_str(optarg);
break;
default:
osnoise_top_usage(params, "Invalid option");
}
Expand Down Expand Up @@ -732,6 +738,25 @@ int osnoise_top_main(int argc, char **argv)
trace_instance_start(&record->trace);
trace_instance_start(trace);

if (params->warmup > 0) {
debug_msg("Warming up for %d seconds\n", params->warmup);
sleep(params->warmup);
if (stop_tracing)
goto out_top;

/*
* Clean up the buffer. The osnoise workload do not run
* with tracing off to avoid creating a performance penalty
* when not needed.
*/
retval = tracefs_instance_file_write(trace->inst, "trace", "");
if (retval < 0) {
debug_msg("Error cleaning up the buffer");
goto out_top;
}

}

tool->start_time = time(NULL);
osnoise_top_set_signals(params);

Expand Down
49 changes: 32 additions & 17 deletions tools/tracing/rtla/src/timerlat_hist.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ struct timerlat_hist_params {
char with_zeros;
int bucket_size;
int entries;
int warmup;
};

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

Expand Down Expand Up @@ -738,13 +741,14 @@ static struct timerlat_hist_params
{"dma-latency", required_argument, 0, '8'},
{"no-aa", no_argument, 0, '9'},
{"dump-task", no_argument, 0, '\1'},
{"warm-up", required_argument, 0, '\2'},
{0, 0, 0, 0}
};

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

c = getopt_long(argc, argv, "a:c:C::b:d:e:E:DhH:i:np:P:s:t::T:uU0123456:7:8:9\1",
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:",
long_options, &option_index);

/* detect the end of the options. */
Expand Down Expand Up @@ -913,6 +917,9 @@ static struct timerlat_hist_params
case '\1':
params->dump_tasks = 1;
break;
case '\2':
params->warmup = get_llong_from_str(optarg);
break;
default:
timerlat_hist_usage("Invalid option");
}
Expand Down Expand Up @@ -1167,22 +1174,6 @@ int timerlat_hist_main(int argc, char *argv[])
}
}

/*
* Start the tracers here, after having set all instances.
*
* Let the trace instance start first for the case of hitting a stop
* tracing while enabling other instances. The trace instance is the
* one with most valuable information.
*/
if (params->trace_output)
trace_instance_start(&record->trace);
if (!params->no_aa)
trace_instance_start(&aa->trace);
trace_instance_start(trace);

tool->start_time = time(NULL);
timerlat_hist_set_signals(params);

if (params->user_workload) {
/* rtla asked to stop */
params_u.should_run = 1;
Expand All @@ -1202,6 +1193,29 @@ int timerlat_hist_main(int argc, char *argv[])
err_msg("Error creating timerlat user-space threads\n");
}

if (params->warmup > 0) {
debug_msg("Warming up for %d seconds\n", params->warmup);
sleep(params->warmup);
if (stop_tracing)
goto out_hist;
}

/*
* Start the tracers here, after having set all instances.
*
* Let the trace instance start first for the case of hitting a stop
* tracing while enabling other instances. The trace instance is the
* one with most valuable information.
*/
if (params->trace_output)
trace_instance_start(&record->trace);
if (!params->no_aa)
trace_instance_start(&aa->trace);
trace_instance_start(trace);

tool->start_time = time(NULL);
timerlat_hist_set_signals(params);

while (!stop_tracing) {
sleep(params->sleep_time);

Expand All @@ -1227,6 +1241,7 @@ int timerlat_hist_main(int argc, char *argv[])
}
}
}

if (params->user_workload && !params_u.stopped_running) {
params_u.should_run = 0;
sleep(1);
Expand Down
47 changes: 29 additions & 18 deletions tools/tracing/rtla/src/timerlat_top.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ struct timerlat_top_params {
int user_top;
int user_workload;
int pretty_output;
int warmup;
cpu_set_t hk_cpu_set;
struct sched_attr sched_param;
struct trace_events *events;
Expand Down Expand Up @@ -444,7 +445,7 @@ static void timerlat_top_usage(char *usage)
"",
" usage: rtla timerlat [top] [-h] [-q] [-a us] [-d s] [-D] [-n] [-p us] [-i us] [-T us] [-s us] \\",
" [[-t[=file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] [-c cpu-list] [-H cpu-list]\\",
" [-P priority] [--dma-latency us] [--aa-only us] [-C[=cgroup_name]] [-u]",
" [-P priority] [--dma-latency us] [--aa-only us] [-C[=cgroup_name]] [-u] [--warm-up s]",
"",
" -h/--help: print this menu",
" -a/--auto: set automatic trace mode, stopping the session if argument in us latency is hit",
Expand Down Expand Up @@ -475,6 +476,7 @@ static void timerlat_top_usage(char *usage)
" in nanoseconds",
" -u/--user-threads: use rtla user-space threads instead of in-kernel timerlat threads",
" -U/--user-load: enable timerlat for user-defined user-space workload",
" --warm-up s: let the workload run for s seconds before collecting data",
NULL,
};

Expand Down Expand Up @@ -541,13 +543,14 @@ static struct timerlat_top_params
{"no-aa", no_argument, 0, '3'},
{"dump-tasks", no_argument, 0, '4'},
{"aa-only", required_argument, 0, '5'},
{"warm-up", required_argument, 0, '6'},
{0, 0, 0, 0}
};

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

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

/* detect the end of the options. */
Expand Down Expand Up @@ -704,6 +707,9 @@ static struct timerlat_top_params
case '4':
params->dump_tasks = 1;
break;
case '6':
params->warmup = get_llong_from_str(optarg);
break;
default:
timerlat_top_usage("Invalid option");
}
Expand Down Expand Up @@ -971,22 +977,6 @@ int timerlat_top_main(int argc, char *argv[])
}
}

/*
* Start the tracers here, after having set all instances.
*
* Let the trace instance start first for the case of hitting a stop
* tracing while enabling other instances. The trace instance is the
* one with most valuable information.
*/
if (params->trace_output)
trace_instance_start(&record->trace);
if (!params->no_aa && aa != top)
trace_instance_start(&aa->trace);
trace_instance_start(trace);

top->start_time = time(NULL);
timerlat_top_set_signals(params);

if (params->user_workload) {
/* rtla asked to stop */
params_u.should_run = 1;
Expand All @@ -1006,6 +996,27 @@ int timerlat_top_main(int argc, char *argv[])
err_msg("Error creating timerlat user-space threads\n");
}

if (params->warmup > 0) {
debug_msg("Warming up for %d seconds\n", params->warmup);
sleep(params->warmup);
}

/*
* Start the tracers here, after having set all instances.
*
* Let the trace instance start first for the case of hitting a stop
* tracing while enabling other instances. The trace instance is the
* one with most valuable information.
*/
if (params->trace_output)
trace_instance_start(&record->trace);
if (!params->no_aa && aa != top)
trace_instance_start(&aa->trace);
trace_instance_start(trace);

top->start_time = time(NULL);
timerlat_top_set_signals(params);

while (!stop_tracing) {
sleep(params->sleep_time);

Expand Down

0 comments on commit cdbf719

Please sign in to comment.