Lines Matching +full:1 +full:d +full:- +full:histogram

1 // SPDX-License-Identifier: GPL-2.0
51 * timerlat_free_histogram - free runtime data
58 /* one histogram for IRQ and one for thread, per CPU */ in timerlat_free_histogram()
59 for (cpu = 0; cpu < data->nr_cpus; cpu++) { in timerlat_free_histogram()
60 if (data->hist[cpu].irq) in timerlat_free_histogram()
61 free(data->hist[cpu].irq); in timerlat_free_histogram()
63 if (data->hist[cpu].thread) in timerlat_free_histogram()
64 free(data->hist[cpu].thread); in timerlat_free_histogram()
66 if (data->hist[cpu].user) in timerlat_free_histogram()
67 free(data->hist[cpu].user); in timerlat_free_histogram()
72 if (data->hist) in timerlat_free_histogram()
73 free(data->hist); in timerlat_free_histogram()
78 timerlat_free_histogram(tool->data); in timerlat_free_histogram_tool()
83 * timerlat_alloc_histogram - alloc runtime data
91 data = calloc(1, sizeof(*data)); in timerlat_alloc_histogram()
95 data->entries = entries; in timerlat_alloc_histogram()
96 data->bucket_size = bucket_size; in timerlat_alloc_histogram()
97 data->nr_cpus = nr_cpus; in timerlat_alloc_histogram()
100 data->hist = calloc(1, sizeof(*data->hist) * nr_cpus); in timerlat_alloc_histogram()
101 if (!data->hist) in timerlat_alloc_histogram()
104 /* one histogram for IRQ and one for thread, per cpu */ in timerlat_alloc_histogram()
106 data->hist[cpu].irq = calloc(1, sizeof(*data->hist->irq) * (entries + 1)); in timerlat_alloc_histogram()
107 if (!data->hist[cpu].irq) in timerlat_alloc_histogram()
110 data->hist[cpu].thread = calloc(1, sizeof(*data->hist->thread) * (entries + 1)); in timerlat_alloc_histogram()
111 if (!data->hist[cpu].thread) in timerlat_alloc_histogram()
114 data->hist[cpu].user = calloc(1, sizeof(*data->hist->user) * (entries + 1)); in timerlat_alloc_histogram()
115 if (!data->hist[cpu].user) in timerlat_alloc_histogram()
121 data->hist[cpu].min_irq = ~0; in timerlat_alloc_histogram()
122 data->hist[cpu].min_thread = ~0; in timerlat_alloc_histogram()
123 data->hist[cpu].min_user = ~0; in timerlat_alloc_histogram()
134 * timerlat_hist_update - record a new timerlat occurent on cpu, updating data
141 struct timerlat_params *params = to_timerlat_params(tool->params); in timerlat_hist_update()
142 struct timerlat_hist_data *data = tool->data; in timerlat_hist_update()
143 int entries = data->entries; in timerlat_hist_update()
147 if (params->common.output_divisor) in timerlat_hist_update()
148 latency = latency / params->common.output_divisor; in timerlat_hist_update()
150 bucket = latency / data->bucket_size; in timerlat_hist_update()
153 hist = data->hist[cpu].irq; in timerlat_hist_update()
154 data->hist[cpu].irq_count++; in timerlat_hist_update()
155 update_min(&data->hist[cpu].min_irq, &latency); in timerlat_hist_update()
156 update_sum(&data->hist[cpu].sum_irq, &latency); in timerlat_hist_update()
157 update_max(&data->hist[cpu].max_irq, &latency); in timerlat_hist_update()
158 } else if (context == 1) { in timerlat_hist_update()
159 hist = data->hist[cpu].thread; in timerlat_hist_update()
160 data->hist[cpu].thread_count++; in timerlat_hist_update()
161 update_min(&data->hist[cpu].min_thread, &latency); in timerlat_hist_update()
162 update_sum(&data->hist[cpu].sum_thread, &latency); in timerlat_hist_update()
163 update_max(&data->hist[cpu].max_thread, &latency); in timerlat_hist_update()
165 hist = data->hist[cpu].user; in timerlat_hist_update()
166 data->hist[cpu].user_count++; in timerlat_hist_update()
167 update_min(&data->hist[cpu].min_user, &latency); in timerlat_hist_update()
168 update_sum(&data->hist[cpu].sum_user, &latency); in timerlat_hist_update()
169 update_max(&data->hist[cpu].max_user, &latency); in timerlat_hist_update()
179 * timerlat_hist_handler - this is the handler for timerlat tracer events
188 int cpu = record->cpu; in timerlat_hist_handler()
192 tep_get_field_val(s, event, "context", record, &context, 1); in timerlat_hist_handler()
193 tep_get_field_val(s, event, "timer_latency", record, &latency, 1); in timerlat_hist_handler()
201 * timerlat_hist_bpf_pull_data - copy data from BPF maps into userspace
205 struct timerlat_hist_data *data = tool->data; in timerlat_hist_bpf_pull_data()
207 long long value_irq[data->nr_cpus], in timerlat_hist_bpf_pull_data()
208 value_thread[data->nr_cpus], in timerlat_hist_bpf_pull_data()
209 value_user[data->nr_cpus]; in timerlat_hist_bpf_pull_data()
211 /* Pull histogram */ in timerlat_hist_bpf_pull_data()
212 for (i = 0; i < data->entries; i++) { in timerlat_hist_bpf_pull_data()
214 value_user, data->nr_cpus); in timerlat_hist_bpf_pull_data()
217 for (j = 0; j < data->nr_cpus; j++) { in timerlat_hist_bpf_pull_data()
218 data->hist[j].irq[i] = value_irq[j]; in timerlat_hist_bpf_pull_data()
219 data->hist[j].thread[i] = value_thread[j]; in timerlat_hist_bpf_pull_data()
220 data->hist[j].user[i] = value_user[j]; in timerlat_hist_bpf_pull_data()
227 data->nr_cpus); in timerlat_hist_bpf_pull_data()
230 for (i = 0; i < data->nr_cpus; i++) { in timerlat_hist_bpf_pull_data()
231 data->hist[i].irq_count = value_irq[i]; in timerlat_hist_bpf_pull_data()
232 data->hist[i].thread_count = value_thread[i]; in timerlat_hist_bpf_pull_data()
233 data->hist[i].user_count = value_user[i]; in timerlat_hist_bpf_pull_data()
238 data->nr_cpus); in timerlat_hist_bpf_pull_data()
241 for (i = 0; i < data->nr_cpus; i++) { in timerlat_hist_bpf_pull_data()
242 data->hist[i].min_irq = value_irq[i]; in timerlat_hist_bpf_pull_data()
243 data->hist[i].min_thread = value_thread[i]; in timerlat_hist_bpf_pull_data()
244 data->hist[i].min_user = value_user[i]; in timerlat_hist_bpf_pull_data()
249 data->nr_cpus); in timerlat_hist_bpf_pull_data()
252 for (i = 0; i < data->nr_cpus; i++) { in timerlat_hist_bpf_pull_data()
253 data->hist[i].max_irq = value_irq[i]; in timerlat_hist_bpf_pull_data()
254 data->hist[i].max_thread = value_thread[i]; in timerlat_hist_bpf_pull_data()
255 data->hist[i].max_user = value_user[i]; in timerlat_hist_bpf_pull_data()
260 data->nr_cpus); in timerlat_hist_bpf_pull_data()
263 for (i = 0; i < data->nr_cpus; i++) { in timerlat_hist_bpf_pull_data()
264 data->hist[i].sum_irq = value_irq[i]; in timerlat_hist_bpf_pull_data()
265 data->hist[i].sum_thread = value_thread[i]; in timerlat_hist_bpf_pull_data()
266 data->hist[i].sum_user = value_user[i]; in timerlat_hist_bpf_pull_data()
271 data->nr_cpus); in timerlat_hist_bpf_pull_data()
274 for (i = 0; i < data->nr_cpus; i++) { in timerlat_hist_bpf_pull_data()
275 data->hist[i].irq[data->entries] = value_irq[i]; in timerlat_hist_bpf_pull_data()
276 data->hist[i].thread[data->entries] = value_thread[i]; in timerlat_hist_bpf_pull_data()
277 data->hist[i].user[data->entries] = value_user[i]; in timerlat_hist_bpf_pull_data()
284 * timerlat_hist_header - print the header of the tracer to the output
288 struct timerlat_params *params = to_timerlat_params(tool->params); in timerlat_hist_header()
289 struct timerlat_hist_data *data = tool->data; in timerlat_hist_header()
290 struct trace_seq *s = tool->trace.seq; in timerlat_hist_header()
294 if (params->common.hist.no_header) in timerlat_hist_header()
297 get_duration(tool->start_time, duration, sizeof(duration)); in timerlat_hist_header()
298 trace_seq_printf(s, "# RTLA timerlat histogram\n"); in timerlat_hist_header()
300 params->common.output_divisor == 1 ? "nanoseconds" : "microseconds", in timerlat_hist_header()
301 params->common.output_divisor == 1 ? "ns" : "us"); in timerlat_hist_header()
305 if (!params->common.hist.no_index) in timerlat_hist_header()
308 for (cpu = 0; cpu < data->nr_cpus; cpu++) { in timerlat_hist_header()
309 if (params->common.cpus && !CPU_ISSET(cpu, &params->common.monitored_cpus)) in timerlat_hist_header()
312 if (!data->hist[cpu].irq_count && !data->hist[cpu].thread_count) in timerlat_hist_header()
315 if (!params->common.hist.no_irq) in timerlat_hist_header()
316 trace_seq_printf(s, " IRQ-%03d", cpu); in timerlat_hist_header()
318 if (!params->common.hist.no_thread) in timerlat_hist_header()
319 trace_seq_printf(s, " Thr-%03d", cpu); in timerlat_hist_header()
321 if (params->common.user_data) in timerlat_hist_header()
322 trace_seq_printf(s, " Usr-%03d", cpu); in timerlat_hist_header()
332 * format_summary_value - format a line of summary value (min, max or avg)
343 trace_seq_printf(seq, "%9c ", '-'); in format_summary_value()
347 * timerlat_print_summary - print the summary of the hist data to the output
356 if (params->common.hist.no_summary) in timerlat_print_summary()
359 if (!params->common.hist.no_index) in timerlat_print_summary()
360 trace_seq_printf(trace->seq, "count:"); in timerlat_print_summary()
362 for (cpu = 0; cpu < data->nr_cpus; cpu++) { in timerlat_print_summary()
363 if (params->common.cpus && !CPU_ISSET(cpu, &params->common.monitored_cpus)) in timerlat_print_summary()
366 if (!data->hist[cpu].irq_count && !data->hist[cpu].thread_count) in timerlat_print_summary()
369 if (!params->common.hist.no_irq) in timerlat_print_summary()
370 trace_seq_printf(trace->seq, "%9llu ", in timerlat_print_summary()
371 data->hist[cpu].irq_count); in timerlat_print_summary()
373 if (!params->common.hist.no_thread) in timerlat_print_summary()
374 trace_seq_printf(trace->seq, "%9llu ", in timerlat_print_summary()
375 data->hist[cpu].thread_count); in timerlat_print_summary()
377 if (params->common.user_data) in timerlat_print_summary()
378 trace_seq_printf(trace->seq, "%9llu ", in timerlat_print_summary()
379 data->hist[cpu].user_count); in timerlat_print_summary()
381 trace_seq_printf(trace->seq, "\n"); in timerlat_print_summary()
383 if (!params->common.hist.no_index) in timerlat_print_summary()
384 trace_seq_printf(trace->seq, "min: "); in timerlat_print_summary()
386 for (cpu = 0; cpu < data->nr_cpus; cpu++) { in timerlat_print_summary()
387 if (params->common.cpus && !CPU_ISSET(cpu, &params->common.monitored_cpus)) in timerlat_print_summary()
390 if (!data->hist[cpu].irq_count && !data->hist[cpu].thread_count) in timerlat_print_summary()
393 if (!params->common.hist.no_irq) in timerlat_print_summary()
394 format_summary_value(trace->seq, in timerlat_print_summary()
395 data->hist[cpu].irq_count, in timerlat_print_summary()
396 data->hist[cpu].min_irq, in timerlat_print_summary()
399 if (!params->common.hist.no_thread) in timerlat_print_summary()
400 format_summary_value(trace->seq, in timerlat_print_summary()
401 data->hist[cpu].thread_count, in timerlat_print_summary()
402 data->hist[cpu].min_thread, in timerlat_print_summary()
405 if (params->common.user_data) in timerlat_print_summary()
406 format_summary_value(trace->seq, in timerlat_print_summary()
407 data->hist[cpu].user_count, in timerlat_print_summary()
408 data->hist[cpu].min_user, in timerlat_print_summary()
411 trace_seq_printf(trace->seq, "\n"); in timerlat_print_summary()
413 if (!params->common.hist.no_index) in timerlat_print_summary()
414 trace_seq_printf(trace->seq, "avg: "); in timerlat_print_summary()
416 for (cpu = 0; cpu < data->nr_cpus; cpu++) { in timerlat_print_summary()
417 if (params->common.cpus && !CPU_ISSET(cpu, &params->common.monitored_cpus)) in timerlat_print_summary()
420 if (!data->hist[cpu].irq_count && !data->hist[cpu].thread_count) in timerlat_print_summary()
423 if (!params->common.hist.no_irq) in timerlat_print_summary()
424 format_summary_value(trace->seq, in timerlat_print_summary()
425 data->hist[cpu].irq_count, in timerlat_print_summary()
426 data->hist[cpu].sum_irq, in timerlat_print_summary()
429 if (!params->common.hist.no_thread) in timerlat_print_summary()
430 format_summary_value(trace->seq, in timerlat_print_summary()
431 data->hist[cpu].thread_count, in timerlat_print_summary()
432 data->hist[cpu].sum_thread, in timerlat_print_summary()
435 if (params->common.user_data) in timerlat_print_summary()
436 format_summary_value(trace->seq, in timerlat_print_summary()
437 data->hist[cpu].user_count, in timerlat_print_summary()
438 data->hist[cpu].sum_user, in timerlat_print_summary()
441 trace_seq_printf(trace->seq, "\n"); in timerlat_print_summary()
443 if (!params->common.hist.no_index) in timerlat_print_summary()
444 trace_seq_printf(trace->seq, "max: "); in timerlat_print_summary()
446 for (cpu = 0; cpu < data->nr_cpus; cpu++) { in timerlat_print_summary()
447 if (params->common.cpus && !CPU_ISSET(cpu, &params->common.monitored_cpus)) in timerlat_print_summary()
450 if (!data->hist[cpu].irq_count && !data->hist[cpu].thread_count) in timerlat_print_summary()
453 if (!params->common.hist.no_irq) in timerlat_print_summary()
454 format_summary_value(trace->seq, in timerlat_print_summary()
455 data->hist[cpu].irq_count, in timerlat_print_summary()
456 data->hist[cpu].max_irq, in timerlat_print_summary()
459 if (!params->common.hist.no_thread) in timerlat_print_summary()
460 format_summary_value(trace->seq, in timerlat_print_summary()
461 data->hist[cpu].thread_count, in timerlat_print_summary()
462 data->hist[cpu].max_thread, in timerlat_print_summary()
465 if (params->common.user_data) in timerlat_print_summary()
466 format_summary_value(trace->seq, in timerlat_print_summary()
467 data->hist[cpu].user_count, in timerlat_print_summary()
468 data->hist[cpu].max_user, in timerlat_print_summary()
471 trace_seq_printf(trace->seq, "\n"); in timerlat_print_summary()
472 trace_seq_do_printf(trace->seq); in timerlat_print_summary()
473 trace_seq_reset(trace->seq); in timerlat_print_summary()
485 if (params->common.hist.no_summary) in timerlat_print_stats_all()
493 for (cpu = 0; cpu < data->nr_cpus; cpu++) { in timerlat_print_stats_all()
494 if (params->common.cpus && !CPU_ISSET(cpu, &params->common.monitored_cpus)) in timerlat_print_stats_all()
497 if (!data->hist[cpu].irq_count && !data->hist[cpu].thread_count) in timerlat_print_stats_all()
500 cpu_data = &data->hist[cpu]; in timerlat_print_stats_all()
502 sum.irq_count += cpu_data->irq_count; in timerlat_print_stats_all()
503 update_min(&sum.min_irq, &cpu_data->min_irq); in timerlat_print_stats_all()
504 update_sum(&sum.sum_irq, &cpu_data->sum_irq); in timerlat_print_stats_all()
505 update_max(&sum.max_irq, &cpu_data->max_irq); in timerlat_print_stats_all()
507 sum.thread_count += cpu_data->thread_count; in timerlat_print_stats_all()
508 update_min(&sum.min_thread, &cpu_data->min_thread); in timerlat_print_stats_all()
509 update_sum(&sum.sum_thread, &cpu_data->sum_thread); in timerlat_print_stats_all()
510 update_max(&sum.max_thread, &cpu_data->max_thread); in timerlat_print_stats_all()
512 sum.user_count += cpu_data->user_count; in timerlat_print_stats_all()
513 update_min(&sum.min_user, &cpu_data->min_user); in timerlat_print_stats_all()
514 update_sum(&sum.sum_user, &cpu_data->sum_user); in timerlat_print_stats_all()
515 update_max(&sum.max_user, &cpu_data->max_user); in timerlat_print_stats_all()
518 if (!params->common.hist.no_index) in timerlat_print_stats_all()
519 trace_seq_printf(trace->seq, "ALL: "); in timerlat_print_stats_all()
521 if (!params->common.hist.no_irq) in timerlat_print_stats_all()
522 trace_seq_printf(trace->seq, " IRQ"); in timerlat_print_stats_all()
524 if (!params->common.hist.no_thread) in timerlat_print_stats_all()
525 trace_seq_printf(trace->seq, " Thr"); in timerlat_print_stats_all()
527 if (params->common.user_data) in timerlat_print_stats_all()
528 trace_seq_printf(trace->seq, " Usr"); in timerlat_print_stats_all()
530 trace_seq_printf(trace->seq, "\n"); in timerlat_print_stats_all()
532 if (!params->common.hist.no_index) in timerlat_print_stats_all()
533 trace_seq_printf(trace->seq, "count:"); in timerlat_print_stats_all()
535 if (!params->common.hist.no_irq) in timerlat_print_stats_all()
536 trace_seq_printf(trace->seq, "%9llu ", in timerlat_print_stats_all()
539 if (!params->common.hist.no_thread) in timerlat_print_stats_all()
540 trace_seq_printf(trace->seq, "%9llu ", in timerlat_print_stats_all()
543 if (params->common.user_data) in timerlat_print_stats_all()
544 trace_seq_printf(trace->seq, "%9llu ", in timerlat_print_stats_all()
547 trace_seq_printf(trace->seq, "\n"); in timerlat_print_stats_all()
549 if (!params->common.hist.no_index) in timerlat_print_stats_all()
550 trace_seq_printf(trace->seq, "min: "); in timerlat_print_stats_all()
552 if (!params->common.hist.no_irq) in timerlat_print_stats_all()
553 format_summary_value(trace->seq, in timerlat_print_stats_all()
558 if (!params->common.hist.no_thread) in timerlat_print_stats_all()
559 format_summary_value(trace->seq, in timerlat_print_stats_all()
564 if (params->common.user_data) in timerlat_print_stats_all()
565 format_summary_value(trace->seq, in timerlat_print_stats_all()
570 trace_seq_printf(trace->seq, "\n"); in timerlat_print_stats_all()
572 if (!params->common.hist.no_index) in timerlat_print_stats_all()
573 trace_seq_printf(trace->seq, "avg: "); in timerlat_print_stats_all()
575 if (!params->common.hist.no_irq) in timerlat_print_stats_all()
576 format_summary_value(trace->seq, in timerlat_print_stats_all()
581 if (!params->common.hist.no_thread) in timerlat_print_stats_all()
582 format_summary_value(trace->seq, in timerlat_print_stats_all()
587 if (params->common.user_data) in timerlat_print_stats_all()
588 format_summary_value(trace->seq, in timerlat_print_stats_all()
593 trace_seq_printf(trace->seq, "\n"); in timerlat_print_stats_all()
595 if (!params->common.hist.no_index) in timerlat_print_stats_all()
596 trace_seq_printf(trace->seq, "max: "); in timerlat_print_stats_all()
598 if (!params->common.hist.no_irq) in timerlat_print_stats_all()
599 format_summary_value(trace->seq, in timerlat_print_stats_all()
604 if (!params->common.hist.no_thread) in timerlat_print_stats_all()
605 format_summary_value(trace->seq, in timerlat_print_stats_all()
610 if (params->common.user_data) in timerlat_print_stats_all()
611 format_summary_value(trace->seq, in timerlat_print_stats_all()
616 trace_seq_printf(trace->seq, "\n"); in timerlat_print_stats_all()
617 trace_seq_do_printf(trace->seq); in timerlat_print_stats_all()
618 trace_seq_reset(trace->seq); in timerlat_print_stats_all()
622 * timerlat_print_stats - print data for each CPUs
627 struct timerlat_params *params = to_timerlat_params(tool->params); in timerlat_print_stats()
628 struct timerlat_hist_data *data = tool->data; in timerlat_print_stats()
629 struct trace_instance *trace = &tool->trace; in timerlat_print_stats()
635 for (bucket = 0; bucket < data->entries; bucket++) { in timerlat_print_stats()
638 if (!params->common.hist.no_index) in timerlat_print_stats()
639 trace_seq_printf(trace->seq, "%-6d", in timerlat_print_stats()
640 bucket * data->bucket_size); in timerlat_print_stats()
642 for (cpu = 0; cpu < data->nr_cpus; cpu++) { in timerlat_print_stats()
643 if (params->common.cpus && !CPU_ISSET(cpu, &params->common.monitored_cpus)) in timerlat_print_stats()
646 if (!data->hist[cpu].irq_count && !data->hist[cpu].thread_count) in timerlat_print_stats()
649 if (!params->common.hist.no_irq) { in timerlat_print_stats()
650 total += data->hist[cpu].irq[bucket]; in timerlat_print_stats()
651 trace_seq_printf(trace->seq, "%9d ", in timerlat_print_stats()
652 data->hist[cpu].irq[bucket]); in timerlat_print_stats()
655 if (!params->common.hist.no_thread) { in timerlat_print_stats()
656 total += data->hist[cpu].thread[bucket]; in timerlat_print_stats()
657 trace_seq_printf(trace->seq, "%9d ", in timerlat_print_stats()
658 data->hist[cpu].thread[bucket]); in timerlat_print_stats()
661 if (params->common.user_data) { in timerlat_print_stats()
662 total += data->hist[cpu].user[bucket]; in timerlat_print_stats()
663 trace_seq_printf(trace->seq, "%9d ", in timerlat_print_stats()
664 data->hist[cpu].user[bucket]); in timerlat_print_stats()
669 if (total == 0 && !params->common.hist.with_zeros) { in timerlat_print_stats()
670 trace_seq_reset(trace->seq); in timerlat_print_stats()
674 trace_seq_printf(trace->seq, "\n"); in timerlat_print_stats()
675 trace_seq_do_printf(trace->seq); in timerlat_print_stats()
676 trace_seq_reset(trace->seq); in timerlat_print_stats()
679 if (!params->common.hist.no_index) in timerlat_print_stats()
680 trace_seq_printf(trace->seq, "over: "); in timerlat_print_stats()
682 for (cpu = 0; cpu < data->nr_cpus; cpu++) { in timerlat_print_stats()
683 if (params->common.cpus && !CPU_ISSET(cpu, &params->common.monitored_cpus)) in timerlat_print_stats()
686 if (!data->hist[cpu].irq_count && !data->hist[cpu].thread_count) in timerlat_print_stats()
689 if (!params->common.hist.no_irq) in timerlat_print_stats()
690 trace_seq_printf(trace->seq, "%9d ", in timerlat_print_stats()
691 data->hist[cpu].irq[data->entries]); in timerlat_print_stats()
693 if (!params->common.hist.no_thread) in timerlat_print_stats()
694 trace_seq_printf(trace->seq, "%9d ", in timerlat_print_stats()
695 data->hist[cpu].thread[data->entries]); in timerlat_print_stats()
697 if (params->common.user_data) in timerlat_print_stats()
698 trace_seq_printf(trace->seq, "%9d ", in timerlat_print_stats()
699 data->hist[cpu].user[data->entries]); in timerlat_print_stats()
701 trace_seq_printf(trace->seq, "\n"); in timerlat_print_stats()
702 trace_seq_do_printf(trace->seq); in timerlat_print_stats()
703 trace_seq_reset(trace->seq); in timerlat_print_stats()
711 * timerlat_hist_usage - prints timerlat top usage message
719 …" usage: [rtla] timerlat hist [-h] [-q] [-d s] [-D] [-n] [-a us] [-p us] [-i us] [-T us] [-s us] … in timerlat_hist_usage()
720 …" [-t[file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] [-c cpu-list] [-H … in timerlat_hist_usage()
721 " [-P priority] [-E N] [-b N] [--no-irq] [--no-thread] [--no-header] [--no-summary] \\", in timerlat_hist_usage()
722 …" [--no-index] [--with-zeros] [--dma-latency us] [-C[=cgroup_name]] [--no-aa] [--dump-task] [-u| in timerlat_hist_usage()
723 " [--warm-up s] [--deepest-idle-state n]", in timerlat_hist_usage()
725 " -h/--help: print this menu", in timerlat_hist_usage()
726 " -a/--auto: set automatic trace mode, stopping the session if argument in us latency is hit", in timerlat_hist_usage()
727 " -p/--period us: timerlat period in us", in timerlat_hist_usage()
728 " -i/--irq us: stop trace if the irq latency is higher than the argument in us", in timerlat_hist_usage()
729 " -T/--thread us: stop trace if the thread latency is higher than the argument in us", in timerlat_hist_usage()
730 …" -s/--stack us: save the stack trace at the IRQ if a thread latency is higher than the argument… in timerlat_hist_usage()
731 " -c/--cpus cpus: run the tracer only on the given cpus", in timerlat_hist_usage()
732 " -H/--house-keeping cpus: run rtla control threads only on the given cpus", in timerlat_hist_usage()
733 …" -C/--cgroup[=cgroup_name]: set cgroup, if no cgroup_name is passed, the rtla's cgroup will be … in timerlat_hist_usage()
734 " -d/--duration time[m|h|d]: duration of the session in seconds", in timerlat_hist_usage()
735 …" --dump-tasks: prints the task running on all CPUs if stop conditions are met (depends on !-… in timerlat_hist_usage()
736 " -D/--debug: print debug info", in timerlat_hist_usage()
737 " -t/--trace[file]: save the stopped trace to [file|timerlat_trace.txt]", in timerlat_hist_usage()
738 …" -e/--event <sys:event>: enable the <sys:event> in the trace instance, multiple -e are allowed", in timerlat_hist_usage()
739 " --filter <filter>: enable a trace event filter to the previous -e event", in timerlat_hist_usage()
740 " --trigger <trigger>: enable a trace event trigger to the previous -e event", in timerlat_hist_usage()
741 " -n/--nano: display data in nanoseconds", in timerlat_hist_usage()
742 " --no-aa: disable auto-analysis, reducing rtla timerlat cpu usage", in timerlat_hist_usage()
743 " -b/--bucket-size N: set the histogram bucket size (default 1)", in timerlat_hist_usage()
744 " -E/--entries N: set the number of entries of the histogram (default 256)", in timerlat_hist_usage()
745 " --no-irq: ignore IRQ latencies", in timerlat_hist_usage()
746 " --no-thread: ignore thread latencies", in timerlat_hist_usage()
747 " --no-header: do not print header", in timerlat_hist_usage()
748 " --no-summary: do not print summary", in timerlat_hist_usage()
749 " --no-index: do not print index", in timerlat_hist_usage()
750 " --with-zeros: print zero only entries", in timerlat_hist_usage()
751 " --dma-latency us: set /dev/cpu_dma_latency latency <us> to reduce exit from idle latency", in timerlat_hist_usage()
752 " -P/--priority o:prio|r:prio|f:prio|d:runtime:period : set scheduling parameters", in timerlat_hist_usage()
753 " o:prio - use SCHED_OTHER with prio", in timerlat_hist_usage()
754 " r:prio - use SCHED_RR with prio", in timerlat_hist_usage()
755 " f:prio - use SCHED_FIFO with prio", in timerlat_hist_usage()
756 " d:runtime[us|ms|s]:period[us|ms|s] - use SCHED_DEADLINE with runtime and period", in timerlat_hist_usage()
758 " -u/--user-threads: use rtla user-space threads instead of kernel-space timerlat threads", in timerlat_hist_usage()
759 " -k/--kernel-threads: use timerlat kernel-space threads instead of rtla user-space threads", in timerlat_hist_usage()
760 " -U/--user-load: enable timerlat for user-defined user-space workload", in timerlat_hist_usage()
761 " --warm-up s: let the workload run for s seconds before collecting data", in timerlat_hist_usage()
762 " --trace-buffer-size kB: set the per-cpu trace buffer size in kB", in timerlat_hist_usage()
763 …" --deepest-idle-state n: only go down to idle state n on cpus used by timerlat to reduce exi… in timerlat_hist_usage()
764 …" --on-threshold <action>: define action to be executed at latency threshold, multiple are al… in timerlat_hist_usage()
765 " --on-end <action>: define action to be executed at measurement end, multiple are allowed", in timerlat_hist_usage()
772 fprintf(stderr, "rtla timerlat hist: a per-cpu histogram of the timer latency (version %s)\n", in timerlat_hist_usage()
785 * timerlat_hist_parse_args - allocs, parse and fill the cmd line parameters
797 params = calloc(1, sizeof(*params)); in timerlat_hist_parse_args()
799 exit(1); in timerlat_hist_parse_args()
801 actions_init(&params->common.threshold_actions); in timerlat_hist_parse_args()
802 actions_init(&params->common.end_actions); in timerlat_hist_parse_args()
805 params->dma_latency = -1; in timerlat_hist_parse_args()
808 params->deepest_idle_state = -2; in timerlat_hist_parse_args()
811 params->common.output_divisor = 1000; in timerlat_hist_parse_args()
812 params->common.hist.bucket_size = 1; in timerlat_hist_parse_args()
813 params->common.hist.entries = 256; in timerlat_hist_parse_args()
816 params->mode = TRACING_MODE_BPF; in timerlat_hist_parse_args()
818 while (1) { in timerlat_hist_parse_args()
823 {"bucket-size", required_argument, 0, 'b'}, in timerlat_hist_parse_args()
824 {"debug", no_argument, 0, 'D'}, in timerlat_hist_parse_args()
826 {"duration", required_argument, 0, 'd'}, in timerlat_hist_parse_args()
827 {"house-keeping", required_argument, 0, 'H'}, in timerlat_hist_parse_args()
836 {"user-threads", no_argument, 0, 'u'}, in timerlat_hist_parse_args()
837 {"kernel-threads", no_argument, 0, 'k'}, in timerlat_hist_parse_args()
838 {"user-load", no_argument, 0, 'U'}, in timerlat_hist_parse_args()
840 {"no-irq", no_argument, 0, '0'}, in timerlat_hist_parse_args()
841 {"no-thread", no_argument, 0, '1'}, in timerlat_hist_parse_args()
842 {"no-header", no_argument, 0, '2'}, in timerlat_hist_parse_args()
843 {"no-summary", no_argument, 0, '3'}, in timerlat_hist_parse_args()
844 {"no-index", no_argument, 0, '4'}, in timerlat_hist_parse_args()
845 {"with-zeros", no_argument, 0, '5'}, in timerlat_hist_parse_args()
848 {"dma-latency", required_argument, 0, '8'}, in timerlat_hist_parse_args()
849 {"no-aa", no_argument, 0, '9'}, in timerlat_hist_parse_args()
850 {"dump-task", no_argument, 0, '\1'}, in timerlat_hist_parse_args()
851 {"warm-up", required_argument, 0, '\2'}, in timerlat_hist_parse_args()
852 {"trace-buffer-size", required_argument, 0, '\3'}, in timerlat_hist_parse_args()
853 {"deepest-idle-state", required_argument, 0, '\4'}, in timerlat_hist_parse_args()
854 {"on-threshold", required_argument, 0, '\5'}, in timerlat_hist_parse_args()
855 {"on-end", required_argument, 0, '\6'}, in timerlat_hist_parse_args()
862 c = getopt_long(argc, argv, "a:c:C::b:d:e:E:DhH:i:knp:P:s:t::T:uU0123456:7:8:9\1\2:\3:", in timerlat_hist_parse_args()
866 if (c == -1) in timerlat_hist_parse_args()
874 params->common.stop_total_us = auto_thresh; in timerlat_hist_parse_args()
875 params->common.stop_us = auto_thresh; in timerlat_hist_parse_args()
878 params->print_stack = auto_thresh; in timerlat_hist_parse_args()
885 retval = parse_cpu_set(optarg, &params->common.monitored_cpus); in timerlat_hist_parse_args()
887 timerlat_hist_usage("\nInvalid -c cpu list\n"); in timerlat_hist_parse_args()
888 params->common.cpus = optarg; in timerlat_hist_parse_args()
891 params->common.cgroup = 1; in timerlat_hist_parse_args()
894 params->common.cgroup_name = NULL; in timerlat_hist_parse_args()
897 params->common.cgroup_name = ++optarg; in timerlat_hist_parse_args()
901 params->common.hist.bucket_size = get_llong_from_str(optarg); in timerlat_hist_parse_args()
902 if (params->common.hist.bucket_size == 0 || in timerlat_hist_parse_args()
903 params->common.hist.bucket_size >= 1000000) in timerlat_hist_parse_args()
906 case 'D': in timerlat_hist_parse_args()
907 config_debug = 1; in timerlat_hist_parse_args()
909 case 'd': in timerlat_hist_parse_args()
910 params->common.duration = parse_seconds_duration(optarg); in timerlat_hist_parse_args()
911 if (!params->common.duration) in timerlat_hist_parse_args()
912 timerlat_hist_usage("Invalid -D duration\n"); in timerlat_hist_parse_args()
921 if (params->common.events) in timerlat_hist_parse_args()
922 tevent->next = params->common.events; in timerlat_hist_parse_args()
924 params->common.events = tevent; in timerlat_hist_parse_args()
927 params->common.hist.entries = get_llong_from_str(optarg); in timerlat_hist_parse_args()
928 if (params->common.hist.entries < 10 || in timerlat_hist_parse_args()
929 params->common.hist.entries > 9999999) in timerlat_hist_parse_args()
937 params->common.hk_cpus = 1; in timerlat_hist_parse_args()
938 retval = parse_cpu_set(optarg, &params->common.hk_cpu_set); in timerlat_hist_parse_args()
945 params->common.stop_us = get_llong_from_str(optarg); in timerlat_hist_parse_args()
948 params->common.kernel_workload = 1; in timerlat_hist_parse_args()
951 params->common.output_divisor = 1; in timerlat_hist_parse_args()
954 params->timerlat_period_us = get_llong_from_str(optarg); in timerlat_hist_parse_args()
955 if (params->timerlat_period_us > 1000000) in timerlat_hist_parse_args()
956 timerlat_hist_usage("Period longer than 1 s\n"); in timerlat_hist_parse_args()
959 retval = parse_prio(optarg, &params->common.sched_param); in timerlat_hist_parse_args()
960 if (retval == -1) in timerlat_hist_parse_args()
961 timerlat_hist_usage("Invalid -P priority"); in timerlat_hist_parse_args()
962 params->common.set_sched = 1; in timerlat_hist_parse_args()
965 params->print_stack = get_llong_from_str(optarg); in timerlat_hist_parse_args()
968 params->common.stop_total_us = get_llong_from_str(optarg); in timerlat_hist_parse_args()
973 trace_output = &optarg[1]; in timerlat_hist_parse_args()
976 } else if (optind < argc && argv[optind][0] != '-') in timerlat_hist_parse_args()
982 params->common.user_workload = 1; in timerlat_hist_parse_args()
983 /* fallback: -u implies in -U */ in timerlat_hist_parse_args()
985 params->common.user_data = 1; in timerlat_hist_parse_args()
988 params->common.hist.no_irq = 1; in timerlat_hist_parse_args()
990 case '1': /* no thread */ in timerlat_hist_parse_args()
991 params->common.hist.no_thread = 1; in timerlat_hist_parse_args()
994 params->common.hist.no_header = 1; in timerlat_hist_parse_args()
997 params->common.hist.no_summary = 1; in timerlat_hist_parse_args()
1000 params->common.hist.no_index = 1; in timerlat_hist_parse_args()
1003 params->common.hist.with_zeros = 1; in timerlat_hist_parse_args()
1006 if (params->common.events) { in timerlat_hist_parse_args()
1007 retval = trace_event_add_trigger(params->common.events, optarg); in timerlat_hist_parse_args()
1013 timerlat_hist_usage("--trigger requires a previous -e\n"); in timerlat_hist_parse_args()
1017 if (params->common.events) { in timerlat_hist_parse_args()
1018 retval = trace_event_add_filter(params->common.events, optarg); in timerlat_hist_parse_args()
1024 timerlat_hist_usage("--filter requires a previous -e\n"); in timerlat_hist_parse_args()
1028 params->dma_latency = get_llong_from_str(optarg); in timerlat_hist_parse_args()
1029 if (params->dma_latency < 0 || params->dma_latency > 10000) { in timerlat_hist_parse_args()
1030 err_msg("--dma-latency needs to be >= 0 and < 10000"); in timerlat_hist_parse_args()
1035 params->no_aa = 1; in timerlat_hist_parse_args()
1037 case '\1': in timerlat_hist_parse_args()
1038 params->dump_tasks = 1; in timerlat_hist_parse_args()
1041 params->common.warmup = get_llong_from_str(optarg); in timerlat_hist_parse_args()
1044 params->common.buffer_size = get_llong_from_str(optarg); in timerlat_hist_parse_args()
1047 params->deepest_idle_state = get_llong_from_str(optarg); in timerlat_hist_parse_args()
1050 retval = actions_parse(&params->common.threshold_actions, optarg, in timerlat_hist_parse_args()
1058 retval = actions_parse(&params->common.end_actions, optarg, in timerlat_hist_parse_args()
1071 actions_add_trace_output(&params->common.threshold_actions, trace_output); in timerlat_hist_parse_args()
1078 if (params->common.hist.no_irq && params->common.hist.no_thread) in timerlat_hist_parse_args()
1079 timerlat_hist_usage("no-irq and no-thread set, there is nothing to do here"); in timerlat_hist_parse_args()
1081 if (params->common.hist.no_index && !params->common.hist.with_zeros) in timerlat_hist_parse_args()
1082 timerlat_hist_usage("no-index set with with-zeros is not set - it does not make sense"); in timerlat_hist_parse_args()
1087 if (!params->common.stop_us && !params->common.stop_total_us) in timerlat_hist_parse_args()
1088 params->no_aa = 1; in timerlat_hist_parse_args()
1090 if (params->common.kernel_workload && params->common.user_workload) in timerlat_hist_parse_args()
1091 timerlat_hist_usage("--kernel-threads and --user-threads are mutually exclusive!"); in timerlat_hist_parse_args()
1094 * If auto-analysis or trace output is enabled, switch from BPF mode to in timerlat_hist_parse_args()
1097 if (params->mode == TRACING_MODE_BPF && in timerlat_hist_parse_args()
1098 (params->common.threshold_actions.present[ACTION_TRACE_OUTPUT] || in timerlat_hist_parse_args()
1099 params->common.end_actions.present[ACTION_TRACE_OUTPUT] || in timerlat_hist_parse_args()
1100 !params->no_aa)) in timerlat_hist_parse_args()
1101 params->mode = TRACING_MODE_MIXED; in timerlat_hist_parse_args()
1103 return &params->common; in timerlat_hist_parse_args()
1107 * timerlat_hist_apply_config - apply the hist configs to the initialized tool
1112 struct timerlat_params *params = to_timerlat_params(tool->params); in timerlat_hist_apply_config()
1122 return -1; in timerlat_hist_apply_config()
1126 * timerlat_init_hist - initialize a timerlat hist tool with parameters
1140 tool->data = timerlat_alloc_histogram(nr_cpus, params->hist.entries, in timerlat_init_hist()
1141 params->hist.bucket_size); in timerlat_init_hist()
1142 if (!tool->data) in timerlat_init_hist()
1145 tep_register_event_handler(tool->trace.tep, -1, "ftrace", "timerlat", in timerlat_init_hist()
1157 struct timerlat_params *params = to_timerlat_params(tool->params); in timerlat_hist_bpf_main_loop()
1161 timerlat_bpf_wait(-1); in timerlat_hist_bpf_main_loop()
1165 actions_perform(&params->common.threshold_actions); in timerlat_hist_bpf_main_loop()
1167 if (!params->common.threshold_actions.continue_flag) in timerlat_hist_bpf_main_loop()
1171 /* continue action reached, re-enable tracing */ in timerlat_hist_bpf_main_loop()
1172 if (tool->record) in timerlat_hist_bpf_main_loop()
1173 trace_instance_start(&tool->record->trace); in timerlat_hist_bpf_main_loop()
1174 if (tool->aa) in timerlat_hist_bpf_main_loop()
1175 trace_instance_start(&tool->aa->trace); in timerlat_hist_bpf_main_loop()
1190 struct timerlat_params *params = to_timerlat_params(tool->params); in timerlat_hist_main()
1193 if (params->mode == TRACING_MODE_TRACEFS) in timerlat_hist_main()