| Author | Tokens | Token Proportion | Commits | Commit Proportion |
|---|---|---|---|---|
| Daniel Bristot de Oliveira | 1232 | 89.86% | 9 | 42.86% |
| Crystal Wood | 86 | 6.27% | 2 | 9.52% |
| Luis Claudio R. Goncalves | 27 | 1.97% | 1 | 4.76% |
| Tomas Glozar | 12 | 0.88% | 4 | 19.05% |
| Costa Shulyupin | 12 | 0.88% | 3 | 14.29% |
| Eder Zulian | 1 | 0.07% | 1 | 4.76% |
| Dan Carpenter | 1 | 0.07% | 1 | 4.76% |
| Total | 1371 | 21 |
// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2021 Red Hat Inc, Daniel Bristot de Oliveira <bristot@kernel.org> */ #define _GNU_SOURCE #include <stdlib.h> #include <string.h> #include <signal.h> #include <unistd.h> #include <stdio.h> #include <time.h> #include "osnoise.h" #include "cli.h" struct osnoise_top_cpu { unsigned long long sum_runtime; unsigned long long sum_noise; unsigned long long max_noise; unsigned long long max_sample; unsigned long long hw_count; unsigned long long nmi_count; unsigned long long irq_count; unsigned long long softirq_count; unsigned long long thread_count; int sum_cycles; }; struct osnoise_top_data { struct osnoise_top_cpu *cpu_data; }; /* * osnoise_free_top - free runtime data */ static void osnoise_free_top(struct osnoise_top_data *data) { free(data->cpu_data); free(data); } static void osnoise_free_top_tool(struct osnoise_tool *tool) { osnoise_free_top(tool->data); } /* * osnoise_alloc_histogram - alloc runtime data */ static struct osnoise_top_data *osnoise_alloc_top(void) { struct osnoise_top_data *data; data = calloc(1, sizeof(*data)); if (!data) return NULL; /* one set of histograms per CPU */ data->cpu_data = calloc(1, sizeof(*data->cpu_data) * nr_cpus); if (!data->cpu_data) goto cleanup; return data; cleanup: osnoise_free_top(data); return NULL; } /* * osnoise_top_handler - this is the handler for osnoise tracer events */ static int osnoise_top_handler(struct trace_seq *s, struct tep_record *record, struct tep_event *event, void *context) { struct trace_instance *trace = context; struct osnoise_tool *tool; unsigned long long val; struct osnoise_top_cpu *cpu_data; struct osnoise_top_data *data; int cpu = record->cpu; tool = container_of(trace, struct osnoise_tool, trace); data = tool->data; cpu_data = &data->cpu_data[cpu]; cpu_data->sum_cycles++; tep_get_field_val(s, event, "runtime", record, &val, 1); update_sum(&cpu_data->sum_runtime, &val); tep_get_field_val(s, event, "noise", record, &val, 1); update_max(&cpu_data->max_noise, &val); update_sum(&cpu_data->sum_noise, &val); tep_get_field_val(s, event, "max_sample", record, &val, 1); update_max(&cpu_data->max_sample, &val); tep_get_field_val(s, event, "hw_count", record, &val, 1); update_sum(&cpu_data->hw_count, &val); tep_get_field_val(s, event, "nmi_count", record, &val, 1); update_sum(&cpu_data->nmi_count, &val); tep_get_field_val(s, event, "irq_count", record, &val, 1); update_sum(&cpu_data->irq_count, &val); tep_get_field_val(s, event, "softirq_count", record, &val, 1); update_sum(&cpu_data->softirq_count, &val); tep_get_field_val(s, event, "thread_count", record, &val, 1); update_sum(&cpu_data->thread_count, &val); return 0; } /* * osnoise_top_header - print the header of the tool output */ static void osnoise_top_header(struct osnoise_tool *top) { struct osnoise_params *params = to_osnoise_params(top->params); struct trace_seq *s = top->trace.seq; bool pretty = params->common.pretty_output; char duration[26]; get_duration(top->start_time, duration, sizeof(duration)); if (pretty) trace_seq_printf(s, "\033[2;37;40m"); trace_seq_printf(s, " "); if (params->mode == MODE_OSNOISE) { trace_seq_printf(s, "Operating System Noise"); trace_seq_printf(s, " "); } else if (params->mode == MODE_HWNOISE) { trace_seq_printf(s, "Hardware-related Noise"); } trace_seq_printf(s, " "); if (pretty) 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 (pretty) 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 (pretty) trace_seq_printf(s, "\033[0;0;0m"); trace_seq_printf(s, "\n"); } /* * clear_terminal - clears the output terminal */ static void clear_terminal(struct trace_seq *seq) { if (!config_debug) trace_seq_printf(seq, "\033c"); } /* * osnoise_top_print - prints the output of a given CPU */ static void osnoise_top_print(struct osnoise_tool *tool, int cpu) { struct osnoise_params *params = to_osnoise_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]; if (!cpu_data->sum_runtime) return; percentage = ((cpu_data->sum_runtime - cpu_data->sum_noise) * 10000000) / cpu_data->sum_runtime; decimal = percentage % 100000; percentage = percentage / 100000; trace_seq_printf(s, "%3d #%-6d %12llu ", cpu, cpu_data->sum_cycles, cpu_data->sum_runtime); trace_seq_printf(s, "%12llu ", cpu_data->sum_noise); trace_seq_printf(s, " %3d.%05d", percentage, decimal); trace_seq_printf(s, "%12llu %12llu", cpu_data->max_noise, cpu_data->max_sample); trace_seq_printf(s, "%12llu ", cpu_data->hw_count); trace_seq_printf(s, "%12llu ", cpu_data->nmi_count); if (params->mode == MODE_HWNOISE) { trace_seq_printf(s, "\n"); return; } trace_seq_printf(s, "%12llu ", cpu_data->irq_count); trace_seq_printf(s, "%12llu ", cpu_data->softirq_count); trace_seq_printf(s, "%12llu\n", cpu_data->thread_count); } /* * osnoise_print_stats - print data for all cpus */ static void osnoise_print_stats(struct osnoise_tool *top) { struct osnoise_params *params = to_osnoise_params(top->params); struct trace_instance *trace = &top->trace; int i; if (!params->common.quiet) clear_terminal(trace->seq); osnoise_top_header(top); for_each_monitored_cpu(i, ¶ms->common) { osnoise_top_print(top, i); } trace_seq_do_printf(trace->seq); trace_seq_reset(trace->seq); osnoise_report_missed_events(top); } /* * osnoise_top_apply_config - apply the top configs to the initialized tool */ static int osnoise_top_apply_config(struct osnoise_tool *tool) { struct osnoise_params *params = to_osnoise_params(tool->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->common.quiet) params->common.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 common_params *params) { struct osnoise_tool *tool; tool = osnoise_init_tool("osnoise_top"); if (!tool) return NULL; tool->data = osnoise_alloc_top(); if (!tool->data) { osnoise_destroy_tool(tool); return NULL; } tep_register_event_handler(tool->trace.tep, -1, "ftrace", "osnoise", osnoise_top_handler, NULL); return tool; } struct tool_ops osnoise_top_ops = { .tracer = "osnoise", .comm_prefix = "osnoise/", .parse_args = osnoise_top_parse_args, .init_tool = osnoise_init_top, .apply_config = osnoise_top_apply_config, .enable = osnoise_enable, .main = top_main_loop, .print_stats = osnoise_print_stats, .free = osnoise_free_top_tool, };
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with Cregit http://github.com/cregit/cregit
Version 2.0-RC1