diff options
Diffstat (limited to 'tools/tracing/rtla/src/osnoise_hist.c')
-rw-r--r-- | tools/tracing/rtla/src/osnoise_hist.c | 369 |
1 files changed, 129 insertions, 240 deletions
diff --git a/tools/tracing/rtla/src/osnoise_hist.c b/tools/tracing/rtla/src/osnoise_hist.c index 8d579bcee709..dffb6d0a98d7 100644 --- a/tools/tracing/rtla/src/osnoise_hist.c +++ b/tools/tracing/rtla/src/osnoise_hist.c @@ -54,6 +54,11 @@ osnoise_free_histogram(struct osnoise_hist_data *data) free(data); } +static void osnoise_free_hist_tool(struct osnoise_tool *tool) +{ + osnoise_free_histogram(tool->data); +} + /* * osnoise_alloc_histogram - alloc runtime data */ @@ -95,15 +100,15 @@ cleanup: static void osnoise_hist_update_multiple(struct osnoise_tool *tool, int cpu, unsigned long long duration, int count) { - struct osnoise_params *params = tool->params; + struct osnoise_params *params = to_osnoise_params(tool->params); struct osnoise_hist_data *data = tool->data; unsigned long long total_duration; int entries = data->entries; int bucket; int *hist; - if (params->output_divisor) - duration = duration / params->output_divisor; + if (params->common.output_divisor) + duration = duration / params->common.output_divisor; bucket = duration / data->bucket_size; @@ -137,7 +142,7 @@ static void osnoise_destroy_trace_hist(struct osnoise_tool *tool) */ static int osnoise_init_trace_hist(struct osnoise_tool *tool) { - struct osnoise_params *params = tool->params; + struct osnoise_params *params = to_osnoise_params(tool->params); struct osnoise_hist_data *data = tool->data; int bucket_size; char buff[128]; @@ -146,7 +151,7 @@ static int osnoise_init_trace_hist(struct osnoise_tool *tool) /* * Set the size of the bucket. */ - bucket_size = params->output_divisor * params->bucket_size; + bucket_size = params->common.output_divisor * params->common.hist.bucket_size; snprintf(buff, sizeof(buff), "duration.buckets=%d", bucket_size); data->trace_hist = tracefs_hist_alloc(tool->trace.tep, "osnoise", "sample_threshold", @@ -222,28 +227,28 @@ static void osnoise_read_trace_hist(struct osnoise_tool *tool) */ static void osnoise_hist_header(struct osnoise_tool *tool) { - struct osnoise_params *params = tool->params; + struct osnoise_params *params = to_osnoise_params(tool->params); struct osnoise_hist_data *data = tool->data; struct trace_seq *s = tool->trace.seq; char duration[26]; int cpu; - if (params->no_header) + if (params->common.hist.no_header) return; get_duration(tool->start_time, duration, sizeof(duration)); trace_seq_printf(s, "# RTLA osnoise histogram\n"); trace_seq_printf(s, "# Time unit is %s (%s)\n", - params->output_divisor == 1 ? "nanoseconds" : "microseconds", - params->output_divisor == 1 ? "ns" : "us"); + params->common.output_divisor == 1 ? "nanoseconds" : "microseconds", + params->common.output_divisor == 1 ? "ns" : "us"); trace_seq_printf(s, "# Duration: %s\n", duration); - if (!params->no_index) + if (!params->common.hist.no_index) trace_seq_printf(s, "Index"); for (cpu = 0; cpu < data->nr_cpus; cpu++) { - if (params->cpus && !CPU_ISSET(cpu, ¶ms->monitored_cpus)) + if (params->common.cpus && !CPU_ISSET(cpu, ¶ms->common.monitored_cpus)) continue; if (!data->hist[cpu].count) @@ -267,14 +272,14 @@ osnoise_print_summary(struct osnoise_params *params, { int cpu; - if (params->no_summary) + if (params->common.hist.no_summary) return; - if (!params->no_index) + if (!params->common.hist.no_index) trace_seq_printf(trace->seq, "count:"); for (cpu = 0; cpu < data->nr_cpus; cpu++) { - if (params->cpus && !CPU_ISSET(cpu, ¶ms->monitored_cpus)) + if (params->common.cpus && !CPU_ISSET(cpu, ¶ms->common.monitored_cpus)) continue; if (!data->hist[cpu].count) @@ -284,11 +289,11 @@ osnoise_print_summary(struct osnoise_params *params, } trace_seq_printf(trace->seq, "\n"); - if (!params->no_index) + if (!params->common.hist.no_index) trace_seq_printf(trace->seq, "min: "); for (cpu = 0; cpu < data->nr_cpus; cpu++) { - if (params->cpus && !CPU_ISSET(cpu, ¶ms->monitored_cpus)) + if (params->common.cpus && !CPU_ISSET(cpu, ¶ms->common.monitored_cpus)) continue; if (!data->hist[cpu].count) @@ -299,11 +304,11 @@ osnoise_print_summary(struct osnoise_params *params, } trace_seq_printf(trace->seq, "\n"); - if (!params->no_index) + if (!params->common.hist.no_index) trace_seq_printf(trace->seq, "avg: "); for (cpu = 0; cpu < data->nr_cpus; cpu++) { - if (params->cpus && !CPU_ISSET(cpu, ¶ms->monitored_cpus)) + if (params->common.cpus && !CPU_ISSET(cpu, ¶ms->common.monitored_cpus)) continue; if (!data->hist[cpu].count) @@ -317,11 +322,11 @@ osnoise_print_summary(struct osnoise_params *params, } trace_seq_printf(trace->seq, "\n"); - if (!params->no_index) + if (!params->common.hist.no_index) trace_seq_printf(trace->seq, "max: "); for (cpu = 0; cpu < data->nr_cpus; cpu++) { - if (params->cpus && !CPU_ISSET(cpu, ¶ms->monitored_cpus)) + if (params->common.cpus && !CPU_ISSET(cpu, ¶ms->common.monitored_cpus)) continue; if (!data->hist[cpu].count) @@ -339,8 +344,9 @@ osnoise_print_summary(struct osnoise_params *params, * osnoise_print_stats - print data for all CPUs */ static void -osnoise_print_stats(struct osnoise_params *params, struct osnoise_tool *tool) +osnoise_print_stats(struct osnoise_tool *tool) { + struct osnoise_params *params = to_osnoise_params(tool->params); struct osnoise_hist_data *data = tool->data; struct trace_instance *trace = &tool->trace; int has_samples = 0; @@ -352,12 +358,12 @@ osnoise_print_stats(struct osnoise_params *params, struct osnoise_tool *tool) for (bucket = 0; bucket < data->entries; bucket++) { total = 0; - if (!params->no_index) + if (!params->common.hist.no_index) trace_seq_printf(trace->seq, "%-6d", bucket * data->bucket_size); for (cpu = 0; cpu < data->nr_cpus; cpu++) { - if (params->cpus && !CPU_ISSET(cpu, ¶ms->monitored_cpus)) + if (params->common.cpus && !CPU_ISSET(cpu, ¶ms->common.monitored_cpus)) continue; if (!data->hist[cpu].count) @@ -367,7 +373,7 @@ osnoise_print_stats(struct osnoise_params *params, struct osnoise_tool *tool) trace_seq_printf(trace->seq, "%9d ", data->hist[cpu].samples[bucket]); } - if (total == 0 && !params->with_zeros) { + if (total == 0 && !params->common.hist.with_zeros) { trace_seq_reset(trace->seq); continue; } @@ -391,11 +397,11 @@ osnoise_print_stats(struct osnoise_params *params, struct osnoise_tool *tool) return; } - if (!params->no_index) + if (!params->common.hist.no_index) trace_seq_printf(trace->seq, "over: "); for (cpu = 0; cpu < data->nr_cpus; cpu++) { - if (params->cpus && !CPU_ISSET(cpu, ¶ms->monitored_cpus)) + if (params->common.cpus && !CPU_ISSET(cpu, ¶ms->common.monitored_cpus)) continue; if (!data->hist[cpu].count) @@ -456,6 +462,8 @@ static void osnoise_hist_usage(char *usage) " in nanoseconds", " --warm-up: let the workload run for s seconds before collecting data", " --trace-buffer-size kB: set the per-cpu trace buffer size in kB", + " --on-threshold <action>: define action to be executed at stop-total threshold, multiple are allowed", + " --on-end <action>: define action to be executed at measurement end, multiple are allowed", NULL, }; @@ -477,22 +485,26 @@ static void osnoise_hist_usage(char *usage) /* * osnoise_hist_parse_args - allocs, parse and fill the cmd line parameters */ -static struct osnoise_params +static struct common_params *osnoise_hist_parse_args(int argc, char *argv[]) { struct osnoise_params *params; struct trace_events *tevent; int retval; int c; + char *trace_output = NULL; params = calloc(1, sizeof(*params)); if (!params) exit(1); + actions_init(¶ms->common.threshold_actions); + actions_init(¶ms->common.end_actions); + /* display data in microseconds */ - params->output_divisor = 1000; - params->bucket_size = 1; - params->entries = 256; + params->common.output_divisor = 1000; + params->common.hist.bucket_size = 1; + params->common.hist.entries = 256; while (1) { static struct option long_options[] = { @@ -521,6 +533,8 @@ static struct osnoise_params {"filter", required_argument, 0, '5'}, {"warm-up", required_argument, 0, '6'}, {"trace-buffer-size", required_argument, 0, '7'}, + {"on-threshold", required_argument, 0, '8'}, + {"on-end", required_argument, 0, '9'}, {0, 0, 0, 0} }; @@ -537,42 +551,43 @@ static struct osnoise_params switch (c) { case 'a': /* set sample stop to auto_thresh */ - params->stop_us = get_llong_from_str(optarg); + params->common.stop_us = get_llong_from_str(optarg); /* set sample threshold to 1 */ params->threshold = 1; /* set trace */ - params->trace_output = "osnoise_trace.txt"; + trace_output = "osnoise_trace.txt"; break; case 'b': - params->bucket_size = get_llong_from_str(optarg); - if ((params->bucket_size == 0) || (params->bucket_size >= 1000000)) + params->common.hist.bucket_size = get_llong_from_str(optarg); + if (params->common.hist.bucket_size == 0 || + params->common.hist.bucket_size >= 1000000) osnoise_hist_usage("Bucket size needs to be > 0 and <= 1000000\n"); break; case 'c': - retval = parse_cpu_set(optarg, ¶ms->monitored_cpus); + retval = parse_cpu_set(optarg, ¶ms->common.monitored_cpus); if (retval) osnoise_hist_usage("\nInvalid -c cpu list\n"); - params->cpus = optarg; + params->common.cpus = optarg; break; case 'C': - params->cgroup = 1; + params->common.cgroup = 1; if (!optarg) { /* will inherit this cgroup */ - params->cgroup_name = NULL; + params->common.cgroup_name = NULL; } else if (*optarg == '=') { /* skip the = */ - params->cgroup_name = ++optarg; + params->common.cgroup_name = ++optarg; } break; case 'D': config_debug = 1; break; case 'd': - params->duration = parse_seconds_duration(optarg); - if (!params->duration) + params->common.duration = parse_seconds_duration(optarg); + if (!params->common.duration) osnoise_hist_usage("Invalid -D duration\n"); break; case 'e': @@ -582,14 +597,15 @@ static struct osnoise_params exit(EXIT_FAILURE); } - if (params->events) - tevent->next = params->events; + if (params->common.events) + tevent->next = params->common.events; - params->events = tevent; + params->common.events = tevent; break; case 'E': - params->entries = get_llong_from_str(optarg); - if ((params->entries < 10) || (params->entries > 9999999)) + params->common.hist.entries = get_llong_from_str(optarg); + if (params->common.hist.entries < 10 || + params->common.hist.entries > 9999999) osnoise_hist_usage("Entries must be > 10 and < 9999999\n"); break; case 'h': @@ -597,8 +613,8 @@ static struct osnoise_params osnoise_hist_usage(NULL); break; case 'H': - params->hk_cpus = 1; - retval = parse_cpu_set(optarg, ¶ms->hk_cpu_set); + params->common.hk_cpus = 1; + retval = parse_cpu_set(optarg, ¶ms->common.hk_cpu_set); if (retval) { err_msg("Error parsing house keeping CPUs\n"); exit(EXIT_FAILURE); @@ -610,10 +626,10 @@ static struct osnoise_params osnoise_hist_usage("Period longer than 10 s\n"); break; case 'P': - retval = parse_prio(optarg, ¶ms->sched_param); + retval = parse_prio(optarg, ¶ms->common.sched_param); if (retval == -1) osnoise_hist_usage("Invalid -P priority"); - params->set_sched = 1; + params->common.set_sched = 1; break; case 'r': params->runtime = get_llong_from_str(optarg); @@ -621,10 +637,10 @@ static struct osnoise_params osnoise_hist_usage("Runtime shorter than 100 us\n"); break; case 's': - params->stop_us = get_llong_from_str(optarg); + params->common.stop_us = get_llong_from_str(optarg); break; case 'S': - params->stop_total_us = get_llong_from_str(optarg); + params->common.stop_total_us = get_llong_from_str(optarg); break; case 'T': params->threshold = get_llong_from_str(optarg); @@ -632,29 +648,29 @@ static struct osnoise_params case 't': if (optarg) { if (optarg[0] == '=') - params->trace_output = &optarg[1]; + trace_output = &optarg[1]; else - params->trace_output = &optarg[0]; + trace_output = &optarg[0]; } else if (optind < argc && argv[optind][0] != '0') - params->trace_output = argv[optind]; + trace_output = argv[optind]; else - params->trace_output = "osnoise_trace.txt"; + trace_output = "osnoise_trace.txt"; break; case '0': /* no header */ - params->no_header = 1; + params->common.hist.no_header = 1; break; case '1': /* no summary */ - params->no_summary = 1; + params->common.hist.no_summary = 1; break; case '2': /* no index */ - params->no_index = 1; + params->common.hist.no_index = 1; break; case '3': /* with zeros */ - params->with_zeros = 1; + params->common.hist.with_zeros = 1; break; case '4': /* trigger */ - if (params->events) { - retval = trace_event_add_trigger(params->events, optarg); + if (params->common.events) { + retval = trace_event_add_trigger(params->common.events, optarg); if (retval) { err_msg("Error adding trigger %s\n", optarg); exit(EXIT_FAILURE); @@ -664,8 +680,8 @@ static struct osnoise_params } break; case '5': /* filter */ - if (params->events) { - retval = trace_event_add_filter(params->events, optarg); + if (params->common.events) { + retval = trace_event_add_filter(params->common.events, optarg); if (retval) { err_msg("Error adding filter %s\n", optarg); exit(EXIT_FAILURE); @@ -675,50 +691,60 @@ static struct osnoise_params } break; case '6': - params->warmup = get_llong_from_str(optarg); + params->common.warmup = get_llong_from_str(optarg); break; case '7': - params->buffer_size = get_llong_from_str(optarg); + params->common.buffer_size = get_llong_from_str(optarg); + break; + case '8': + retval = actions_parse(¶ms->common.threshold_actions, optarg, + "osnoise_trace.txt"); + if (retval) { + err_msg("Invalid action %s\n", optarg); + exit(EXIT_FAILURE); + } + break; + case '9': + retval = actions_parse(¶ms->common.end_actions, optarg, + "osnoise_trace.txt"); + if (retval) { + err_msg("Invalid action %s\n", optarg); + exit(EXIT_FAILURE); + } break; default: osnoise_hist_usage("Invalid option"); } } + if (trace_output) + actions_add_trace_output(¶ms->common.threshold_actions, trace_output); + if (geteuid()) { err_msg("rtla needs root permission\n"); exit(EXIT_FAILURE); } - if (params->no_index && !params->with_zeros) + if (params->common.hist.no_index && !params->common.hist.with_zeros) osnoise_hist_usage("no-index set and with-zeros not set - it does not make sense"); - return params; + return ¶ms->common; } /* * osnoise_hist_apply_config - apply the hist configs to the initialized tool */ static int -osnoise_hist_apply_config(struct osnoise_tool *tool, struct osnoise_params *params) +osnoise_hist_apply_config(struct osnoise_tool *tool) { - int retval; - - retval = osnoise_apply_config(tool, params); - if (retval) - goto out_err; - - return 0; - -out_err: - return -1; + return osnoise_apply_config(tool, to_osnoise_params(tool->params)); } /* * osnoise_init_hist - initialize a osnoise hist tool with parameters */ static struct osnoise_tool -*osnoise_init_hist(struct osnoise_params *params) +*osnoise_init_hist(struct common_params *params) { struct osnoise_tool *tool; int nr_cpus; @@ -729,12 +755,11 @@ static struct osnoise_tool if (!tool) return NULL; - tool->data = osnoise_alloc_histogram(nr_cpus, params->entries, params->bucket_size); + tool->data = osnoise_alloc_histogram(nr_cpus, params->hist.entries, + params->hist.bucket_size); if (!tool->data) goto out_err; - tool->params = params; - return tool; out_err: @@ -742,171 +767,35 @@ out_err: return NULL; } -static int stop_tracing; -static void stop_hist(int sig) -{ - stop_tracing = 1; -} - -/* - * osnoise_hist_set_signals - handles the signal to stop the tool - */ -static void -osnoise_hist_set_signals(struct osnoise_params *params) -{ - signal(SIGINT, stop_hist); - if (params->duration) { - signal(SIGALRM, stop_hist); - alarm(params->duration); - } -} - -int osnoise_hist_main(int argc, char *argv[]) +static int osnoise_hist_enable(struct osnoise_tool *tool) { - struct osnoise_params *params; - struct osnoise_tool *record = NULL; - struct osnoise_tool *tool = NULL; - enum result return_value = ERROR; - struct trace_instance *trace; int retval; - params = osnoise_hist_parse_args(argc, argv); - if (!params) - exit(1); - - tool = osnoise_init_hist(params); - if (!tool) { - err_msg("Could not init osnoise hist\n"); - goto out_exit; - } - - retval = osnoise_hist_apply_config(tool, params); - if (retval) { - err_msg("Could not apply config\n"); - goto out_destroy; - } - - trace = &tool->trace; - - retval = enable_osnoise(trace); - if (retval) { - err_msg("Failed to enable osnoise tracer\n"); - goto out_destroy; - } - retval = osnoise_init_trace_hist(tool); if (retval) - goto out_destroy; - - if (params->set_sched) { - retval = set_comm_sched_attr("osnoise/", ¶ms->sched_param); - if (retval) { - err_msg("Failed to set sched parameters\n"); - goto out_free; - } - } - - if (params->cgroup) { - retval = set_comm_cgroup("timerlat/", params->cgroup_name); - if (!retval) { - err_msg("Failed to move threads to cgroup\n"); - goto out_free; - } - } + return retval; - if (params->trace_output) { - record = osnoise_init_trace_tool("osnoise"); - if (!record) { - err_msg("Failed to enable the trace instance\n"); - goto out_free; - } - - if (params->events) { - retval = trace_events_enable(&record->trace, params->events); - if (retval) - goto out_hist; - } - - if (params->buffer_size > 0) { - retval = trace_set_buffer_size(&record->trace, params->buffer_size); - if (retval) - goto out_hist; - } - } - - /* - * Start the tracer here, after having set all instances. - * - * Let the trace instance start first for the case of hitting a stop - * tracing while enabling other instances. The trace instance is the - * one with most valuable information. - */ - if (params->trace_output) - trace_instance_start(&record->trace); - trace_instance_start(trace); - - if (params->warmup > 0) { - debug_msg("Warming up for %d seconds\n", params->warmup); - sleep(params->warmup); - if (stop_tracing) - goto out_hist; - - /* - * Clean up the buffer. The osnoise workload do not run - * with tracing off to avoid creating a performance penalty - * when not needed. - */ - retval = tracefs_instance_file_write(trace->inst, "trace", ""); - if (retval < 0) { - debug_msg("Error cleaning up the buffer"); - goto out_hist; - } - - } - - tool->start_time = time(NULL); - osnoise_hist_set_signals(params); - - while (!stop_tracing) { - sleep(params->sleep_time); - - retval = tracefs_iterate_raw_events(trace->tep, - trace->inst, - NULL, - 0, - collect_registered_events, - trace); - if (retval < 0) { - err_msg("Error iterating on events\n"); - goto out_hist; - } + return osnoise_enable(tool); +} - if (osnoise_trace_is_off(tool, record)) - break; - } +static int osnoise_hist_main_loop(struct osnoise_tool *tool) +{ + int retval; + retval = hist_main_loop(tool); osnoise_read_trace_hist(tool); - osnoise_print_stats(params, tool); - - return_value = PASSED; - - if (osnoise_trace_is_off(tool, record)) { - printf("rtla osnoise hit stop tracing\n"); - save_trace_to_file(record ? record->trace.inst : NULL, - params->trace_output); - return_value = FAILED; - } - -out_hist: - trace_events_destroy(&record->trace, params->events); - params->events = NULL; -out_free: - osnoise_free_histogram(tool->data); -out_destroy: - osnoise_destroy_tool(record); - osnoise_destroy_tool(tool); - free(params); -out_exit: - exit(return_value); + return retval; } + +struct tool_ops osnoise_hist_ops = { + .tracer = "osnoise", + .comm_prefix = "osnoise/", + .parse_args = osnoise_hist_parse_args, + .init_tool = osnoise_init_hist, + .apply_config = osnoise_hist_apply_config, + .enable = osnoise_hist_enable, + .main = osnoise_hist_main_loop, + .print_stats = osnoise_print_stats, + .free = osnoise_free_hist_tool, +}; |