Lines Matching +full:0 +full:- +full:9 +full:a +full:- +full:e
1 // SPDX-License-Identifier: GPL-2.0
49 * timerlat_free_top - free runtime data
53 free(data->cpu_data); in timerlat_free_top()
59 timerlat_free_top(tool->data); in timerlat_free_top_tool()
64 * timerlat_alloc_histogram - alloc runtime data
75 data->nr_cpus = nr_cpus; in timerlat_alloc_top()
78 data->cpu_data = calloc(1, sizeof(*data->cpu_data) * nr_cpus); in timerlat_alloc_top()
79 if (!data->cpu_data) in timerlat_alloc_top()
83 for (cpu = 0; cpu < nr_cpus; cpu++) { in timerlat_alloc_top()
84 data->cpu_data[cpu].min_irq = ~0; in timerlat_alloc_top()
85 data->cpu_data[cpu].min_thread = ~0; in timerlat_alloc_top()
86 data->cpu_data[cpu].min_user = ~0; in timerlat_alloc_top()
99 memset(summary, 0, sizeof(*summary)); in timerlat_top_reset_sum()
100 summary->min_irq = ~0; in timerlat_top_reset_sum()
101 summary->min_thread = ~0; in timerlat_top_reset_sum()
102 summary->min_user = ~0; in timerlat_top_reset_sum()
108 struct timerlat_top_data *data = tool->data; in timerlat_top_update_sum()
109 struct timerlat_top_cpu *cpu_data = &data->cpu_data[cpu]; in timerlat_top_update_sum()
111 sum->irq_count += cpu_data->irq_count; in timerlat_top_update_sum()
112 update_min(&sum->min_irq, &cpu_data->min_irq); in timerlat_top_update_sum()
113 update_sum(&sum->sum_irq, &cpu_data->sum_irq); in timerlat_top_update_sum()
114 update_max(&sum->max_irq, &cpu_data->max_irq); in timerlat_top_update_sum()
116 sum->thread_count += cpu_data->thread_count; in timerlat_top_update_sum()
117 update_min(&sum->min_thread, &cpu_data->min_thread); in timerlat_top_update_sum()
118 update_sum(&sum->sum_thread, &cpu_data->sum_thread); in timerlat_top_update_sum()
119 update_max(&sum->max_thread, &cpu_data->max_thread); in timerlat_top_update_sum()
121 sum->user_count += cpu_data->user_count; in timerlat_top_update_sum()
122 update_min(&sum->min_user, &cpu_data->min_user); in timerlat_top_update_sum()
123 update_sum(&sum->sum_user, &cpu_data->sum_user); in timerlat_top_update_sum()
124 update_max(&sum->max_user, &cpu_data->max_user); in timerlat_top_update_sum()
128 * timerlat_hist_update - record a new timerlat occurent on cpu, updating data
135 struct timerlat_params *params = to_timerlat_params(tool->params); in timerlat_top_update()
136 struct timerlat_top_data *data = tool->data; in timerlat_top_update()
137 struct timerlat_top_cpu *cpu_data = &data->cpu_data[cpu]; in timerlat_top_update()
139 if (params->common.output_divisor) in timerlat_top_update()
140 latency = latency / params->common.output_divisor; in timerlat_top_update()
143 cpu_data->irq_count++; in timerlat_top_update()
144 cpu_data->cur_irq = latency; in timerlat_top_update()
145 update_min(&cpu_data->min_irq, &latency); in timerlat_top_update()
146 update_sum(&cpu_data->sum_irq, &latency); in timerlat_top_update()
147 update_max(&cpu_data->max_irq, &latency); in timerlat_top_update()
149 cpu_data->thread_count++; in timerlat_top_update()
150 cpu_data->cur_thread = latency; in timerlat_top_update()
151 update_min(&cpu_data->min_thread, &latency); in timerlat_top_update()
152 update_sum(&cpu_data->sum_thread, &latency); in timerlat_top_update()
153 update_max(&cpu_data->max_thread, &latency); in timerlat_top_update()
155 cpu_data->user_count++; in timerlat_top_update()
156 cpu_data->cur_user = latency; in timerlat_top_update()
157 update_min(&cpu_data->min_user, &latency); in timerlat_top_update()
158 update_sum(&cpu_data->sum_user, &latency); in timerlat_top_update()
159 update_max(&cpu_data->max_user, &latency); in timerlat_top_update()
164 * timerlat_top_handler - this is the handler for timerlat tracer events
173 int cpu = record->cpu; in timerlat_top_handler()
177 if (!top->params->aa_only) { in timerlat_top_handler()
184 return 0; in timerlat_top_handler()
188 * timerlat_top_bpf_pull_data - copy data from BPF maps into userspace
192 struct timerlat_top_data *data = tool->data; in timerlat_top_bpf_pull_data()
194 long long value_irq[data->nr_cpus], in timerlat_top_bpf_pull_data()
195 value_thread[data->nr_cpus], in timerlat_top_bpf_pull_data()
196 value_user[data->nr_cpus]; in timerlat_top_bpf_pull_data()
201 data->nr_cpus); in timerlat_top_bpf_pull_data()
204 for (i = 0; i < data->nr_cpus; i++) { in timerlat_top_bpf_pull_data()
205 data->cpu_data[i].cur_irq = value_irq[i]; in timerlat_top_bpf_pull_data()
206 data->cpu_data[i].cur_thread = value_thread[i]; in timerlat_top_bpf_pull_data()
207 data->cpu_data[i].cur_user = value_user[i]; in timerlat_top_bpf_pull_data()
212 data->nr_cpus); in timerlat_top_bpf_pull_data()
215 for (i = 0; i < data->nr_cpus; i++) { in timerlat_top_bpf_pull_data()
216 data->cpu_data[i].irq_count = value_irq[i]; in timerlat_top_bpf_pull_data()
217 data->cpu_data[i].thread_count = value_thread[i]; in timerlat_top_bpf_pull_data()
218 data->cpu_data[i].user_count = value_user[i]; in timerlat_top_bpf_pull_data()
223 data->nr_cpus); in timerlat_top_bpf_pull_data()
226 for (i = 0; i < data->nr_cpus; i++) { in timerlat_top_bpf_pull_data()
227 data->cpu_data[i].min_irq = value_irq[i]; in timerlat_top_bpf_pull_data()
228 data->cpu_data[i].min_thread = value_thread[i]; in timerlat_top_bpf_pull_data()
229 data->cpu_data[i].min_user = value_user[i]; in timerlat_top_bpf_pull_data()
234 data->nr_cpus); in timerlat_top_bpf_pull_data()
237 for (i = 0; i < data->nr_cpus; i++) { in timerlat_top_bpf_pull_data()
238 data->cpu_data[i].max_irq = value_irq[i]; in timerlat_top_bpf_pull_data()
239 data->cpu_data[i].max_thread = value_thread[i]; in timerlat_top_bpf_pull_data()
240 data->cpu_data[i].max_user = value_user[i]; in timerlat_top_bpf_pull_data()
245 data->nr_cpus); in timerlat_top_bpf_pull_data()
248 for (i = 0; i < data->nr_cpus; i++) { in timerlat_top_bpf_pull_data()
249 data->cpu_data[i].sum_irq = value_irq[i]; in timerlat_top_bpf_pull_data()
250 data->cpu_data[i].sum_thread = value_thread[i]; in timerlat_top_bpf_pull_data()
251 data->cpu_data[i].sum_user = value_user[i]; in timerlat_top_bpf_pull_data()
254 return 0; in timerlat_top_bpf_pull_data()
258 * timerlat_top_header - print the header of the tool output
262 struct trace_seq *s = top->trace.seq; in timerlat_top_header()
263 bool pretty = params->common.pretty_output; in timerlat_top_header()
266 get_duration(top->start_time, duration, sizeof(duration)); in timerlat_top_header()
272 if (params->common.user_data) in timerlat_top_header()
276 trace_seq_printf(s, "\033[0;0;0m"); in timerlat_top_header()
279 …trace_seq_printf(s, "%-6s | IRQ Timer Latency (%s) | Thread Timer Latenc… in timerlat_top_header()
280 params->common.output_divisor == 1 ? "ns" : "us", in timerlat_top_header()
281 params->common.output_divisor == 1 ? "ns" : "us"); in timerlat_top_header()
283 if (params->common.user_data) { in timerlat_top_header()
285 params->common.output_divisor == 1 ? "ns" : "us"); in timerlat_top_header()
293 if (params->common.user_data) in timerlat_top_header()
297 trace_seq_printf(s, "\033[0;0;0m"); in timerlat_top_header()
301 static const char *no_value = " -";
304 * timerlat_top_print - prints the output of a given CPU
308 struct timerlat_params *params = to_timerlat_params(top->params); in timerlat_top_print()
309 struct timerlat_top_data *data = top->data; in timerlat_top_print()
310 struct timerlat_top_cpu *cpu_data = &data->cpu_data[cpu]; in timerlat_top_print()
311 struct trace_seq *s = top->trace.seq; in timerlat_top_print()
316 if (!cpu_data->irq_count && !cpu_data->thread_count) in timerlat_top_print()
322 trace_seq_printf(s, "%3d #%-9llu |", cpu, cpu_data->irq_count); in timerlat_top_print()
324 if (!cpu_data->irq_count) { in timerlat_top_print()
327 trace_seq_printf(s, "%9llu ", cpu_data->cur_irq); in timerlat_top_print()
328 trace_seq_printf(s, "%9llu ", cpu_data->min_irq); in timerlat_top_print()
329 trace_seq_printf(s, "%9llu ", cpu_data->sum_irq / cpu_data->irq_count); in timerlat_top_print()
330 trace_seq_printf(s, "%9llu |", cpu_data->max_irq); in timerlat_top_print()
333 if (!cpu_data->thread_count) { in timerlat_top_print()
336 trace_seq_printf(s, "%9llu ", cpu_data->cur_thread); in timerlat_top_print()
337 trace_seq_printf(s, "%9llu ", cpu_data->min_thread); in timerlat_top_print()
338 trace_seq_printf(s, "%9llu ", in timerlat_top_print()
339 cpu_data->sum_thread / cpu_data->thread_count); in timerlat_top_print()
340 trace_seq_printf(s, "%9llu", cpu_data->max_thread); in timerlat_top_print()
343 if (!params->common.user_data) { in timerlat_top_print()
350 if (!cpu_data->user_count) { in timerlat_top_print()
353 trace_seq_printf(s, "%9llu ", cpu_data->cur_user); in timerlat_top_print()
354 trace_seq_printf(s, "%9llu ", cpu_data->min_user); in timerlat_top_print()
355 trace_seq_printf(s, "%9llu ", in timerlat_top_print()
356 cpu_data->sum_user / cpu_data->user_count); in timerlat_top_print()
357 trace_seq_printf(s, "%9llu\n", cpu_data->max_user); in timerlat_top_print()
362 * timerlat_top_print_sum - prints the summary output
367 const char *split = "----------------------------------------"; in timerlat_top_print_sum()
368 struct timerlat_params *params = to_timerlat_params(top->params); in timerlat_top_print_sum()
369 unsigned long long count = summary->irq_count; in timerlat_top_print_sum()
370 struct trace_seq *s = top->trace.seq; in timerlat_top_print_sum()
371 int e = 0; in timerlat_top_print_sum() local
376 if (!summary->irq_count && !summary->thread_count) in timerlat_top_print_sum()
380 e++; in timerlat_top_print_sum()
385 if (params->common.user_data) in timerlat_top_print_sum()
386 trace_seq_printf(s, "-|%.*s", 39, split); in timerlat_top_print_sum()
389 trace_seq_printf(s, "ALL #%-6llu e%d |", count, e); in timerlat_top_print_sum()
391 if (!summary->irq_count) { in timerlat_top_print_sum()
395 trace_seq_printf(s, "%9llu ", summary->min_irq); in timerlat_top_print_sum()
396 trace_seq_printf(s, "%9llu ", summary->sum_irq / summary->irq_count); in timerlat_top_print_sum()
397 trace_seq_printf(s, "%9llu |", summary->max_irq); in timerlat_top_print_sum()
400 if (!summary->thread_count) { in timerlat_top_print_sum()
404 trace_seq_printf(s, "%9llu ", summary->min_thread); in timerlat_top_print_sum()
405 trace_seq_printf(s, "%9llu ", in timerlat_top_print_sum()
406 summary->sum_thread / summary->thread_count); in timerlat_top_print_sum()
407 trace_seq_printf(s, "%9llu", summary->max_thread); in timerlat_top_print_sum()
410 if (!params->common.user_data) { in timerlat_top_print_sum()
417 if (!summary->user_count) { in timerlat_top_print_sum()
421 trace_seq_printf(s, "%9llu ", summary->min_user); in timerlat_top_print_sum()
422 trace_seq_printf(s, "%9llu ", in timerlat_top_print_sum()
423 summary->sum_user / summary->user_count); in timerlat_top_print_sum()
424 trace_seq_printf(s, "%9llu\n", summary->max_user); in timerlat_top_print_sum()
429 * clear_terminal - clears the output terminal
438 * timerlat_print_stats - print data for all cpus
443 struct timerlat_params *params = to_timerlat_params(top->params); in timerlat_print_stats()
444 struct trace_instance *trace = &top->trace; in timerlat_print_stats()
446 static int nr_cpus = -1; in timerlat_print_stats()
449 if (params->common.aa_only) in timerlat_print_stats()
452 if (nr_cpus == -1) in timerlat_print_stats()
455 if (!params->common.quiet) in timerlat_print_stats()
456 clear_terminal(trace->seq); in timerlat_print_stats()
462 for (i = 0; i < nr_cpus; i++) { in timerlat_print_stats()
463 if (params->common.cpus && !CPU_ISSET(i, ¶ms->common.monitored_cpus)) in timerlat_print_stats()
471 trace_seq_do_printf(trace->seq); in timerlat_print_stats()
472 trace_seq_reset(trace->seq); in timerlat_print_stats()
477 * timerlat_top_usage - prints timerlat top usage message
485 …" usage: rtla timerlat [top] [-h] [-q] [-a us] [-d s] [-D] [-n] [-p us] [-i us] [-T us] [-s us] \… in timerlat_top_usage()
486 …" [[-t[file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] [-c cpu-list] [-H cpu-l… in timerlat_top_usage()
487 …" [-P priority] [--dma-latency us] [--aa-only us] [-C[=cgroup_name]] [-u|-k] [--warm-up s] [--de… in timerlat_top_usage()
489 " -h/--help: print this menu", in timerlat_top_usage()
490 " -a/--auto: set automatic trace mode, stopping the session if argument in us latency is hit", in timerlat_top_usage()
491 …" --aa-only us: stop if <us> latency is hit, only printing the auto analysis (reduces CPU usa… in timerlat_top_usage()
492 " -p/--period us: timerlat period in us", in timerlat_top_usage()
493 " -i/--irq us: stop trace if the irq latency is higher than the argument in us", in timerlat_top_usage()
494 " -T/--thread us: stop trace if the thread latency is higher than the argument in us", in timerlat_top_usage()
495 …" -s/--stack us: save the stack trace at the IRQ if a thread latency is higher than the argument… in timerlat_top_usage()
496 " -c/--cpus cpus: run the tracer only on the given cpus", in timerlat_top_usage()
497 " -H/--house-keeping cpus: run rtla control threads only on the given cpus", in timerlat_top_usage()
498 …" -C/--cgroup[=cgroup_name]: set cgroup, if no cgroup_name is passed, the rtla's cgroup will be … in timerlat_top_usage()
499 " -d/--duration time[s|m|h|d]: duration of the session", in timerlat_top_usage()
500 " -D/--debug: print debug info", in timerlat_top_usage()
501 …" --dump-tasks: prints the task running on all CPUs if stop conditions are met (depends on !-… in timerlat_top_usage()
502 " -t/--trace[file]: save the stopped trace to [file|timerlat_trace.txt]", in timerlat_top_usage()
503 …" -e/--event <sys:event>: enable the <sys:event> in the trace instance, multiple -e are allowed", in timerlat_top_usage()
504 " --filter <command>: enable a trace event filter to the previous -e event", in timerlat_top_usage()
505 " --trigger <command>: enable a trace event trigger to the previous -e event", in timerlat_top_usage()
506 " -n/--nano: display data in nanoseconds", in timerlat_top_usage()
507 " --no-aa: disable auto-analysis, reducing rtla timerlat cpu usage", in timerlat_top_usage()
508 " -q/--quiet print only a summary at the end", in timerlat_top_usage()
509 " --dma-latency us: set /dev/cpu_dma_latency latency <us> to reduce exit from idle latency", in timerlat_top_usage()
510 " -P/--priority o:prio|r:prio|f:prio|d:runtime:period : set scheduling parameters", in timerlat_top_usage()
511 " o:prio - use SCHED_OTHER with prio", in timerlat_top_usage()
512 " r:prio - use SCHED_RR with prio", in timerlat_top_usage()
513 " f:prio - use SCHED_FIFO with prio", in timerlat_top_usage()
514 " d:runtime[us|ms|s]:period[us|ms|s] - use SCHED_DEADLINE with runtime and period", in timerlat_top_usage()
516 " -u/--user-threads: use rtla user-space threads instead of kernel-space timerlat threads", in timerlat_top_usage()
517 " -k/--kernel-threads: use timerlat kernel-space threads instead of rtla user-space threads", in timerlat_top_usage()
518 " -U/--user-load: enable timerlat for user-defined user-space workload", in timerlat_top_usage()
519 " --warm-up s: let the workload run for s seconds before collecting data", in timerlat_top_usage()
520 " --trace-buffer-size kB: set the per-cpu trace buffer size in kB", in timerlat_top_usage()
521 …" --deepest-idle-state n: only go down to idle state n on cpus used by timerlat to reduce exi… in timerlat_top_usage()
522 …" --on-threshold <action>: define action to be executed at latency threshold, multiple are al… in timerlat_top_usage()
523 " --on-end: define action to be executed at measurement end, multiple are allowed", in timerlat_top_usage()
530 fprintf(stderr, "rtla timerlat top: a per-cpu summary of the timer latency (version %s)\n", in timerlat_top_usage()
533 for (i = 0; msg[i]; i++) in timerlat_top_usage()
543 * timerlat_top_parse_args - allocs, parse and fill the cmd line parameters
559 actions_init(¶ms->common.threshold_actions); in timerlat_top_parse_args()
560 actions_init(¶ms->common.end_actions); in timerlat_top_parse_args()
563 params->dma_latency = -1; in timerlat_top_parse_args()
566 params->deepest_idle_state = -2; in timerlat_top_parse_args()
569 params->common.output_divisor = 1000; in timerlat_top_parse_args()
572 params->mode = TRACING_MODE_BPF; in timerlat_top_parse_args()
576 {"auto", required_argument, 0, 'a'}, in timerlat_top_parse_args()
577 {"cpus", required_argument, 0, 'c'}, in timerlat_top_parse_args()
578 {"cgroup", optional_argument, 0, 'C'}, in timerlat_top_parse_args()
579 {"debug", no_argument, 0, 'D'}, in timerlat_top_parse_args()
580 {"duration", required_argument, 0, 'd'}, in timerlat_top_parse_args()
581 {"event", required_argument, 0, 'e'}, in timerlat_top_parse_args()
582 {"help", no_argument, 0, 'h'}, in timerlat_top_parse_args()
583 {"house-keeping", required_argument, 0, 'H'}, in timerlat_top_parse_args()
584 {"irq", required_argument, 0, 'i'}, in timerlat_top_parse_args()
585 {"nano", no_argument, 0, 'n'}, in timerlat_top_parse_args()
586 {"period", required_argument, 0, 'p'}, in timerlat_top_parse_args()
587 {"priority", required_argument, 0, 'P'}, in timerlat_top_parse_args()
588 {"quiet", no_argument, 0, 'q'}, in timerlat_top_parse_args()
589 {"stack", required_argument, 0, 's'}, in timerlat_top_parse_args()
590 {"thread", required_argument, 0, 'T'}, in timerlat_top_parse_args()
591 {"trace", optional_argument, 0, 't'}, in timerlat_top_parse_args()
592 {"user-threads", no_argument, 0, 'u'}, in timerlat_top_parse_args()
593 {"kernel-threads", no_argument, 0, 'k'}, in timerlat_top_parse_args()
594 {"user-load", no_argument, 0, 'U'}, in timerlat_top_parse_args()
595 {"trigger", required_argument, 0, '0'}, in timerlat_top_parse_args()
596 {"filter", required_argument, 0, '1'}, in timerlat_top_parse_args()
597 {"dma-latency", required_argument, 0, '2'}, in timerlat_top_parse_args()
598 {"no-aa", no_argument, 0, '3'}, in timerlat_top_parse_args()
599 {"dump-tasks", no_argument, 0, '4'}, in timerlat_top_parse_args()
600 {"aa-only", required_argument, 0, '5'}, in timerlat_top_parse_args()
601 {"warm-up", required_argument, 0, '6'}, in timerlat_top_parse_args()
602 {"trace-buffer-size", required_argument, 0, '7'}, in timerlat_top_parse_args()
603 {"deepest-idle-state", required_argument, 0, '8'}, in timerlat_top_parse_args()
604 {"on-threshold", required_argument, 0, '9'}, in timerlat_top_parse_args()
605 {"on-end", required_argument, 0, '\1'}, in timerlat_top_parse_args()
606 {0, 0, 0, 0} in timerlat_top_parse_args()
610 int option_index = 0; in timerlat_top_parse_args()
612 c = getopt_long(argc, argv, "a:c:C::d:De:hH:i:knp:P:qs:t::T:uU0:1:2:345:6:7:", in timerlat_top_parse_args()
616 if (c == -1) in timerlat_top_parse_args()
620 case 'a': in timerlat_top_parse_args()
624 params->common.stop_total_us = auto_thresh; in timerlat_top_parse_args()
625 params->common.stop_us = auto_thresh; in timerlat_top_parse_args()
628 params->print_stack = auto_thresh; in timerlat_top_parse_args()
635 /* it is here because it is similar to -a */ in timerlat_top_parse_args()
639 params->common.stop_total_us = auto_thresh; in timerlat_top_parse_args()
640 params->common.stop_us = auto_thresh; in timerlat_top_parse_args()
643 params->print_stack = auto_thresh; in timerlat_top_parse_args()
646 params->common.aa_only = 1; in timerlat_top_parse_args()
649 retval = parse_cpu_set(optarg, ¶ms->common.monitored_cpus); in timerlat_top_parse_args()
651 timerlat_top_usage("\nInvalid -c cpu list\n"); in timerlat_top_parse_args()
652 params->common.cpus = optarg; in timerlat_top_parse_args()
655 params->common.cgroup = 1; in timerlat_top_parse_args()
658 params->common.cgroup_name = NULL; in timerlat_top_parse_args()
661 params->common.cgroup_name = ++optarg; in timerlat_top_parse_args()
668 params->common.duration = parse_seconds_duration(optarg); in timerlat_top_parse_args()
669 if (!params->common.duration) in timerlat_top_parse_args()
670 timerlat_top_usage("Invalid -d duration\n"); in timerlat_top_parse_args()
672 case 'e': in timerlat_top_parse_args()
679 if (params->common.events) in timerlat_top_parse_args()
680 tevent->next = params->common.events; in timerlat_top_parse_args()
681 params->common.events = tevent; in timerlat_top_parse_args()
688 params->common.hk_cpus = 1; in timerlat_top_parse_args()
689 retval = parse_cpu_set(optarg, ¶ms->common.hk_cpu_set); in timerlat_top_parse_args()
696 params->common.stop_us = get_llong_from_str(optarg); in timerlat_top_parse_args()
699 params->common.kernel_workload = true; in timerlat_top_parse_args()
702 params->common.output_divisor = 1; in timerlat_top_parse_args()
705 params->timerlat_period_us = get_llong_from_str(optarg); in timerlat_top_parse_args()
706 if (params->timerlat_period_us > 1000000) in timerlat_top_parse_args()
710 retval = parse_prio(optarg, ¶ms->common.sched_param); in timerlat_top_parse_args()
711 if (retval == -1) in timerlat_top_parse_args()
712 timerlat_top_usage("Invalid -P priority"); in timerlat_top_parse_args()
713 params->common.set_sched = 1; in timerlat_top_parse_args()
716 params->common.quiet = 1; in timerlat_top_parse_args()
719 params->print_stack = get_llong_from_str(optarg); in timerlat_top_parse_args()
722 params->common.stop_total_us = get_llong_from_str(optarg); in timerlat_top_parse_args()
726 if (optarg[0] == '=') in timerlat_top_parse_args()
729 trace_output = &optarg[0]; in timerlat_top_parse_args()
730 } else if (optind < argc && argv[optind][0] != '-') in timerlat_top_parse_args()
736 params->common.user_workload = true; in timerlat_top_parse_args()
737 /* fallback: -u implies -U */ in timerlat_top_parse_args()
739 params->common.user_data = true; in timerlat_top_parse_args()
741 case '0': /* trigger */ in timerlat_top_parse_args()
742 if (params->common.events) { in timerlat_top_parse_args()
743 retval = trace_event_add_trigger(params->common.events, optarg); in timerlat_top_parse_args()
749 timerlat_top_usage("--trigger requires a previous -e\n"); in timerlat_top_parse_args()
753 if (params->common.events) { in timerlat_top_parse_args()
754 retval = trace_event_add_filter(params->common.events, optarg); in timerlat_top_parse_args()
760 timerlat_top_usage("--filter requires a previous -e\n"); in timerlat_top_parse_args()
763 case '2': /* dma-latency */ in timerlat_top_parse_args()
764 params->dma_latency = get_llong_from_str(optarg); in timerlat_top_parse_args()
765 if (params->dma_latency < 0 || params->dma_latency > 10000) { in timerlat_top_parse_args()
766 err_msg("--dma-latency needs to be >= 0 and < 10000"); in timerlat_top_parse_args()
770 case '3': /* no-aa */ in timerlat_top_parse_args()
771 params->no_aa = 1; in timerlat_top_parse_args()
774 params->dump_tasks = 1; in timerlat_top_parse_args()
777 params->common.warmup = get_llong_from_str(optarg); in timerlat_top_parse_args()
780 params->common.buffer_size = get_llong_from_str(optarg); in timerlat_top_parse_args()
783 params->deepest_idle_state = get_llong_from_str(optarg); in timerlat_top_parse_args()
785 case '9': in timerlat_top_parse_args()
786 retval = actions_parse(¶ms->common.threshold_actions, optarg, in timerlat_top_parse_args()
794 retval = actions_parse(¶ms->common.end_actions, optarg, in timerlat_top_parse_args()
807 actions_add_trace_output(¶ms->common.threshold_actions, trace_output); in timerlat_top_parse_args()
817 if (!params->common.stop_us && !params->common.stop_total_us) in timerlat_top_parse_args()
818 params->no_aa = 1; in timerlat_top_parse_args()
820 if (params->no_aa && params->common.aa_only) in timerlat_top_parse_args()
821 timerlat_top_usage("--no-aa and --aa-only are mutually exclusive!"); in timerlat_top_parse_args()
823 if (params->common.kernel_workload && params->common.user_workload) in timerlat_top_parse_args()
824 timerlat_top_usage("--kernel-threads and --user-threads are mutually exclusive!"); in timerlat_top_parse_args()
827 * If auto-analysis or trace output is enabled, switch from BPF mode to in timerlat_top_parse_args()
830 if (params->mode == TRACING_MODE_BPF && in timerlat_top_parse_args()
831 (params->common.threshold_actions.present[ACTION_TRACE_OUTPUT] || in timerlat_top_parse_args()
832 params->common.end_actions.present[ACTION_TRACE_OUTPUT] || in timerlat_top_parse_args()
833 !params->no_aa)) in timerlat_top_parse_args()
834 params->mode = TRACING_MODE_MIXED; in timerlat_top_parse_args()
836 return ¶ms->common; in timerlat_top_parse_args()
840 * timerlat_top_apply_config - apply the top configs to the initialized tool
845 struct timerlat_params *params = to_timerlat_params(top->params); in timerlat_top_apply_config()
852 if (isatty(STDOUT_FILENO) && !params->common.quiet) in timerlat_top_apply_config()
853 params->common.pretty_output = 1; in timerlat_top_apply_config()
855 return 0; in timerlat_top_apply_config()
858 return -1; in timerlat_top_apply_config()
862 * timerlat_init_top - initialize a timerlat top tool with parameters
876 top->data = timerlat_alloc_top(nr_cpus); in timerlat_init_top()
877 if (!top->data) in timerlat_init_top()
880 tep_register_event_handler(top->trace.tep, -1, "ftrace", "timerlat", in timerlat_init_top()
891 * timerlat_top_bpf_main_loop - main loop to process events (BPF variant)
896 struct timerlat_params *params = to_timerlat_params(tool->params); in timerlat_top_bpf_main_loop()
899 if (params->common.aa_only) { in timerlat_top_bpf_main_loop()
900 /* Auto-analysis only, just wait for stop tracing */ in timerlat_top_bpf_main_loop()
901 timerlat_bpf_wait(-1); in timerlat_top_bpf_main_loop()
902 return 0; in timerlat_top_bpf_main_loop()
905 /* Pull and display data in a loop */ in timerlat_top_bpf_main_loop()
907 wait_retval = timerlat_bpf_wait(params->common.quiet ? -1 : in timerlat_top_bpf_main_loop()
908 params->common.sleep_time); in timerlat_top_bpf_main_loop()
916 if (!params->common.quiet) in timerlat_top_bpf_main_loop()
921 actions_perform(¶ms->common.threshold_actions); in timerlat_top_bpf_main_loop()
923 if (!params->common.threshold_actions.continue_flag) in timerlat_top_bpf_main_loop()
927 /* continue action reached, re-enable tracing */ in timerlat_top_bpf_main_loop()
928 if (tool->record) in timerlat_top_bpf_main_loop()
929 trace_instance_start(&tool->record->trace); in timerlat_top_bpf_main_loop()
930 if (tool->aa) in timerlat_top_bpf_main_loop()
931 trace_instance_start(&tool->aa->trace); in timerlat_top_bpf_main_loop()
935 /* is there still any user-threads ? */ in timerlat_top_bpf_main_loop()
936 if (params->common.user_workload) { in timerlat_top_bpf_main_loop()
937 if (params->common.user.stopped_running) { in timerlat_top_bpf_main_loop()
944 return 0; in timerlat_top_bpf_main_loop()
949 struct timerlat_params *params = to_timerlat_params(tool->params); in timerlat_top_main_loop()
952 if (params->mode == TRACING_MODE_TRACEFS) { in timerlat_top_main_loop()