1829a6c0bSDaniel Bristot de Oliveira // SPDX-License-Identifier: GPL-2.0 2829a6c0bSDaniel Bristot de Oliveira /* 3829a6c0bSDaniel Bristot de Oliveira * Copyright (C) 2021 Red Hat Inc, Daniel Bristot de Oliveira <bristot@kernel.org> 4829a6c0bSDaniel Bristot de Oliveira */ 5829a6c0bSDaniel Bristot de Oliveira 6272ced25SDaniel Bristot de Oliveira #define _GNU_SOURCE 7829a6c0bSDaniel Bristot de Oliveira #include <getopt.h> 8829a6c0bSDaniel Bristot de Oliveira #include <stdlib.h> 9829a6c0bSDaniel Bristot de Oliveira #include <string.h> 10829a6c0bSDaniel Bristot de Oliveira #include <signal.h> 11829a6c0bSDaniel Bristot de Oliveira #include <unistd.h> 12829a6c0bSDaniel Bristot de Oliveira #include <errno.h> 13829a6c0bSDaniel Bristot de Oliveira #include <stdio.h> 14829a6c0bSDaniel Bristot de Oliveira #include <time.h> 15272ced25SDaniel Bristot de Oliveira #include <sched.h> 16829a6c0bSDaniel Bristot de Oliveira 17829a6c0bSDaniel Bristot de Oliveira #include "utils.h" 18829a6c0bSDaniel Bristot de Oliveira #include "osnoise.h" 19829a6c0bSDaniel Bristot de Oliveira 20829a6c0bSDaniel Bristot de Oliveira struct osnoise_hist_params { 21829a6c0bSDaniel Bristot de Oliveira char *cpus; 22894c29c7SDaniel Bristot de Oliveira cpu_set_t monitored_cpus; 23829a6c0bSDaniel Bristot de Oliveira char *trace_output; 24a957cbc0SDaniel Bristot de Oliveira char *cgroup_name; 25829a6c0bSDaniel Bristot de Oliveira unsigned long long runtime; 26829a6c0bSDaniel Bristot de Oliveira unsigned long long period; 27d635316aSDaniel Bristot de Oliveira long long threshold; 28829a6c0bSDaniel Bristot de Oliveira long long stop_us; 29829a6c0bSDaniel Bristot de Oliveira long long stop_total_us; 30829a6c0bSDaniel Bristot de Oliveira int sleep_time; 31829a6c0bSDaniel Bristot de Oliveira int duration; 32829a6c0bSDaniel Bristot de Oliveira int set_sched; 33829a6c0bSDaniel Bristot de Oliveira int output_divisor; 34a957cbc0SDaniel Bristot de Oliveira int cgroup; 35272ced25SDaniel Bristot de Oliveira int hk_cpus; 36272ced25SDaniel Bristot de Oliveira cpu_set_t hk_cpu_set; 37829a6c0bSDaniel Bristot de Oliveira struct sched_attr sched_param; 3851d64c3aSDaniel Bristot de Oliveira struct trace_events *events; 39829a6c0bSDaniel Bristot de Oliveira 40829a6c0bSDaniel Bristot de Oliveira char no_header; 41829a6c0bSDaniel Bristot de Oliveira char no_summary; 42829a6c0bSDaniel Bristot de Oliveira char no_index; 43829a6c0bSDaniel Bristot de Oliveira char with_zeros; 44829a6c0bSDaniel Bristot de Oliveira int bucket_size; 45829a6c0bSDaniel Bristot de Oliveira int entries; 46829a6c0bSDaniel Bristot de Oliveira }; 47829a6c0bSDaniel Bristot de Oliveira 48829a6c0bSDaniel Bristot de Oliveira struct osnoise_hist_cpu { 49829a6c0bSDaniel Bristot de Oliveira int *samples; 50829a6c0bSDaniel Bristot de Oliveira int count; 51829a6c0bSDaniel Bristot de Oliveira 52829a6c0bSDaniel Bristot de Oliveira unsigned long long min_sample; 53829a6c0bSDaniel Bristot de Oliveira unsigned long long sum_sample; 54829a6c0bSDaniel Bristot de Oliveira unsigned long long max_sample; 55829a6c0bSDaniel Bristot de Oliveira 56829a6c0bSDaniel Bristot de Oliveira }; 57829a6c0bSDaniel Bristot de Oliveira 58829a6c0bSDaniel Bristot de Oliveira struct osnoise_hist_data { 59829a6c0bSDaniel Bristot de Oliveira struct tracefs_hist *trace_hist; 60829a6c0bSDaniel Bristot de Oliveira struct osnoise_hist_cpu *hist; 61829a6c0bSDaniel Bristot de Oliveira int entries; 62829a6c0bSDaniel Bristot de Oliveira int bucket_size; 63829a6c0bSDaniel Bristot de Oliveira int nr_cpus; 64829a6c0bSDaniel Bristot de Oliveira }; 65829a6c0bSDaniel Bristot de Oliveira 66829a6c0bSDaniel Bristot de Oliveira /* 67829a6c0bSDaniel Bristot de Oliveira * osnoise_free_histogram - free runtime data 68829a6c0bSDaniel Bristot de Oliveira */ 69829a6c0bSDaniel Bristot de Oliveira static void 70829a6c0bSDaniel Bristot de Oliveira osnoise_free_histogram(struct osnoise_hist_data *data) 71829a6c0bSDaniel Bristot de Oliveira { 72829a6c0bSDaniel Bristot de Oliveira int cpu; 73829a6c0bSDaniel Bristot de Oliveira 74829a6c0bSDaniel Bristot de Oliveira /* one histogram for IRQ and one for thread, per CPU */ 75829a6c0bSDaniel Bristot de Oliveira for (cpu = 0; cpu < data->nr_cpus; cpu++) { 76829a6c0bSDaniel Bristot de Oliveira if (data->hist[cpu].samples) 77829a6c0bSDaniel Bristot de Oliveira free(data->hist[cpu].samples); 78829a6c0bSDaniel Bristot de Oliveira } 79829a6c0bSDaniel Bristot de Oliveira 80829a6c0bSDaniel Bristot de Oliveira /* one set of histograms per CPU */ 81829a6c0bSDaniel Bristot de Oliveira if (data->hist) 82829a6c0bSDaniel Bristot de Oliveira free(data->hist); 83829a6c0bSDaniel Bristot de Oliveira 84829a6c0bSDaniel Bristot de Oliveira free(data); 85829a6c0bSDaniel Bristot de Oliveira } 86829a6c0bSDaniel Bristot de Oliveira 87829a6c0bSDaniel Bristot de Oliveira /* 88829a6c0bSDaniel Bristot de Oliveira * osnoise_alloc_histogram - alloc runtime data 89829a6c0bSDaniel Bristot de Oliveira */ 90829a6c0bSDaniel Bristot de Oliveira static struct osnoise_hist_data 91829a6c0bSDaniel Bristot de Oliveira *osnoise_alloc_histogram(int nr_cpus, int entries, int bucket_size) 92829a6c0bSDaniel Bristot de Oliveira { 93829a6c0bSDaniel Bristot de Oliveira struct osnoise_hist_data *data; 94829a6c0bSDaniel Bristot de Oliveira int cpu; 95829a6c0bSDaniel Bristot de Oliveira 96829a6c0bSDaniel Bristot de Oliveira data = calloc(1, sizeof(*data)); 97829a6c0bSDaniel Bristot de Oliveira if (!data) 98829a6c0bSDaniel Bristot de Oliveira return NULL; 99829a6c0bSDaniel Bristot de Oliveira 100829a6c0bSDaniel Bristot de Oliveira data->entries = entries; 101829a6c0bSDaniel Bristot de Oliveira data->bucket_size = bucket_size; 102829a6c0bSDaniel Bristot de Oliveira data->nr_cpus = nr_cpus; 103829a6c0bSDaniel Bristot de Oliveira 104829a6c0bSDaniel Bristot de Oliveira data->hist = calloc(1, sizeof(*data->hist) * nr_cpus); 105829a6c0bSDaniel Bristot de Oliveira if (!data->hist) 106829a6c0bSDaniel Bristot de Oliveira goto cleanup; 107829a6c0bSDaniel Bristot de Oliveira 108829a6c0bSDaniel Bristot de Oliveira for (cpu = 0; cpu < nr_cpus; cpu++) { 109829a6c0bSDaniel Bristot de Oliveira data->hist[cpu].samples = calloc(1, sizeof(*data->hist->samples) * (entries + 1)); 110829a6c0bSDaniel Bristot de Oliveira if (!data->hist[cpu].samples) 111829a6c0bSDaniel Bristot de Oliveira goto cleanup; 112829a6c0bSDaniel Bristot de Oliveira } 113829a6c0bSDaniel Bristot de Oliveira 114829a6c0bSDaniel Bristot de Oliveira /* set the min to max */ 115829a6c0bSDaniel Bristot de Oliveira for (cpu = 0; cpu < nr_cpus; cpu++) 116829a6c0bSDaniel Bristot de Oliveira data->hist[cpu].min_sample = ~0; 117829a6c0bSDaniel Bristot de Oliveira 118829a6c0bSDaniel Bristot de Oliveira return data; 119829a6c0bSDaniel Bristot de Oliveira 120829a6c0bSDaniel Bristot de Oliveira cleanup: 121829a6c0bSDaniel Bristot de Oliveira osnoise_free_histogram(data); 122829a6c0bSDaniel Bristot de Oliveira return NULL; 123829a6c0bSDaniel Bristot de Oliveira } 124829a6c0bSDaniel Bristot de Oliveira 125829a6c0bSDaniel Bristot de Oliveira static void osnoise_hist_update_multiple(struct osnoise_tool *tool, int cpu, 126829a6c0bSDaniel Bristot de Oliveira unsigned long long duration, int count) 127829a6c0bSDaniel Bristot de Oliveira { 128829a6c0bSDaniel Bristot de Oliveira struct osnoise_hist_params *params = tool->params; 129829a6c0bSDaniel Bristot de Oliveira struct osnoise_hist_data *data = tool->data; 130fe137a4fSAndreas Ziegler unsigned long long total_duration; 131829a6c0bSDaniel Bristot de Oliveira int entries = data->entries; 132829a6c0bSDaniel Bristot de Oliveira int bucket; 133829a6c0bSDaniel Bristot de Oliveira int *hist; 134829a6c0bSDaniel Bristot de Oliveira 135829a6c0bSDaniel Bristot de Oliveira if (params->output_divisor) 136829a6c0bSDaniel Bristot de Oliveira duration = duration / params->output_divisor; 137829a6c0bSDaniel Bristot de Oliveira 138829a6c0bSDaniel Bristot de Oliveira if (data->bucket_size) 139829a6c0bSDaniel Bristot de Oliveira bucket = duration / data->bucket_size; 140829a6c0bSDaniel Bristot de Oliveira 141fe137a4fSAndreas Ziegler total_duration = duration * count; 142fe137a4fSAndreas Ziegler 143829a6c0bSDaniel Bristot de Oliveira hist = data->hist[cpu].samples; 144829a6c0bSDaniel Bristot de Oliveira data->hist[cpu].count += count; 145829a6c0bSDaniel Bristot de Oliveira update_min(&data->hist[cpu].min_sample, &duration); 146fe137a4fSAndreas Ziegler update_sum(&data->hist[cpu].sum_sample, &total_duration); 147829a6c0bSDaniel Bristot de Oliveira update_max(&data->hist[cpu].max_sample, &duration); 148829a6c0bSDaniel Bristot de Oliveira 149829a6c0bSDaniel Bristot de Oliveira if (bucket < entries) 150829a6c0bSDaniel Bristot de Oliveira hist[bucket] += count; 151829a6c0bSDaniel Bristot de Oliveira else 152829a6c0bSDaniel Bristot de Oliveira hist[entries] += count; 153829a6c0bSDaniel Bristot de Oliveira } 154829a6c0bSDaniel Bristot de Oliveira 155829a6c0bSDaniel Bristot de Oliveira /* 156829a6c0bSDaniel Bristot de Oliveira * osnoise_destroy_trace_hist - disable events used to collect histogram 157829a6c0bSDaniel Bristot de Oliveira */ 158829a6c0bSDaniel Bristot de Oliveira static void osnoise_destroy_trace_hist(struct osnoise_tool *tool) 159829a6c0bSDaniel Bristot de Oliveira { 160829a6c0bSDaniel Bristot de Oliveira struct osnoise_hist_data *data = tool->data; 161829a6c0bSDaniel Bristot de Oliveira 162829a6c0bSDaniel Bristot de Oliveira tracefs_hist_pause(tool->trace.inst, data->trace_hist); 163829a6c0bSDaniel Bristot de Oliveira tracefs_hist_destroy(tool->trace.inst, data->trace_hist); 164829a6c0bSDaniel Bristot de Oliveira } 165829a6c0bSDaniel Bristot de Oliveira 166829a6c0bSDaniel Bristot de Oliveira /* 167829a6c0bSDaniel Bristot de Oliveira * osnoise_init_trace_hist - enable events used to collect histogram 168829a6c0bSDaniel Bristot de Oliveira */ 169829a6c0bSDaniel Bristot de Oliveira static int osnoise_init_trace_hist(struct osnoise_tool *tool) 170829a6c0bSDaniel Bristot de Oliveira { 171829a6c0bSDaniel Bristot de Oliveira struct osnoise_hist_params *params = tool->params; 172829a6c0bSDaniel Bristot de Oliveira struct osnoise_hist_data *data = tool->data; 173829a6c0bSDaniel Bristot de Oliveira int bucket_size; 174829a6c0bSDaniel Bristot de Oliveira char buff[128]; 175829a6c0bSDaniel Bristot de Oliveira int retval = 0; 176829a6c0bSDaniel Bristot de Oliveira 177829a6c0bSDaniel Bristot de Oliveira /* 178829a6c0bSDaniel Bristot de Oliveira * Set the size of the bucket. 179829a6c0bSDaniel Bristot de Oliveira */ 180829a6c0bSDaniel Bristot de Oliveira bucket_size = params->output_divisor * params->bucket_size; 181829a6c0bSDaniel Bristot de Oliveira snprintf(buff, sizeof(buff), "duration.buckets=%d", bucket_size); 182829a6c0bSDaniel Bristot de Oliveira 183829a6c0bSDaniel Bristot de Oliveira data->trace_hist = tracefs_hist_alloc(tool->trace.tep, "osnoise", "sample_threshold", 184829a6c0bSDaniel Bristot de Oliveira buff, TRACEFS_HIST_KEY_NORMAL); 185829a6c0bSDaniel Bristot de Oliveira if (!data->trace_hist) 186829a6c0bSDaniel Bristot de Oliveira return 1; 187829a6c0bSDaniel Bristot de Oliveira 188829a6c0bSDaniel Bristot de Oliveira retval = tracefs_hist_add_key(data->trace_hist, "cpu", 0); 189829a6c0bSDaniel Bristot de Oliveira if (retval) 190829a6c0bSDaniel Bristot de Oliveira goto out_err; 191829a6c0bSDaniel Bristot de Oliveira 192829a6c0bSDaniel Bristot de Oliveira retval = tracefs_hist_start(tool->trace.inst, data->trace_hist); 193829a6c0bSDaniel Bristot de Oliveira if (retval) 194829a6c0bSDaniel Bristot de Oliveira goto out_err; 195829a6c0bSDaniel Bristot de Oliveira 196829a6c0bSDaniel Bristot de Oliveira return 0; 197829a6c0bSDaniel Bristot de Oliveira 198829a6c0bSDaniel Bristot de Oliveira out_err: 199829a6c0bSDaniel Bristot de Oliveira osnoise_destroy_trace_hist(tool); 200829a6c0bSDaniel Bristot de Oliveira return 1; 201829a6c0bSDaniel Bristot de Oliveira } 202829a6c0bSDaniel Bristot de Oliveira 203829a6c0bSDaniel Bristot de Oliveira /* 204829a6c0bSDaniel Bristot de Oliveira * osnoise_read_trace_hist - parse histogram file and file osnoise histogram 205829a6c0bSDaniel Bristot de Oliveira */ 206829a6c0bSDaniel Bristot de Oliveira static void osnoise_read_trace_hist(struct osnoise_tool *tool) 207829a6c0bSDaniel Bristot de Oliveira { 208829a6c0bSDaniel Bristot de Oliveira struct osnoise_hist_data *data = tool->data; 209829a6c0bSDaniel Bristot de Oliveira long long cpu, counter, duration; 210829a6c0bSDaniel Bristot de Oliveira char *content, *position; 211829a6c0bSDaniel Bristot de Oliveira 212829a6c0bSDaniel Bristot de Oliveira tracefs_hist_pause(tool->trace.inst, data->trace_hist); 213829a6c0bSDaniel Bristot de Oliveira 214829a6c0bSDaniel Bristot de Oliveira content = tracefs_event_file_read(tool->trace.inst, "osnoise", 215829a6c0bSDaniel Bristot de Oliveira "sample_threshold", 216829a6c0bSDaniel Bristot de Oliveira "hist", NULL); 217829a6c0bSDaniel Bristot de Oliveira if (!content) 218829a6c0bSDaniel Bristot de Oliveira return; 219829a6c0bSDaniel Bristot de Oliveira 220829a6c0bSDaniel Bristot de Oliveira position = content; 221829a6c0bSDaniel Bristot de Oliveira while (true) { 222829a6c0bSDaniel Bristot de Oliveira position = strstr(position, "duration: ~"); 223829a6c0bSDaniel Bristot de Oliveira if (!position) 224829a6c0bSDaniel Bristot de Oliveira break; 225829a6c0bSDaniel Bristot de Oliveira position += strlen("duration: ~"); 226829a6c0bSDaniel Bristot de Oliveira duration = get_llong_from_str(position); 227829a6c0bSDaniel Bristot de Oliveira if (duration == -1) 228829a6c0bSDaniel Bristot de Oliveira err_msg("error reading duration from histogram\n"); 229829a6c0bSDaniel Bristot de Oliveira 230829a6c0bSDaniel Bristot de Oliveira position = strstr(position, "cpu:"); 231829a6c0bSDaniel Bristot de Oliveira if (!position) 232829a6c0bSDaniel Bristot de Oliveira break; 233829a6c0bSDaniel Bristot de Oliveira position += strlen("cpu: "); 234829a6c0bSDaniel Bristot de Oliveira cpu = get_llong_from_str(position); 235829a6c0bSDaniel Bristot de Oliveira if (cpu == -1) 236829a6c0bSDaniel Bristot de Oliveira err_msg("error reading cpu from histogram\n"); 237829a6c0bSDaniel Bristot de Oliveira 238829a6c0bSDaniel Bristot de Oliveira position = strstr(position, "hitcount:"); 239829a6c0bSDaniel Bristot de Oliveira if (!position) 240829a6c0bSDaniel Bristot de Oliveira break; 241829a6c0bSDaniel Bristot de Oliveira position += strlen("hitcount: "); 242829a6c0bSDaniel Bristot de Oliveira counter = get_llong_from_str(position); 243829a6c0bSDaniel Bristot de Oliveira if (counter == -1) 244829a6c0bSDaniel Bristot de Oliveira err_msg("error reading counter from histogram\n"); 245829a6c0bSDaniel Bristot de Oliveira 246829a6c0bSDaniel Bristot de Oliveira osnoise_hist_update_multiple(tool, cpu, duration, counter); 247829a6c0bSDaniel Bristot de Oliveira } 248829a6c0bSDaniel Bristot de Oliveira free(content); 249829a6c0bSDaniel Bristot de Oliveira } 250829a6c0bSDaniel Bristot de Oliveira 251829a6c0bSDaniel Bristot de Oliveira /* 252829a6c0bSDaniel Bristot de Oliveira * osnoise_hist_header - print the header of the tracer to the output 253829a6c0bSDaniel Bristot de Oliveira */ 254829a6c0bSDaniel Bristot de Oliveira static void osnoise_hist_header(struct osnoise_tool *tool) 255829a6c0bSDaniel Bristot de Oliveira { 256829a6c0bSDaniel Bristot de Oliveira struct osnoise_hist_params *params = tool->params; 257829a6c0bSDaniel Bristot de Oliveira struct osnoise_hist_data *data = tool->data; 258829a6c0bSDaniel Bristot de Oliveira struct trace_seq *s = tool->trace.seq; 259829a6c0bSDaniel Bristot de Oliveira char duration[26]; 260829a6c0bSDaniel Bristot de Oliveira int cpu; 261829a6c0bSDaniel Bristot de Oliveira 262829a6c0bSDaniel Bristot de Oliveira if (params->no_header) 263829a6c0bSDaniel Bristot de Oliveira return; 264829a6c0bSDaniel Bristot de Oliveira 265829a6c0bSDaniel Bristot de Oliveira get_duration(tool->start_time, duration, sizeof(duration)); 266829a6c0bSDaniel Bristot de Oliveira trace_seq_printf(s, "# RTLA osnoise histogram\n"); 267829a6c0bSDaniel Bristot de Oliveira trace_seq_printf(s, "# Time unit is %s (%s)\n", 268829a6c0bSDaniel Bristot de Oliveira params->output_divisor == 1 ? "nanoseconds" : "microseconds", 269829a6c0bSDaniel Bristot de Oliveira params->output_divisor == 1 ? "ns" : "us"); 270829a6c0bSDaniel Bristot de Oliveira 271829a6c0bSDaniel Bristot de Oliveira trace_seq_printf(s, "# Duration: %s\n", duration); 272829a6c0bSDaniel Bristot de Oliveira 273829a6c0bSDaniel Bristot de Oliveira if (!params->no_index) 274829a6c0bSDaniel Bristot de Oliveira trace_seq_printf(s, "Index"); 275829a6c0bSDaniel Bristot de Oliveira 276829a6c0bSDaniel Bristot de Oliveira for (cpu = 0; cpu < data->nr_cpus; cpu++) { 277894c29c7SDaniel Bristot de Oliveira if (params->cpus && !CPU_ISSET(cpu, ¶ms->monitored_cpus)) 278829a6c0bSDaniel Bristot de Oliveira continue; 279829a6c0bSDaniel Bristot de Oliveira 280829a6c0bSDaniel Bristot de Oliveira if (!data->hist[cpu].count) 281829a6c0bSDaniel Bristot de Oliveira continue; 282829a6c0bSDaniel Bristot de Oliveira 283829a6c0bSDaniel Bristot de Oliveira trace_seq_printf(s, " CPU-%03d", cpu); 284829a6c0bSDaniel Bristot de Oliveira } 285829a6c0bSDaniel Bristot de Oliveira trace_seq_printf(s, "\n"); 286829a6c0bSDaniel Bristot de Oliveira 287829a6c0bSDaniel Bristot de Oliveira trace_seq_do_printf(s); 288829a6c0bSDaniel Bristot de Oliveira trace_seq_reset(s); 289829a6c0bSDaniel Bristot de Oliveira } 290829a6c0bSDaniel Bristot de Oliveira 291829a6c0bSDaniel Bristot de Oliveira /* 292829a6c0bSDaniel Bristot de Oliveira * osnoise_print_summary - print the summary of the hist data to the output 293829a6c0bSDaniel Bristot de Oliveira */ 294829a6c0bSDaniel Bristot de Oliveira static void 295829a6c0bSDaniel Bristot de Oliveira osnoise_print_summary(struct osnoise_hist_params *params, 296829a6c0bSDaniel Bristot de Oliveira struct trace_instance *trace, 297829a6c0bSDaniel Bristot de Oliveira struct osnoise_hist_data *data) 298829a6c0bSDaniel Bristot de Oliveira { 299829a6c0bSDaniel Bristot de Oliveira int cpu; 300829a6c0bSDaniel Bristot de Oliveira 301829a6c0bSDaniel Bristot de Oliveira if (params->no_summary) 302829a6c0bSDaniel Bristot de Oliveira return; 303829a6c0bSDaniel Bristot de Oliveira 304829a6c0bSDaniel Bristot de Oliveira if (!params->no_index) 305829a6c0bSDaniel Bristot de Oliveira trace_seq_printf(trace->seq, "count:"); 306829a6c0bSDaniel Bristot de Oliveira 307829a6c0bSDaniel Bristot de Oliveira for (cpu = 0; cpu < data->nr_cpus; cpu++) { 308894c29c7SDaniel Bristot de Oliveira if (params->cpus && !CPU_ISSET(cpu, ¶ms->monitored_cpus)) 309829a6c0bSDaniel Bristot de Oliveira continue; 310829a6c0bSDaniel Bristot de Oliveira 311829a6c0bSDaniel Bristot de Oliveira if (!data->hist[cpu].count) 312829a6c0bSDaniel Bristot de Oliveira continue; 313829a6c0bSDaniel Bristot de Oliveira 314829a6c0bSDaniel Bristot de Oliveira trace_seq_printf(trace->seq, "%9d ", data->hist[cpu].count); 315829a6c0bSDaniel Bristot de Oliveira } 316829a6c0bSDaniel Bristot de Oliveira trace_seq_printf(trace->seq, "\n"); 317829a6c0bSDaniel Bristot de Oliveira 318829a6c0bSDaniel Bristot de Oliveira if (!params->no_index) 319829a6c0bSDaniel Bristot de Oliveira trace_seq_printf(trace->seq, "min: "); 320829a6c0bSDaniel Bristot de Oliveira 321829a6c0bSDaniel Bristot de Oliveira for (cpu = 0; cpu < data->nr_cpus; cpu++) { 322894c29c7SDaniel Bristot de Oliveira if (params->cpus && !CPU_ISSET(cpu, ¶ms->monitored_cpus)) 323829a6c0bSDaniel Bristot de Oliveira continue; 324829a6c0bSDaniel Bristot de Oliveira 325829a6c0bSDaniel Bristot de Oliveira if (!data->hist[cpu].count) 326829a6c0bSDaniel Bristot de Oliveira continue; 327829a6c0bSDaniel Bristot de Oliveira 328829a6c0bSDaniel Bristot de Oliveira trace_seq_printf(trace->seq, "%9llu ", data->hist[cpu].min_sample); 329829a6c0bSDaniel Bristot de Oliveira 330829a6c0bSDaniel Bristot de Oliveira } 331829a6c0bSDaniel Bristot de Oliveira trace_seq_printf(trace->seq, "\n"); 332829a6c0bSDaniel Bristot de Oliveira 333829a6c0bSDaniel Bristot de Oliveira if (!params->no_index) 334829a6c0bSDaniel Bristot de Oliveira trace_seq_printf(trace->seq, "avg: "); 335829a6c0bSDaniel Bristot de Oliveira 336829a6c0bSDaniel Bristot de Oliveira for (cpu = 0; cpu < data->nr_cpus; cpu++) { 337894c29c7SDaniel Bristot de Oliveira if (params->cpus && !CPU_ISSET(cpu, ¶ms->monitored_cpus)) 338829a6c0bSDaniel Bristot de Oliveira continue; 339829a6c0bSDaniel Bristot de Oliveira 340829a6c0bSDaniel Bristot de Oliveira if (!data->hist[cpu].count) 341829a6c0bSDaniel Bristot de Oliveira continue; 342829a6c0bSDaniel Bristot de Oliveira 343829a6c0bSDaniel Bristot de Oliveira if (data->hist[cpu].count) 3441fab1469SAndreas Ziegler trace_seq_printf(trace->seq, "%9.2f ", 3451fab1469SAndreas Ziegler ((double) data->hist[cpu].sum_sample) / data->hist[cpu].count); 346829a6c0bSDaniel Bristot de Oliveira else 347829a6c0bSDaniel Bristot de Oliveira trace_seq_printf(trace->seq, " - "); 348829a6c0bSDaniel Bristot de Oliveira } 349829a6c0bSDaniel Bristot de Oliveira trace_seq_printf(trace->seq, "\n"); 350829a6c0bSDaniel Bristot de Oliveira 351829a6c0bSDaniel Bristot de Oliveira if (!params->no_index) 352829a6c0bSDaniel Bristot de Oliveira trace_seq_printf(trace->seq, "max: "); 353829a6c0bSDaniel Bristot de Oliveira 354829a6c0bSDaniel Bristot de Oliveira for (cpu = 0; cpu < data->nr_cpus; cpu++) { 355894c29c7SDaniel Bristot de Oliveira if (params->cpus && !CPU_ISSET(cpu, ¶ms->monitored_cpus)) 356829a6c0bSDaniel Bristot de Oliveira continue; 357829a6c0bSDaniel Bristot de Oliveira 358829a6c0bSDaniel Bristot de Oliveira if (!data->hist[cpu].count) 359829a6c0bSDaniel Bristot de Oliveira continue; 360829a6c0bSDaniel Bristot de Oliveira 361829a6c0bSDaniel Bristot de Oliveira trace_seq_printf(trace->seq, "%9llu ", data->hist[cpu].max_sample); 362829a6c0bSDaniel Bristot de Oliveira 363829a6c0bSDaniel Bristot de Oliveira } 364829a6c0bSDaniel Bristot de Oliveira trace_seq_printf(trace->seq, "\n"); 365829a6c0bSDaniel Bristot de Oliveira trace_seq_do_printf(trace->seq); 366829a6c0bSDaniel Bristot de Oliveira trace_seq_reset(trace->seq); 367829a6c0bSDaniel Bristot de Oliveira } 368829a6c0bSDaniel Bristot de Oliveira 369829a6c0bSDaniel Bristot de Oliveira /* 370829a6c0bSDaniel Bristot de Oliveira * osnoise_print_stats - print data for all CPUs 371829a6c0bSDaniel Bristot de Oliveira */ 372829a6c0bSDaniel Bristot de Oliveira static void 373829a6c0bSDaniel Bristot de Oliveira osnoise_print_stats(struct osnoise_hist_params *params, struct osnoise_tool *tool) 374829a6c0bSDaniel Bristot de Oliveira { 375829a6c0bSDaniel Bristot de Oliveira struct osnoise_hist_data *data = tool->data; 376829a6c0bSDaniel Bristot de Oliveira struct trace_instance *trace = &tool->trace; 377829a6c0bSDaniel Bristot de Oliveira int bucket, cpu; 378829a6c0bSDaniel Bristot de Oliveira int total; 379829a6c0bSDaniel Bristot de Oliveira 380829a6c0bSDaniel Bristot de Oliveira osnoise_hist_header(tool); 381829a6c0bSDaniel Bristot de Oliveira 382829a6c0bSDaniel Bristot de Oliveira for (bucket = 0; bucket < data->entries; bucket++) { 383829a6c0bSDaniel Bristot de Oliveira total = 0; 384829a6c0bSDaniel Bristot de Oliveira 385829a6c0bSDaniel Bristot de Oliveira if (!params->no_index) 386829a6c0bSDaniel Bristot de Oliveira trace_seq_printf(trace->seq, "%-6d", 387829a6c0bSDaniel Bristot de Oliveira bucket * data->bucket_size); 388829a6c0bSDaniel Bristot de Oliveira 389829a6c0bSDaniel Bristot de Oliveira for (cpu = 0; cpu < data->nr_cpus; cpu++) { 390894c29c7SDaniel Bristot de Oliveira if (params->cpus && !CPU_ISSET(cpu, ¶ms->monitored_cpus)) 391829a6c0bSDaniel Bristot de Oliveira continue; 392829a6c0bSDaniel Bristot de Oliveira 393829a6c0bSDaniel Bristot de Oliveira if (!data->hist[cpu].count) 394829a6c0bSDaniel Bristot de Oliveira continue; 395829a6c0bSDaniel Bristot de Oliveira 396829a6c0bSDaniel Bristot de Oliveira total += data->hist[cpu].samples[bucket]; 397829a6c0bSDaniel Bristot de Oliveira trace_seq_printf(trace->seq, "%9d ", data->hist[cpu].samples[bucket]); 398829a6c0bSDaniel Bristot de Oliveira } 399829a6c0bSDaniel Bristot de Oliveira 400829a6c0bSDaniel Bristot de Oliveira if (total == 0 && !params->with_zeros) { 401829a6c0bSDaniel Bristot de Oliveira trace_seq_reset(trace->seq); 402829a6c0bSDaniel Bristot de Oliveira continue; 403829a6c0bSDaniel Bristot de Oliveira } 404829a6c0bSDaniel Bristot de Oliveira 405829a6c0bSDaniel Bristot de Oliveira trace_seq_printf(trace->seq, "\n"); 406829a6c0bSDaniel Bristot de Oliveira trace_seq_do_printf(trace->seq); 407829a6c0bSDaniel Bristot de Oliveira trace_seq_reset(trace->seq); 408829a6c0bSDaniel Bristot de Oliveira } 409829a6c0bSDaniel Bristot de Oliveira 410829a6c0bSDaniel Bristot de Oliveira if (!params->no_index) 411829a6c0bSDaniel Bristot de Oliveira trace_seq_printf(trace->seq, "over: "); 412829a6c0bSDaniel Bristot de Oliveira 413829a6c0bSDaniel Bristot de Oliveira for (cpu = 0; cpu < data->nr_cpus; cpu++) { 414894c29c7SDaniel Bristot de Oliveira if (params->cpus && !CPU_ISSET(cpu, ¶ms->monitored_cpus)) 415829a6c0bSDaniel Bristot de Oliveira continue; 416829a6c0bSDaniel Bristot de Oliveira 417829a6c0bSDaniel Bristot de Oliveira if (!data->hist[cpu].count) 418829a6c0bSDaniel Bristot de Oliveira continue; 419829a6c0bSDaniel Bristot de Oliveira 420829a6c0bSDaniel Bristot de Oliveira trace_seq_printf(trace->seq, "%9d ", 421829a6c0bSDaniel Bristot de Oliveira data->hist[cpu].samples[data->entries]); 422829a6c0bSDaniel Bristot de Oliveira } 423829a6c0bSDaniel Bristot de Oliveira trace_seq_printf(trace->seq, "\n"); 424829a6c0bSDaniel Bristot de Oliveira trace_seq_do_printf(trace->seq); 425829a6c0bSDaniel Bristot de Oliveira trace_seq_reset(trace->seq); 426829a6c0bSDaniel Bristot de Oliveira 427829a6c0bSDaniel Bristot de Oliveira osnoise_print_summary(params, trace, data); 428829a6c0bSDaniel Bristot de Oliveira } 429829a6c0bSDaniel Bristot de Oliveira 430829a6c0bSDaniel Bristot de Oliveira /* 431829a6c0bSDaniel Bristot de Oliveira * osnoise_hist_usage - prints osnoise hist usage message 432829a6c0bSDaniel Bristot de Oliveira */ 433829a6c0bSDaniel Bristot de Oliveira static void osnoise_hist_usage(char *usage) 434829a6c0bSDaniel Bristot de Oliveira { 435829a6c0bSDaniel Bristot de Oliveira int i; 436829a6c0bSDaniel Bristot de Oliveira 437829a6c0bSDaniel Bristot de Oliveira static const char * const msg[] = { 438829a6c0bSDaniel Bristot de Oliveira "", 4392b622eddSDaniel Bristot de Oliveira " usage: rtla osnoise hist [-h] [-D] [-d s] [-a us] [-p us] [-r us] [-s us] [-S us] \\", 44044f3a37dSDaniel Bristot de Oliveira " [-T us] [-t[=file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] \\", 441272ced25SDaniel Bristot de Oliveira " [-c cpu-list] [-H cpu-list] [-P priority] [-b N] [-E N] [--no-header] [--no-summary] \\", 442272ced25SDaniel Bristot de Oliveira " [--no-index] [--with-zeros] [-C[=cgroup_name]]", 443829a6c0bSDaniel Bristot de Oliveira "", 444829a6c0bSDaniel Bristot de Oliveira " -h/--help: print this menu", 4452b622eddSDaniel Bristot de Oliveira " -a/--auto: set automatic trace mode, stopping the session if argument in us sample is hit", 446829a6c0bSDaniel Bristot de Oliveira " -p/--period us: osnoise period in us", 447829a6c0bSDaniel Bristot de Oliveira " -r/--runtime us: osnoise runtime in us", 448829a6c0bSDaniel Bristot de Oliveira " -s/--stop us: stop trace if a single sample is higher than the argument in us", 449829a6c0bSDaniel Bristot de Oliveira " -S/--stop-total us: stop trace if the total sample is higher than the argument in us", 450d635316aSDaniel Bristot de Oliveira " -T/--threshold us: the minimum delta to be considered a noise", 451829a6c0bSDaniel Bristot de Oliveira " -c/--cpus cpu-list: list of cpus to run osnoise threads", 452272ced25SDaniel Bristot de Oliveira " -H/--house-keeping cpus: run rtla control threads only on the given cpus", 453a957cbc0SDaniel Bristot de Oliveira " -C/--cgroup[=cgroup_name]: set cgroup, if no cgroup_name is passed, the rtla's cgroup will be inherited", 454829a6c0bSDaniel Bristot de Oliveira " -d/--duration time[s|m|h|d]: duration of the session", 455829a6c0bSDaniel Bristot de Oliveira " -D/--debug: print debug info", 456829a6c0bSDaniel Bristot de Oliveira " -t/--trace[=file]: save the stopped trace to [file|osnoise_trace.txt]", 45751d64c3aSDaniel Bristot de Oliveira " -e/--event <sys:event>: enable the <sys:event> in the trace instance, multiple -e are allowed", 45844f3a37dSDaniel Bristot de Oliveira " --filter <filter>: enable a trace event filter to the previous -e event", 4591a754893SDaniel Bristot de Oliveira " --trigger <trigger>: enable a trace event trigger to the previous -e event", 460829a6c0bSDaniel Bristot de Oliveira " -b/--bucket-size N: set the histogram bucket size (default 1)", 461dd48f316SDaniel Bristot de Oliveira " -E/--entries N: set the number of entries of the histogram (default 256)", 462829a6c0bSDaniel Bristot de Oliveira " --no-header: do not print header", 463829a6c0bSDaniel Bristot de Oliveira " --no-summary: do not print summary", 464829a6c0bSDaniel Bristot de Oliveira " --no-index: do not print index", 465829a6c0bSDaniel Bristot de Oliveira " --with-zeros: print zero only entries", 466829a6c0bSDaniel Bristot de Oliveira " -P/--priority o:prio|r:prio|f:prio|d:runtime:period: set scheduling parameters", 467829a6c0bSDaniel Bristot de Oliveira " o:prio - use SCHED_OTHER with prio", 468829a6c0bSDaniel Bristot de Oliveira " r:prio - use SCHED_RR with prio", 469829a6c0bSDaniel Bristot de Oliveira " f:prio - use SCHED_FIFO with prio", 470829a6c0bSDaniel Bristot de Oliveira " d:runtime[us|ms|s]:period[us|ms|s] - use SCHED_DEADLINE with runtime and period", 471829a6c0bSDaniel Bristot de Oliveira " in nanoseconds", 472829a6c0bSDaniel Bristot de Oliveira NULL, 473829a6c0bSDaniel Bristot de Oliveira }; 474829a6c0bSDaniel Bristot de Oliveira 475829a6c0bSDaniel Bristot de Oliveira if (usage) 476829a6c0bSDaniel Bristot de Oliveira fprintf(stderr, "%s\n", usage); 477829a6c0bSDaniel Bristot de Oliveira 478829a6c0bSDaniel Bristot de Oliveira fprintf(stderr, "rtla osnoise hist: a per-cpu histogram of the OS noise (version %s)\n", 479829a6c0bSDaniel Bristot de Oliveira VERSION); 480829a6c0bSDaniel Bristot de Oliveira 481829a6c0bSDaniel Bristot de Oliveira for (i = 0; msg[i]; i++) 482829a6c0bSDaniel Bristot de Oliveira fprintf(stderr, "%s\n", msg[i]); 483*7c3611caSJohn Kacur 484*7c3611caSJohn Kacur if (usage) 485*7c3611caSJohn Kacur exit(EXIT_FAILURE); 486*7c3611caSJohn Kacur 487*7c3611caSJohn Kacur exit(EXIT_SUCCESS); 488829a6c0bSDaniel Bristot de Oliveira } 489829a6c0bSDaniel Bristot de Oliveira 490829a6c0bSDaniel Bristot de Oliveira /* 491829a6c0bSDaniel Bristot de Oliveira * osnoise_hist_parse_args - allocs, parse and fill the cmd line parameters 492829a6c0bSDaniel Bristot de Oliveira */ 493829a6c0bSDaniel Bristot de Oliveira static struct osnoise_hist_params 494829a6c0bSDaniel Bristot de Oliveira *osnoise_hist_parse_args(int argc, char *argv[]) 495829a6c0bSDaniel Bristot de Oliveira { 496829a6c0bSDaniel Bristot de Oliveira struct osnoise_hist_params *params; 49751d64c3aSDaniel Bristot de Oliveira struct trace_events *tevent; 498829a6c0bSDaniel Bristot de Oliveira int retval; 499829a6c0bSDaniel Bristot de Oliveira int c; 500829a6c0bSDaniel Bristot de Oliveira 501829a6c0bSDaniel Bristot de Oliveira params = calloc(1, sizeof(*params)); 502829a6c0bSDaniel Bristot de Oliveira if (!params) 503829a6c0bSDaniel Bristot de Oliveira exit(1); 504829a6c0bSDaniel Bristot de Oliveira 505829a6c0bSDaniel Bristot de Oliveira /* display data in microseconds */ 506829a6c0bSDaniel Bristot de Oliveira params->output_divisor = 1000; 507829a6c0bSDaniel Bristot de Oliveira params->bucket_size = 1; 508829a6c0bSDaniel Bristot de Oliveira params->entries = 256; 509829a6c0bSDaniel Bristot de Oliveira 510829a6c0bSDaniel Bristot de Oliveira while (1) { 511829a6c0bSDaniel Bristot de Oliveira static struct option long_options[] = { 5122b622eddSDaniel Bristot de Oliveira {"auto", required_argument, 0, 'a'}, 513829a6c0bSDaniel Bristot de Oliveira {"bucket-size", required_argument, 0, 'b'}, 514dd48f316SDaniel Bristot de Oliveira {"entries", required_argument, 0, 'E'}, 515829a6c0bSDaniel Bristot de Oliveira {"cpus", required_argument, 0, 'c'}, 516a957cbc0SDaniel Bristot de Oliveira {"cgroup", optional_argument, 0, 'C'}, 517829a6c0bSDaniel Bristot de Oliveira {"debug", no_argument, 0, 'D'}, 518829a6c0bSDaniel Bristot de Oliveira {"duration", required_argument, 0, 'd'}, 519272ced25SDaniel Bristot de Oliveira {"house-keeping", required_argument, 0, 'H'}, 520829a6c0bSDaniel Bristot de Oliveira {"help", no_argument, 0, 'h'}, 521829a6c0bSDaniel Bristot de Oliveira {"period", required_argument, 0, 'p'}, 522829a6c0bSDaniel Bristot de Oliveira {"priority", required_argument, 0, 'P'}, 523829a6c0bSDaniel Bristot de Oliveira {"runtime", required_argument, 0, 'r'}, 524829a6c0bSDaniel Bristot de Oliveira {"stop", required_argument, 0, 's'}, 525829a6c0bSDaniel Bristot de Oliveira {"stop-total", required_argument, 0, 'S'}, 526829a6c0bSDaniel Bristot de Oliveira {"trace", optional_argument, 0, 't'}, 52751d64c3aSDaniel Bristot de Oliveira {"event", required_argument, 0, 'e'}, 528d635316aSDaniel Bristot de Oliveira {"threshold", required_argument, 0, 'T'}, 529829a6c0bSDaniel Bristot de Oliveira {"no-header", no_argument, 0, '0'}, 530829a6c0bSDaniel Bristot de Oliveira {"no-summary", no_argument, 0, '1'}, 531829a6c0bSDaniel Bristot de Oliveira {"no-index", no_argument, 0, '2'}, 532829a6c0bSDaniel Bristot de Oliveira {"with-zeros", no_argument, 0, '3'}, 5331a754893SDaniel Bristot de Oliveira {"trigger", required_argument, 0, '4'}, 53444f3a37dSDaniel Bristot de Oliveira {"filter", required_argument, 0, '5'}, 535829a6c0bSDaniel Bristot de Oliveira {0, 0, 0, 0} 536829a6c0bSDaniel Bristot de Oliveira }; 537829a6c0bSDaniel Bristot de Oliveira 538829a6c0bSDaniel Bristot de Oliveira /* getopt_long stores the option index here. */ 539829a6c0bSDaniel Bristot de Oliveira int option_index = 0; 540829a6c0bSDaniel Bristot de Oliveira 541272ced25SDaniel Bristot de Oliveira c = getopt_long(argc, argv, "a:c:C::b:d:e:E:DhH:p:P:r:s:S:t::T:01234:5:", 542829a6c0bSDaniel Bristot de Oliveira long_options, &option_index); 543829a6c0bSDaniel Bristot de Oliveira 544829a6c0bSDaniel Bristot de Oliveira /* detect the end of the options. */ 545829a6c0bSDaniel Bristot de Oliveira if (c == -1) 546829a6c0bSDaniel Bristot de Oliveira break; 547829a6c0bSDaniel Bristot de Oliveira 548829a6c0bSDaniel Bristot de Oliveira switch (c) { 5492b622eddSDaniel Bristot de Oliveira case 'a': 5502b622eddSDaniel Bristot de Oliveira /* set sample stop to auto_thresh */ 5512b622eddSDaniel Bristot de Oliveira params->stop_us = get_llong_from_str(optarg); 5522b622eddSDaniel Bristot de Oliveira 5532b622eddSDaniel Bristot de Oliveira /* set sample threshold to 1 */ 5542b622eddSDaniel Bristot de Oliveira params->threshold = 1; 5552b622eddSDaniel Bristot de Oliveira 5562b622eddSDaniel Bristot de Oliveira /* set trace */ 5572b622eddSDaniel Bristot de Oliveira params->trace_output = "osnoise_trace.txt"; 5582b622eddSDaniel Bristot de Oliveira 5592b622eddSDaniel Bristot de Oliveira break; 560829a6c0bSDaniel Bristot de Oliveira case 'b': 561829a6c0bSDaniel Bristot de Oliveira params->bucket_size = get_llong_from_str(optarg); 562829a6c0bSDaniel Bristot de Oliveira if ((params->bucket_size == 0) || (params->bucket_size >= 1000000)) 563829a6c0bSDaniel Bristot de Oliveira osnoise_hist_usage("Bucket size needs to be > 0 and <= 1000000\n"); 564829a6c0bSDaniel Bristot de Oliveira break; 565829a6c0bSDaniel Bristot de Oliveira case 'c': 566894c29c7SDaniel Bristot de Oliveira retval = parse_cpu_set(optarg, ¶ms->monitored_cpus); 567829a6c0bSDaniel Bristot de Oliveira if (retval) 568829a6c0bSDaniel Bristot de Oliveira osnoise_hist_usage("\nInvalid -c cpu list\n"); 569829a6c0bSDaniel Bristot de Oliveira params->cpus = optarg; 570829a6c0bSDaniel Bristot de Oliveira break; 571a957cbc0SDaniel Bristot de Oliveira case 'C': 572a957cbc0SDaniel Bristot de Oliveira params->cgroup = 1; 573a957cbc0SDaniel Bristot de Oliveira if (!optarg) { 574a957cbc0SDaniel Bristot de Oliveira /* will inherit this cgroup */ 575a957cbc0SDaniel Bristot de Oliveira params->cgroup_name = NULL; 576a957cbc0SDaniel Bristot de Oliveira } else if (*optarg == '=') { 577a957cbc0SDaniel Bristot de Oliveira /* skip the = */ 578a957cbc0SDaniel Bristot de Oliveira params->cgroup_name = ++optarg; 579a957cbc0SDaniel Bristot de Oliveira } 580a957cbc0SDaniel Bristot de Oliveira break; 581829a6c0bSDaniel Bristot de Oliveira case 'D': 582829a6c0bSDaniel Bristot de Oliveira config_debug = 1; 583829a6c0bSDaniel Bristot de Oliveira break; 584829a6c0bSDaniel Bristot de Oliveira case 'd': 585829a6c0bSDaniel Bristot de Oliveira params->duration = parse_seconds_duration(optarg); 586829a6c0bSDaniel Bristot de Oliveira if (!params->duration) 587829a6c0bSDaniel Bristot de Oliveira osnoise_hist_usage("Invalid -D duration\n"); 588829a6c0bSDaniel Bristot de Oliveira break; 58951d64c3aSDaniel Bristot de Oliveira case 'e': 59051d64c3aSDaniel Bristot de Oliveira tevent = trace_event_alloc(optarg); 59151d64c3aSDaniel Bristot de Oliveira if (!tevent) { 59251d64c3aSDaniel Bristot de Oliveira err_msg("Error alloc trace event"); 59351d64c3aSDaniel Bristot de Oliveira exit(EXIT_FAILURE); 59451d64c3aSDaniel Bristot de Oliveira } 59551d64c3aSDaniel Bristot de Oliveira 59651d64c3aSDaniel Bristot de Oliveira if (params->events) 59751d64c3aSDaniel Bristot de Oliveira tevent->next = params->events; 59851d64c3aSDaniel Bristot de Oliveira 59951d64c3aSDaniel Bristot de Oliveira params->events = tevent; 60051d64c3aSDaniel Bristot de Oliveira break; 601dd48f316SDaniel Bristot de Oliveira case 'E': 602829a6c0bSDaniel Bristot de Oliveira params->entries = get_llong_from_str(optarg); 603829a6c0bSDaniel Bristot de Oliveira if ((params->entries < 10) || (params->entries > 9999999)) 604829a6c0bSDaniel Bristot de Oliveira osnoise_hist_usage("Entries must be > 10 and < 9999999\n"); 605829a6c0bSDaniel Bristot de Oliveira break; 606829a6c0bSDaniel Bristot de Oliveira case 'h': 607829a6c0bSDaniel Bristot de Oliveira case '?': 608829a6c0bSDaniel Bristot de Oliveira osnoise_hist_usage(NULL); 609829a6c0bSDaniel Bristot de Oliveira break; 610272ced25SDaniel Bristot de Oliveira case 'H': 611272ced25SDaniel Bristot de Oliveira params->hk_cpus = 1; 612272ced25SDaniel Bristot de Oliveira retval = parse_cpu_set(optarg, ¶ms->hk_cpu_set); 613272ced25SDaniel Bristot de Oliveira if (retval) { 614272ced25SDaniel Bristot de Oliveira err_msg("Error parsing house keeping CPUs\n"); 615272ced25SDaniel Bristot de Oliveira exit(EXIT_FAILURE); 616272ced25SDaniel Bristot de Oliveira } 617272ced25SDaniel Bristot de Oliveira break; 618829a6c0bSDaniel Bristot de Oliveira case 'p': 619829a6c0bSDaniel Bristot de Oliveira params->period = get_llong_from_str(optarg); 620829a6c0bSDaniel Bristot de Oliveira if (params->period > 10000000) 621829a6c0bSDaniel Bristot de Oliveira osnoise_hist_usage("Period longer than 10 s\n"); 622829a6c0bSDaniel Bristot de Oliveira break; 623829a6c0bSDaniel Bristot de Oliveira case 'P': 624829a6c0bSDaniel Bristot de Oliveira retval = parse_prio(optarg, ¶ms->sched_param); 625829a6c0bSDaniel Bristot de Oliveira if (retval == -1) 626829a6c0bSDaniel Bristot de Oliveira osnoise_hist_usage("Invalid -P priority"); 627829a6c0bSDaniel Bristot de Oliveira params->set_sched = 1; 628829a6c0bSDaniel Bristot de Oliveira break; 629829a6c0bSDaniel Bristot de Oliveira case 'r': 630829a6c0bSDaniel Bristot de Oliveira params->runtime = get_llong_from_str(optarg); 631829a6c0bSDaniel Bristot de Oliveira if (params->runtime < 100) 632829a6c0bSDaniel Bristot de Oliveira osnoise_hist_usage("Runtime shorter than 100 us\n"); 633829a6c0bSDaniel Bristot de Oliveira break; 634829a6c0bSDaniel Bristot de Oliveira case 's': 635829a6c0bSDaniel Bristot de Oliveira params->stop_us = get_llong_from_str(optarg); 636829a6c0bSDaniel Bristot de Oliveira break; 637829a6c0bSDaniel Bristot de Oliveira case 'S': 638829a6c0bSDaniel Bristot de Oliveira params->stop_total_us = get_llong_from_str(optarg); 639829a6c0bSDaniel Bristot de Oliveira break; 640d635316aSDaniel Bristot de Oliveira case 'T': 641d635316aSDaniel Bristot de Oliveira params->threshold = get_llong_from_str(optarg); 642d635316aSDaniel Bristot de Oliveira break; 643829a6c0bSDaniel Bristot de Oliveira case 't': 644829a6c0bSDaniel Bristot de Oliveira if (optarg) 645829a6c0bSDaniel Bristot de Oliveira /* skip = */ 646829a6c0bSDaniel Bristot de Oliveira params->trace_output = &optarg[1]; 647829a6c0bSDaniel Bristot de Oliveira else 648829a6c0bSDaniel Bristot de Oliveira params->trace_output = "osnoise_trace.txt"; 649829a6c0bSDaniel Bristot de Oliveira break; 650829a6c0bSDaniel Bristot de Oliveira case '0': /* no header */ 651829a6c0bSDaniel Bristot de Oliveira params->no_header = 1; 652829a6c0bSDaniel Bristot de Oliveira break; 653829a6c0bSDaniel Bristot de Oliveira case '1': /* no summary */ 654829a6c0bSDaniel Bristot de Oliveira params->no_summary = 1; 655829a6c0bSDaniel Bristot de Oliveira break; 656829a6c0bSDaniel Bristot de Oliveira case '2': /* no index */ 657829a6c0bSDaniel Bristot de Oliveira params->no_index = 1; 658829a6c0bSDaniel Bristot de Oliveira break; 659829a6c0bSDaniel Bristot de Oliveira case '3': /* with zeros */ 660829a6c0bSDaniel Bristot de Oliveira params->with_zeros = 1; 661829a6c0bSDaniel Bristot de Oliveira break; 6621a754893SDaniel Bristot de Oliveira case '4': /* trigger */ 6631a754893SDaniel Bristot de Oliveira if (params->events) { 6641a754893SDaniel Bristot de Oliveira retval = trace_event_add_trigger(params->events, optarg); 6651a754893SDaniel Bristot de Oliveira if (retval) { 6661a754893SDaniel Bristot de Oliveira err_msg("Error adding trigger %s\n", optarg); 6671a754893SDaniel Bristot de Oliveira exit(EXIT_FAILURE); 6681a754893SDaniel Bristot de Oliveira } 6691a754893SDaniel Bristot de Oliveira } else { 6701a754893SDaniel Bristot de Oliveira osnoise_hist_usage("--trigger requires a previous -e\n"); 6711a754893SDaniel Bristot de Oliveira } 6721a754893SDaniel Bristot de Oliveira break; 67344f3a37dSDaniel Bristot de Oliveira case '5': /* filter */ 67444f3a37dSDaniel Bristot de Oliveira if (params->events) { 67544f3a37dSDaniel Bristot de Oliveira retval = trace_event_add_filter(params->events, optarg); 67644f3a37dSDaniel Bristot de Oliveira if (retval) { 67744f3a37dSDaniel Bristot de Oliveira err_msg("Error adding filter %s\n", optarg); 67844f3a37dSDaniel Bristot de Oliveira exit(EXIT_FAILURE); 67944f3a37dSDaniel Bristot de Oliveira } 68044f3a37dSDaniel Bristot de Oliveira } else { 68144f3a37dSDaniel Bristot de Oliveira osnoise_hist_usage("--filter requires a previous -e\n"); 68244f3a37dSDaniel Bristot de Oliveira } 68344f3a37dSDaniel Bristot de Oliveira break; 684829a6c0bSDaniel Bristot de Oliveira default: 685829a6c0bSDaniel Bristot de Oliveira osnoise_hist_usage("Invalid option"); 686829a6c0bSDaniel Bristot de Oliveira } 687829a6c0bSDaniel Bristot de Oliveira } 688829a6c0bSDaniel Bristot de Oliveira 689829a6c0bSDaniel Bristot de Oliveira if (geteuid()) { 690829a6c0bSDaniel Bristot de Oliveira err_msg("rtla needs root permission\n"); 691829a6c0bSDaniel Bristot de Oliveira exit(EXIT_FAILURE); 692829a6c0bSDaniel Bristot de Oliveira } 693829a6c0bSDaniel Bristot de Oliveira 694829a6c0bSDaniel Bristot de Oliveira if (params->no_index && !params->with_zeros) 695829a6c0bSDaniel Bristot de Oliveira osnoise_hist_usage("no-index set and with-zeros not set - it does not make sense"); 696829a6c0bSDaniel Bristot de Oliveira 697829a6c0bSDaniel Bristot de Oliveira return params; 698829a6c0bSDaniel Bristot de Oliveira } 699829a6c0bSDaniel Bristot de Oliveira 700829a6c0bSDaniel Bristot de Oliveira /* 701829a6c0bSDaniel Bristot de Oliveira * osnoise_hist_apply_config - apply the hist configs to the initialized tool 702829a6c0bSDaniel Bristot de Oliveira */ 703829a6c0bSDaniel Bristot de Oliveira static int 704829a6c0bSDaniel Bristot de Oliveira osnoise_hist_apply_config(struct osnoise_tool *tool, struct osnoise_hist_params *params) 705829a6c0bSDaniel Bristot de Oliveira { 706829a6c0bSDaniel Bristot de Oliveira int retval; 707829a6c0bSDaniel Bristot de Oliveira 708829a6c0bSDaniel Bristot de Oliveira if (!params->sleep_time) 709829a6c0bSDaniel Bristot de Oliveira params->sleep_time = 1; 710829a6c0bSDaniel Bristot de Oliveira 711829a6c0bSDaniel Bristot de Oliveira if (params->cpus) { 712829a6c0bSDaniel Bristot de Oliveira retval = osnoise_set_cpus(tool->context, params->cpus); 713829a6c0bSDaniel Bristot de Oliveira if (retval) { 714829a6c0bSDaniel Bristot de Oliveira err_msg("Failed to apply CPUs config\n"); 715829a6c0bSDaniel Bristot de Oliveira goto out_err; 716829a6c0bSDaniel Bristot de Oliveira } 717829a6c0bSDaniel Bristot de Oliveira } 718829a6c0bSDaniel Bristot de Oliveira 719829a6c0bSDaniel Bristot de Oliveira if (params->runtime || params->period) { 720829a6c0bSDaniel Bristot de Oliveira retval = osnoise_set_runtime_period(tool->context, 721829a6c0bSDaniel Bristot de Oliveira params->runtime, 722829a6c0bSDaniel Bristot de Oliveira params->period); 723829a6c0bSDaniel Bristot de Oliveira if (retval) { 724829a6c0bSDaniel Bristot de Oliveira err_msg("Failed to set runtime and/or period\n"); 725829a6c0bSDaniel Bristot de Oliveira goto out_err; 726829a6c0bSDaniel Bristot de Oliveira } 727829a6c0bSDaniel Bristot de Oliveira } 728829a6c0bSDaniel Bristot de Oliveira 729829a6c0bSDaniel Bristot de Oliveira if (params->stop_us) { 730829a6c0bSDaniel Bristot de Oliveira retval = osnoise_set_stop_us(tool->context, params->stop_us); 731829a6c0bSDaniel Bristot de Oliveira if (retval) { 732829a6c0bSDaniel Bristot de Oliveira err_msg("Failed to set stop us\n"); 733829a6c0bSDaniel Bristot de Oliveira goto out_err; 734829a6c0bSDaniel Bristot de Oliveira } 735829a6c0bSDaniel Bristot de Oliveira } 736829a6c0bSDaniel Bristot de Oliveira 737829a6c0bSDaniel Bristot de Oliveira if (params->stop_total_us) { 738829a6c0bSDaniel Bristot de Oliveira retval = osnoise_set_stop_total_us(tool->context, params->stop_total_us); 739829a6c0bSDaniel Bristot de Oliveira if (retval) { 740829a6c0bSDaniel Bristot de Oliveira err_msg("Failed to set stop total us\n"); 741829a6c0bSDaniel Bristot de Oliveira goto out_err; 742829a6c0bSDaniel Bristot de Oliveira } 743829a6c0bSDaniel Bristot de Oliveira } 744829a6c0bSDaniel Bristot de Oliveira 745d635316aSDaniel Bristot de Oliveira if (params->threshold) { 746d635316aSDaniel Bristot de Oliveira retval = osnoise_set_tracing_thresh(tool->context, params->threshold); 747d635316aSDaniel Bristot de Oliveira if (retval) { 748d635316aSDaniel Bristot de Oliveira err_msg("Failed to set tracing_thresh\n"); 749d635316aSDaniel Bristot de Oliveira goto out_err; 750d635316aSDaniel Bristot de Oliveira } 751d635316aSDaniel Bristot de Oliveira } 752d635316aSDaniel Bristot de Oliveira 753272ced25SDaniel Bristot de Oliveira if (params->hk_cpus) { 754272ced25SDaniel Bristot de Oliveira retval = sched_setaffinity(getpid(), sizeof(params->hk_cpu_set), 755272ced25SDaniel Bristot de Oliveira ¶ms->hk_cpu_set); 756272ced25SDaniel Bristot de Oliveira if (retval == -1) { 757272ced25SDaniel Bristot de Oliveira err_msg("Failed to set rtla to the house keeping CPUs\n"); 758272ced25SDaniel Bristot de Oliveira goto out_err; 759272ced25SDaniel Bristot de Oliveira } 760c58a3f8cSDaniel Bristot de Oliveira } else if (params->cpus) { 761c58a3f8cSDaniel Bristot de Oliveira /* 762c58a3f8cSDaniel Bristot de Oliveira * Even if the user do not set a house-keeping CPU, try to 763c58a3f8cSDaniel Bristot de Oliveira * move rtla to a CPU set different to the one where the user 764c58a3f8cSDaniel Bristot de Oliveira * set the workload to run. 765c58a3f8cSDaniel Bristot de Oliveira * 766c58a3f8cSDaniel Bristot de Oliveira * No need to check results as this is an automatic attempt. 767c58a3f8cSDaniel Bristot de Oliveira */ 768c58a3f8cSDaniel Bristot de Oliveira auto_house_keeping(¶ms->monitored_cpus); 769272ced25SDaniel Bristot de Oliveira } 770272ced25SDaniel Bristot de Oliveira 771829a6c0bSDaniel Bristot de Oliveira return 0; 772829a6c0bSDaniel Bristot de Oliveira 773829a6c0bSDaniel Bristot de Oliveira out_err: 774829a6c0bSDaniel Bristot de Oliveira return -1; 775829a6c0bSDaniel Bristot de Oliveira } 776829a6c0bSDaniel Bristot de Oliveira 777829a6c0bSDaniel Bristot de Oliveira /* 778829a6c0bSDaniel Bristot de Oliveira * osnoise_init_hist - initialize a osnoise hist tool with parameters 779829a6c0bSDaniel Bristot de Oliveira */ 780829a6c0bSDaniel Bristot de Oliveira static struct osnoise_tool 781829a6c0bSDaniel Bristot de Oliveira *osnoise_init_hist(struct osnoise_hist_params *params) 782829a6c0bSDaniel Bristot de Oliveira { 783829a6c0bSDaniel Bristot de Oliveira struct osnoise_tool *tool; 784829a6c0bSDaniel Bristot de Oliveira int nr_cpus; 785829a6c0bSDaniel Bristot de Oliveira 786829a6c0bSDaniel Bristot de Oliveira nr_cpus = sysconf(_SC_NPROCESSORS_CONF); 787829a6c0bSDaniel Bristot de Oliveira 788829a6c0bSDaniel Bristot de Oliveira tool = osnoise_init_tool("osnoise_hist"); 789829a6c0bSDaniel Bristot de Oliveira if (!tool) 790829a6c0bSDaniel Bristot de Oliveira return NULL; 791829a6c0bSDaniel Bristot de Oliveira 792829a6c0bSDaniel Bristot de Oliveira tool->data = osnoise_alloc_histogram(nr_cpus, params->entries, params->bucket_size); 793829a6c0bSDaniel Bristot de Oliveira if (!tool->data) 794829a6c0bSDaniel Bristot de Oliveira goto out_err; 795829a6c0bSDaniel Bristot de Oliveira 796829a6c0bSDaniel Bristot de Oliveira tool->params = params; 797829a6c0bSDaniel Bristot de Oliveira 798829a6c0bSDaniel Bristot de Oliveira return tool; 799829a6c0bSDaniel Bristot de Oliveira 800829a6c0bSDaniel Bristot de Oliveira out_err: 801829a6c0bSDaniel Bristot de Oliveira osnoise_destroy_tool(tool); 802829a6c0bSDaniel Bristot de Oliveira return NULL; 803829a6c0bSDaniel Bristot de Oliveira } 804829a6c0bSDaniel Bristot de Oliveira 805829a6c0bSDaniel Bristot de Oliveira static int stop_tracing; 806829a6c0bSDaniel Bristot de Oliveira static void stop_hist(int sig) 807829a6c0bSDaniel Bristot de Oliveira { 808829a6c0bSDaniel Bristot de Oliveira stop_tracing = 1; 809829a6c0bSDaniel Bristot de Oliveira } 810829a6c0bSDaniel Bristot de Oliveira 811829a6c0bSDaniel Bristot de Oliveira /* 812829a6c0bSDaniel Bristot de Oliveira * osnoise_hist_set_signals - handles the signal to stop the tool 813829a6c0bSDaniel Bristot de Oliveira */ 814829a6c0bSDaniel Bristot de Oliveira static void 815829a6c0bSDaniel Bristot de Oliveira osnoise_hist_set_signals(struct osnoise_hist_params *params) 816829a6c0bSDaniel Bristot de Oliveira { 817829a6c0bSDaniel Bristot de Oliveira signal(SIGINT, stop_hist); 818829a6c0bSDaniel Bristot de Oliveira if (params->duration) { 819829a6c0bSDaniel Bristot de Oliveira signal(SIGALRM, stop_hist); 820829a6c0bSDaniel Bristot de Oliveira alarm(params->duration); 821829a6c0bSDaniel Bristot de Oliveira } 822829a6c0bSDaniel Bristot de Oliveira } 823829a6c0bSDaniel Bristot de Oliveira 824829a6c0bSDaniel Bristot de Oliveira int osnoise_hist_main(int argc, char *argv[]) 825829a6c0bSDaniel Bristot de Oliveira { 826829a6c0bSDaniel Bristot de Oliveira struct osnoise_hist_params *params; 8274bbf59a9SDaniel Bristot de Oliveira struct osnoise_tool *record = NULL; 8284bbf59a9SDaniel Bristot de Oliveira struct osnoise_tool *tool = NULL; 829829a6c0bSDaniel Bristot de Oliveira struct trace_instance *trace; 830829a6c0bSDaniel Bristot de Oliveira int return_value = 1; 831829a6c0bSDaniel Bristot de Oliveira int retval; 832829a6c0bSDaniel Bristot de Oliveira 833829a6c0bSDaniel Bristot de Oliveira params = osnoise_hist_parse_args(argc, argv); 834829a6c0bSDaniel Bristot de Oliveira if (!params) 835829a6c0bSDaniel Bristot de Oliveira exit(1); 836829a6c0bSDaniel Bristot de Oliveira 837829a6c0bSDaniel Bristot de Oliveira tool = osnoise_init_hist(params); 838829a6c0bSDaniel Bristot de Oliveira if (!tool) { 839829a6c0bSDaniel Bristot de Oliveira err_msg("Could not init osnoise hist\n"); 840829a6c0bSDaniel Bristot de Oliveira goto out_exit; 841829a6c0bSDaniel Bristot de Oliveira } 842829a6c0bSDaniel Bristot de Oliveira 843829a6c0bSDaniel Bristot de Oliveira retval = osnoise_hist_apply_config(tool, params); 844829a6c0bSDaniel Bristot de Oliveira if (retval) { 845829a6c0bSDaniel Bristot de Oliveira err_msg("Could not apply config\n"); 846829a6c0bSDaniel Bristot de Oliveira goto out_destroy; 847829a6c0bSDaniel Bristot de Oliveira } 848829a6c0bSDaniel Bristot de Oliveira 849829a6c0bSDaniel Bristot de Oliveira trace = &tool->trace; 850829a6c0bSDaniel Bristot de Oliveira 851829a6c0bSDaniel Bristot de Oliveira retval = enable_osnoise(trace); 852829a6c0bSDaniel Bristot de Oliveira if (retval) { 853829a6c0bSDaniel Bristot de Oliveira err_msg("Failed to enable osnoise tracer\n"); 854829a6c0bSDaniel Bristot de Oliveira goto out_destroy; 855829a6c0bSDaniel Bristot de Oliveira } 856829a6c0bSDaniel Bristot de Oliveira 857829a6c0bSDaniel Bristot de Oliveira retval = osnoise_init_trace_hist(tool); 858829a6c0bSDaniel Bristot de Oliveira if (retval) 859829a6c0bSDaniel Bristot de Oliveira goto out_destroy; 860829a6c0bSDaniel Bristot de Oliveira 861829a6c0bSDaniel Bristot de Oliveira if (params->set_sched) { 862829a6c0bSDaniel Bristot de Oliveira retval = set_comm_sched_attr("osnoise/", ¶ms->sched_param); 863829a6c0bSDaniel Bristot de Oliveira if (retval) { 864829a6c0bSDaniel Bristot de Oliveira err_msg("Failed to set sched parameters\n"); 8652a6b52edSWan Jiabing goto out_free; 866829a6c0bSDaniel Bristot de Oliveira } 867829a6c0bSDaniel Bristot de Oliveira } 868829a6c0bSDaniel Bristot de Oliveira 869a957cbc0SDaniel Bristot de Oliveira if (params->cgroup) { 870a957cbc0SDaniel Bristot de Oliveira retval = set_comm_cgroup("timerlat/", params->cgroup_name); 871a957cbc0SDaniel Bristot de Oliveira if (!retval) { 872a957cbc0SDaniel Bristot de Oliveira err_msg("Failed to move threads to cgroup\n"); 873a957cbc0SDaniel Bristot de Oliveira goto out_free; 874a957cbc0SDaniel Bristot de Oliveira } 875a957cbc0SDaniel Bristot de Oliveira } 876a957cbc0SDaniel Bristot de Oliveira 877829a6c0bSDaniel Bristot de Oliveira if (params->trace_output) { 878829a6c0bSDaniel Bristot de Oliveira record = osnoise_init_trace_tool("osnoise"); 879829a6c0bSDaniel Bristot de Oliveira if (!record) { 880829a6c0bSDaniel Bristot de Oliveira err_msg("Failed to enable the trace instance\n"); 8812a6b52edSWan Jiabing goto out_free; 882829a6c0bSDaniel Bristot de Oliveira } 88351d64c3aSDaniel Bristot de Oliveira 88451d64c3aSDaniel Bristot de Oliveira if (params->events) { 88551d64c3aSDaniel Bristot de Oliveira retval = trace_events_enable(&record->trace, params->events); 88651d64c3aSDaniel Bristot de Oliveira if (retval) 88751d64c3aSDaniel Bristot de Oliveira goto out_hist; 88851d64c3aSDaniel Bristot de Oliveira } 88951d64c3aSDaniel Bristot de Oliveira 890829a6c0bSDaniel Bristot de Oliveira } 891829a6c0bSDaniel Bristot de Oliveira 89257cf76ecSDaniel Bristot de Oliveira /* 89357cf76ecSDaniel Bristot de Oliveira * Start the tracer here, after having set all instances. 89457cf76ecSDaniel Bristot de Oliveira * 89557cf76ecSDaniel Bristot de Oliveira * Let the trace instance start first for the case of hitting a stop 89657cf76ecSDaniel Bristot de Oliveira * tracing while enabling other instances. The trace instance is the 89757cf76ecSDaniel Bristot de Oliveira * one with most valuable information. 89857cf76ecSDaniel Bristot de Oliveira */ 89957cf76ecSDaniel Bristot de Oliveira if (params->trace_output) 90057cf76ecSDaniel Bristot de Oliveira trace_instance_start(&record->trace); 90157cf76ecSDaniel Bristot de Oliveira trace_instance_start(trace); 90257cf76ecSDaniel Bristot de Oliveira 903829a6c0bSDaniel Bristot de Oliveira tool->start_time = time(NULL); 904829a6c0bSDaniel Bristot de Oliveira osnoise_hist_set_signals(params); 905829a6c0bSDaniel Bristot de Oliveira 906829a6c0bSDaniel Bristot de Oliveira while (!stop_tracing) { 907829a6c0bSDaniel Bristot de Oliveira sleep(params->sleep_time); 908829a6c0bSDaniel Bristot de Oliveira 909829a6c0bSDaniel Bristot de Oliveira retval = tracefs_iterate_raw_events(trace->tep, 910829a6c0bSDaniel Bristot de Oliveira trace->inst, 911829a6c0bSDaniel Bristot de Oliveira NULL, 912829a6c0bSDaniel Bristot de Oliveira 0, 913829a6c0bSDaniel Bristot de Oliveira collect_registered_events, 914829a6c0bSDaniel Bristot de Oliveira trace); 915829a6c0bSDaniel Bristot de Oliveira if (retval < 0) { 916829a6c0bSDaniel Bristot de Oliveira err_msg("Error iterating on events\n"); 917829a6c0bSDaniel Bristot de Oliveira goto out_hist; 918829a6c0bSDaniel Bristot de Oliveira } 919829a6c0bSDaniel Bristot de Oliveira 92028d2160cSDaniel Bristot de Oliveira if (trace_is_off(&tool->trace, &record->trace)) 921829a6c0bSDaniel Bristot de Oliveira break; 92275016ca3SDaniel Bristot de Oliveira } 923829a6c0bSDaniel Bristot de Oliveira 924829a6c0bSDaniel Bristot de Oliveira osnoise_read_trace_hist(tool); 925829a6c0bSDaniel Bristot de Oliveira 926829a6c0bSDaniel Bristot de Oliveira osnoise_print_stats(params, tool); 927829a6c0bSDaniel Bristot de Oliveira 928829a6c0bSDaniel Bristot de Oliveira return_value = 0; 929829a6c0bSDaniel Bristot de Oliveira 93028d2160cSDaniel Bristot de Oliveira if (trace_is_off(&tool->trace, &record->trace)) { 9317d38c351SDaniel Bristot de Oliveira printf("rtla osnoise hit stop tracing\n"); 932829a6c0bSDaniel Bristot de Oliveira if (params->trace_output) { 933829a6c0bSDaniel Bristot de Oliveira printf(" Saving trace to %s\n", params->trace_output); 934829a6c0bSDaniel Bristot de Oliveira save_trace_to_file(record->trace.inst, params->trace_output); 935829a6c0bSDaniel Bristot de Oliveira } 936829a6c0bSDaniel Bristot de Oliveira } 937829a6c0bSDaniel Bristot de Oliveira 938829a6c0bSDaniel Bristot de Oliveira out_hist: 93951d64c3aSDaniel Bristot de Oliveira trace_events_destroy(&record->trace, params->events); 94051d64c3aSDaniel Bristot de Oliveira params->events = NULL; 9412a6b52edSWan Jiabing out_free: 942829a6c0bSDaniel Bristot de Oliveira osnoise_free_histogram(tool->data); 943829a6c0bSDaniel Bristot de Oliveira out_destroy: 944829a6c0bSDaniel Bristot de Oliveira osnoise_destroy_tool(record); 9454bbf59a9SDaniel Bristot de Oliveira osnoise_destroy_tool(tool); 946829a6c0bSDaniel Bristot de Oliveira free(params); 947829a6c0bSDaniel Bristot de Oliveira out_exit: 948829a6c0bSDaniel Bristot de Oliveira exit(return_value); 949829a6c0bSDaniel Bristot de Oliveira } 950