if (params->pretty_output)
trace_seq_printf(s, "\033[0;0;0m");
trace_seq_printf(s, "\n");
trace_seq_printf(s, "duration: %9s | time is in us\n", duration);
if (params->pretty_output)
trace_seq_printf(s, "\033[2;30;47m");
trace_seq_printf(s, "CPU Period Runtime ");
trace_seq_printf(s, " Noise ");
trace_seq_printf(s, " %% CPU Aval ");
trace_seq_printf(s, " Max Noise Max Single ");
trace_seq_printf(s, " HW NMI");
if (params->mode == MODE_HWNOISE) goto eol;
trace_seq_printf(s, " IRQ Softirq Thread");
eol: if (params->pretty_output)
trace_seq_printf(s, "\033[0;0;0m");
trace_seq_printf(s, "\n");
}
/* * clear_terminal - clears the output terminal
*/ staticvoid clear_terminal(struct trace_seq *seq)
{ if (!config_debug)
trace_seq_printf(seq, "\033c");
}
/* * osnoise_top_print - prints the output of a given CPU
*/ staticvoid osnoise_top_print(struct osnoise_tool *tool, int cpu)
{ struct osnoise_params *params = tool->params; struct trace_seq *s = tool->trace.seq; struct osnoise_top_cpu *cpu_data; struct osnoise_top_data *data; int percentage; int decimal;
data = tool->data;
cpu_data = &data->cpu_data[cpu];
/* * osnoise_top_usage - prints osnoise top usage message
*/ staticvoid osnoise_top_usage(struct osnoise_params *params, char *usage)
{ int i;
staticconstchar * const msg[] = { " [-h] [-q] [-D] [-d s] [-a us] [-p us] [-r us] [-s us] [-S us] \\", " [-T us] [-t[file]] [-e sys[:event]] [--filter ] [--trigger ] \\", " [-c cpu-list] [-H cpu-list] [-P priority] [-C[=cgroup_name]] [--warm-up s]", "", " -h/--help: print this menu", " -a/--auto: set automatic trace mode, stopping the session if argument in us sample is hit", " -p/--period us: osnoise period in us", " -r/--runtime us: osnoise runtime in us", " -s/--stop us: stop trace if a single sample is higher than the argument in us", " -S/--stop-total us: stop trace if the total sample is higher than the argument in us", " -T/--threshold us: the minimum delta to be considered a noise", " -c/--cpus cpu-list: list of cpus to run osnoise threads", " -H/--house-keeping cpus: run rtla control threads only on the given cpus", " -C/--cgroup[=cgroup_name]: set cgroup, if no cgroup_name is passed, the rtla's cgroup will be inherited", " -d/--duration time[s|m|h|d]: duration of the session", " -D/--debug: print debug info", " -t/--trace[file]: save the stopped trace to [file|osnoise_trace.txt]", " -e/--event : enable the in the trace instance, multiple -e are allowed", " --filter : enable a trace event filter to the previous -e event", " --trigger : enable a trace event trigger to the previous -e event", " -q/--quiet print only a summary at the end", " -P/--priority o:prio|r:prio|f:prio|d:runtime:period : set scheduling parameters", " o:prio - use SCHED_OTHER with prio", " r:prio - use SCHED_RR with prio", " f:prio - use SCHED_FIFO with prio", " d:runtime[us|ms|s]:period[us|ms|s] - use SCHED_DEADLINE with runtime and period", " in nanoseconds", " --warm-up s: let the workload run for s seconds before collecting data", " --trace-buffer-size kB: set the per-cpu trace buffer size in kB",
NULL,
};
if (usage)
fprintf(stderr, "%s\n", usage);
if (params->mode == MODE_OSNOISE) {
fprintf(stderr, "rtla osnoise top: a per-cpu summary of the OS noise (version %s)\n",
VERSION);
fprintf(stderr, " usage: rtla osnoise [top]");
}
if (params->mode == MODE_HWNOISE) {
fprintf(stderr, "rtla hwnoise: a summary of hardware-related noise (version %s)\n",
VERSION);
fprintf(stderr, " usage: rtla hwnoise");
}
for (i = 0; msg[i]; i++)
fprintf(stderr, "%s\n", msg[i]);
if (usage) exit(EXIT_FAILURE);
exit(EXIT_SUCCESS);
}
/* * osnoise_top_parse_args - allocs, parse and fill the cmd line parameters
*/ struct osnoise_params *osnoise_top_parse_args(int argc, char **argv)
{ struct osnoise_params *params; struct trace_events *tevent; int retval; int c;
params = calloc(1, sizeof(*params)); if (!params) exit(1);
if (strcmp(argv[0], "hwnoise") == 0) {
params->mode = MODE_HWNOISE; /* * Reduce CPU usage for 75% to avoid killing the system.
*/
params->runtime = 750000;
params->period = 1000000;
}
if (geteuid()) {
err_msg("osnoise needs root permission\n"); exit(EXIT_FAILURE);
}
return params;
}
/* * osnoise_top_apply_config - apply the top configs to the initialized tool
*/ staticint
osnoise_top_apply_config(struct osnoise_tool *tool, struct osnoise_params *params)
{ int retval;
retval = osnoise_apply_config(tool, params); if (retval) goto out_err;
if (params->mode == MODE_HWNOISE) {
retval = osnoise_set_irq_disable(tool->context, 1); if (retval) {
err_msg("Failed to set OSNOISE_IRQ_DISABLE option\n"); goto out_err;
}
}
if (isatty(STDOUT_FILENO) && !params->quiet)
params->pretty_output = 1;
return 0;
out_err: return -1;
}
/* * osnoise_init_top - initialize a osnoise top tool with parameters
*/ struct osnoise_tool *osnoise_init_top(struct osnoise_params *params)
{ struct osnoise_tool *tool; int nr_cpus;
nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
tool = osnoise_init_tool("osnoise_top"); if (!tool) return NULL;
tool->data = osnoise_alloc_top(nr_cpus); if (!tool->data) {
osnoise_destroy_tool(tool); return NULL;
}
/* * osnoise_top_set_signals - handles the signal to stop the tool
*/ staticvoid osnoise_top_set_signals(struct osnoise_params *params)
{
signal(SIGINT, stop_top); if (params->duration) {
signal(SIGALRM, stop_top);
alarm(params->duration);
}
}
int osnoise_top_main(int argc, char **argv)
{ 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_top_parse_args(argc, argv); if (!params) exit(1);
tool = osnoise_init_top(params); if (!tool) {
err_msg("Could not init osnoise top\n"); goto out_exit;
}
retval = osnoise_top_apply_config(tool, params); if (retval) {
err_msg("Could not apply config\n"); goto out_free;
}
trace = &tool->trace;
retval = enable_osnoise(trace); if (retval) {
err_msg("Failed to enable osnoise tracer\n"); goto out_free;
}
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("osnoise/", params->cgroup_name); if (!retval) {
err_msg("Failed to move threads to cgroup\n"); goto out_free;
}
}
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_top;
}
if (params->buffer_size > 0) {
retval = trace_set_buffer_size(&record->trace, params->buffer_size); if (retval) goto out_top;
}
}
/* * 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_top;
/* * 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_top;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.