On Wed, Oct 27, 2021 at 12:06:22AM +0200, Daniel Bristot de Oliveira wrote: > The rtla osnoise hist tool collects all osnoise:sample_threshold > occurrence in a histogram, displaying the results in a user-friendly > way. The tool also allows many configurations of the osnoise tracer > and the collection of the tracer output. > > Here is one example of the rtla osnoise hist tool output: > ---------- %< ---------- > [root@f34 ~]# rtla osnoise hist --bucket-size 10 --entries 100 -c 0-8 -d 1M -r 9000 -P F:1 > # RTLA osnoise histogram > # Time unit is microseconds (us) > # Duration: 0 00:01:00 > Index CPU-000 CPU-001 CPU-002 CPU-003 CPU-004 CPU-005 CPU-006 CPU-007 CPU-008 > 0 430 434 352 455 440 463 467 436 484 > 10 88 88 92 141 120 100 126 166 100 > 20 19 7 12 22 8 8 13 13 16 > 30 6 0 2 0 1 2 2 1 0 > 50 0 0 0 0 0 0 1 0 0 > over: 0 0 0 0 0 0 0 0 0 > count: 543 529 458 618 569 573 609 616 600 > min: 0 0 0 0 0 0 0 0 0 > avg: 0 0 0 0 0 0 0 0 0 > max: 30 20 30 20 30 30 50 30 20 > ---------- >% ---------- > > Running > - rtla osnoise hist --help > > provides information about the available options. > > Cc: Steven Rostedt <rostedt@xxxxxxxxxxx> > Cc: Ingo Molnar <mingo@xxxxxxxxxx> > Cc: Tom Zanussi <zanussi@xxxxxxxxxx> > Cc: Masami Hiramatsu <mhiramat@xxxxxxxxxx> > Cc: Juri Lelli <juri.lelli@xxxxxxxxxx> > Cc: Clark Williams <williams@xxxxxxxxxx> > Cc: John Kacur <jkacur@xxxxxxxxxx> > Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx> > Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> > Cc: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx> > Cc: Daniel Bristot de Oliveira <bristot@xxxxxxxxxx> > Cc: linux-rt-users@xxxxxxxxxxxxxxx > Cc: linux-trace-devel@xxxxxxxxxxxxxxx > Cc: linux-kernel@xxxxxxxxxxxxxxx > Signed-off-by: Daniel Bristot de Oliveira <bristot@xxxxxxxxxx> > --- > tools/tracing/rtla/src/osnoise.c | 6 +- > tools/tracing/rtla/src/osnoise.h | 1 + > tools/tracing/rtla/src/osnoise_hist.c | 793 ++++++++++++++++++++++++++ > 3 files changed, 799 insertions(+), 1 deletion(-) > create mode 100644 tools/tracing/rtla/src/osnoise_hist.c > > diff --git a/tools/tracing/rtla/src/osnoise.c b/tools/tracing/rtla/src/osnoise.c > index b9866dfdda66..6c6358ebf66f 100644 > --- a/tools/tracing/rtla/src/osnoise.c > +++ b/tools/tracing/rtla/src/osnoise.c > @@ -790,7 +790,8 @@ static void osnoise_usage(void) > " usage: [rtla] osnoise [MODE] ...", > "", > " modes:", > - " top - prints the summary from osnoise tracer", > + " top - prints the summary from osnoise tracer", > + " hist - prints a histogram of osnoise samples", > "", > "if no MODE is given, the top mode is called, passing the arguments", > NULL, > @@ -825,6 +826,9 @@ int osnoise_main(int argc, char *argv[]) > } else if (strcmp(argv[1], "top") == 0) { > osnoise_top_main(argc-1, &argv[1]); > exit(0); > + } else if (strcmp(argv[1], "hist") == 0) { > + osnoise_hist_main(argc-1, &argv[1]); > + exit(0); > } > > usage: > diff --git a/tools/tracing/rtla/src/osnoise.h b/tools/tracing/rtla/src/osnoise.h > index 4882ee275ea0..dbaad7a162a2 100644 > --- a/tools/tracing/rtla/src/osnoise.h > +++ b/tools/tracing/rtla/src/osnoise.h > @@ -82,5 +82,6 @@ void osnoise_destroy_tool(struct osnoise_tool *top); > struct osnoise_tool *osnoise_init_tool(char *tool_name); > struct osnoise_tool *osnoise_init_trace_tool(char *tracer); > > +int osnoise_hist_main(int argc, char *argv[]); > int osnoise_top_main(int argc, char **argv); > int osnoise_main(int argc, char **argv); > diff --git a/tools/tracing/rtla/src/osnoise_hist.c b/tools/tracing/rtla/src/osnoise_hist.c > new file mode 100644 > index 000000000000..c93f30d69795 > --- /dev/null > +++ b/tools/tracing/rtla/src/osnoise_hist.c > @@ -0,0 +1,793 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2021 Red Hat Inc, Daniel Bristot de Oliveira <bristot@xxxxxxxxxx> > + */ > + > +#include <getopt.h> > +#include <stdlib.h> > +#include <string.h> > +#include <signal.h> > +#include <unistd.h> > +#include <errno.h> > +#include <stdio.h> > +#include <time.h> > + > +#include "utils.h" > +#include "osnoise.h" > + > +struct osnoise_hist_params { > + char *cpus; > + char *monitored_cpus; > + char *trace_output; > + unsigned long long runtime; > + unsigned long long period; > + long long stop_us; > + long long stop_total_us; > + int sleep_time; > + int duration; > + int set_sched; > + int output_divisor; > + struct sched_attr sched_param; > + > + char no_header; > + char no_summary; > + char no_index; > + char with_zeros; > + int bucket_size; > + int entries; > +}; > + > +struct osnoise_hist_cpu { > + int *samples; > + int *thread; > + > + int count; > + int thread_count; > + > + unsigned long long min_sample; > + unsigned long long sum_sample; > + unsigned long long max_sample; > + > + unsigned long long min_thread; > + unsigned long long sum_thread; > + unsigned long long max_thread; > +}; > + > +struct osnoise_hist_data { > + struct tracefs_hist *trace_hist; > + struct osnoise_hist_cpu *hist; > + int entries; > + int bucket_size; > + int nr_cpus; > +}; > + > +/* > + * osnoise_free_histogram - free runtime data > + */ > +static void > +osnoise_free_histogram(struct osnoise_hist_data *data) > +{ > + int cpu; > + > + /* one histogram for IRQ and one for thread, per CPU */ > + for (cpu = 0; cpu < data->nr_cpus; cpu++) { > + if (data->hist[cpu].samples) > + free(data->hist[cpu].samples); > + > + if (data->hist[cpu].thread) > + free(data->hist[cpu].thread); > + } > + > + /* one set of histograms per CPU */ > + if (data->hist) > + free(data->hist); > + > + free(data); > +} > + > +/* > + * osnoise_alloc_histogram - alloc runtime data > + */ > +static struct osnoise_hist_data > +*osnoise_alloc_histogram(int nr_cpus, int entries, int bucket_size) > +{ > + struct osnoise_hist_data *data; > + int cpu; > + > + data = calloc(1, sizeof(*data)); > + if (!data) > + return NULL; > + > + data->entries = entries; > + data->bucket_size = bucket_size; > + data->nr_cpus = nr_cpus; > + > + /* one set of histograms per CPU */ > + data->hist = calloc(1, sizeof(*data->hist) * nr_cpus); > + if (!data->hist) > + goto cleanup; > + > + /* one histogram for IRQ and one for thread, per cpu */ > + for (cpu = 0; cpu < nr_cpus; cpu++) { > + data->hist[cpu].samples = calloc(1, sizeof(*data->hist) * (entries + 1)); @samples is a pointer to int and used for int array. The "sizeof(*data->hist)" should be "sizeof(int)" or am I totally wrong. The same in PATCH 13. Thanks, Tao