aboutsummaryrefslogtreecommitdiff
path: root/tools/tracing/rtla/src/timerlat_top.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/tracing/rtla/src/timerlat_top.c')
-rw-r--r--tools/tracing/rtla/src/timerlat_top.c58
1 files changed, 49 insertions, 9 deletions
diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c
index 8c16419fe22a..059b468981e4 100644
--- a/tools/tracing/rtla/src/timerlat_top.c
+++ b/tools/tracing/rtla/src/timerlat_top.c
@@ -48,15 +48,16 @@ struct timerlat_top_params {
int pretty_output;
int warmup;
int buffer_size;
+ int deepest_idle_state;
cpu_set_t hk_cpu_set;
struct sched_attr sched_param;
struct trace_events *events;
};
struct timerlat_top_cpu {
- int irq_count;
- int thread_count;
- int user_count;
+ unsigned long long irq_count;
+ unsigned long long thread_count;
+ unsigned long long user_count;
unsigned long long cur_irq;
unsigned long long min_irq;
@@ -280,7 +281,7 @@ static void timerlat_top_print(struct osnoise_tool *top, int cpu)
/*
* Unless trace is being lost, IRQ counter is always the max.
*/
- trace_seq_printf(s, "%3d #%-9d |", cpu, cpu_data->irq_count);
+ trace_seq_printf(s, "%3d #%-9llu |", cpu, cpu_data->irq_count);
if (!cpu_data->irq_count) {
trace_seq_printf(s, "%s %s %s %s |", no_value, no_value, no_value, no_value);
@@ -447,7 +448,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|-k] [--warm-up s]",
+ " [-P priority] [--dma-latency us] [--aa-only us] [-C[=cgroup_name]] [-u|-k] [--warm-up s] [--deepest-idle-state n]",
"",
" -h/--help: print this menu",
" -a/--auto: set automatic trace mode, stopping the session if argument in us latency is hit",
@@ -459,7 +460,7 @@ static void timerlat_top_usage(char *usage)
" -c/--cpus cpus: run the tracer only on the given cpus",
" -H/--house-keeping cpus: run rtla control threads only on the given cpus",
" -C/--cgroup[=cgroup_name]: set cgroup, if no cgroup_name is passed, the rtla's cgroup will be inherited",
- " -d/--duration time[m|h|d]: duration of the session in seconds",
+ " -d/--duration time[s|m|h|d]: duration of the session",
" -D/--debug: print debug info",
" --dump-tasks: prints the task running on all CPUs if stop conditions are met (depends on !--no-aa)",
" -t/--trace[file]: save the stopped trace to [file|timerlat_trace.txt]",
@@ -481,6 +482,7 @@ static void timerlat_top_usage(char *usage)
" -U/--user-load: enable timerlat for user-defined user-space workload",
" --warm-up s: let the workload run for s seconds before collecting data",
" --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",
NULL,
};
@@ -518,6 +520,9 @@ static struct timerlat_top_params
/* disabled by default */
params->dma_latency = -1;
+ /* disabled by default */
+ params->deepest_idle_state = -2;
+
/* display data in microseconds */
params->output_divisor = 1000;
@@ -550,6 +555,7 @@ static struct timerlat_top_params
{"aa-only", required_argument, 0, '5'},
{"warm-up", required_argument, 0, '6'},
{"trace-buffer-size", required_argument, 0, '7'},
+ {"deepest-idle-state", required_argument, 0, '8'},
{0, 0, 0, 0}
};
@@ -613,7 +619,7 @@ static struct timerlat_top_params
case 'd':
params->duration = parse_seconds_duration(optarg);
if (!params->duration)
- timerlat_top_usage("Invalid -D duration\n");
+ timerlat_top_usage("Invalid -d duration\n");
break;
case 'e':
tevent = trace_event_alloc(optarg);
@@ -726,6 +732,9 @@ static struct timerlat_top_params
case '7':
params->buffer_size = get_llong_from_str(optarg);
break;
+ case '8':
+ params->deepest_idle_state = get_llong_from_str(optarg);
+ break;
default:
timerlat_top_usage("Invalid option");
}
@@ -830,7 +839,7 @@ timerlat_top_apply_config(struct osnoise_tool *top, struct timerlat_top_params *
* If the user did not specify a type of thread, try user-threads first.
* Fall back to kernel threads otherwise.
*/
- if (!params->kernel_workload && !params->user_workload) {
+ if (!params->kernel_workload && !params->user_top) {
retval = tracefs_file_exists(NULL, "osnoise/per_cpu/cpu0/timerlat_fd");
if (retval) {
debug_msg("User-space interface detected, setting user-threads\n");
@@ -850,7 +859,7 @@ timerlat_top_apply_config(struct osnoise_tool *top, struct timerlat_top_params *
}
}
- if (isatty(1) && !params->quiet)
+ if (isatty(STDOUT_FILENO) && !params->quiet)
params->pretty_output = 1;
return 0;
@@ -922,6 +931,7 @@ int timerlat_top_main(int argc, char *argv[])
int return_value = 1;
char *max_lat;
int retval;
+ int nr_cpus, i;
params = timerlat_top_parse_args(argc, argv);
if (!params)
@@ -971,6 +981,28 @@ int timerlat_top_main(int argc, char *argv[])
}
}
+ if (params->deepest_idle_state >= -1) {
+ if (!have_libcpupower_support()) {
+ err_msg("rtla built without libcpupower, --deepest-idle-state is not supported\n");
+ goto out_free;
+ }
+
+ nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
+
+ for (i = 0; i < nr_cpus; i++) {
+ if (params->cpus && !CPU_ISSET(i, &params->monitored_cpus))
+ continue;
+ if (save_cpu_idle_disable_state(i) < 0) {
+ err_msg("Could not save cpu idle state.\n");
+ goto out_free;
+ }
+ if (set_deepest_cpu_idle_state(i, params->deepest_idle_state) < 0) {
+ err_msg("Could not set deepest cpu idle state.\n");
+ goto out_free;
+ }
+ }
+ }
+
if (params->trace_output) {
record = osnoise_init_trace_tool("timerlat");
if (!record) {
@@ -1125,6 +1157,13 @@ out_top:
timerlat_aa_destroy();
if (dma_latency_fd >= 0)
close(dma_latency_fd);
+ if (params->deepest_idle_state >= -1) {
+ for (i = 0; i < nr_cpus; i++) {
+ if (params->cpus && !CPU_ISSET(i, &params->monitored_cpus))
+ continue;
+ restore_cpu_idle_disable_state(i);
+ }
+ }
trace_events_destroy(&record->trace, params->events);
params->events = NULL;
out_free:
@@ -1134,6 +1173,7 @@ out_free:
osnoise_destroy_tool(record);
osnoise_destroy_tool(top);
free(params);
+ free_cpu_idle_disable_states();
out_exit:
exit(return_value);
}