^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Refactored from builtin-top.c, see that files for further copyright notes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "event.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "evlist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "evsel.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "parse-events.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "symbol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "top.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "../perf.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <inttypes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define SNPRINTF(buf, size, fmt, args...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) size_t r = snprintf(buf, size, fmt, ## args); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) r > size ? size : r; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) float samples_per_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) float ksamples_per_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) float esamples_percent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct record_opts *opts = &top->record_opts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct target *target = &opts->target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) size_t ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) if (top->samples) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) samples_per_sec = top->samples / top->delay_secs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) ksamples_per_sec = top->kernel_samples / top->delay_secs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) esamples_percent = (100.0 * top->exact_samples) / top->samples;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) samples_per_sec = ksamples_per_sec = esamples_percent = 0.0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (!perf_guest) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) float ksamples_percent = 0.0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (samples_per_sec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) ksamples_percent = (100.0 * ksamples_per_sec) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) samples_per_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) ret = SNPRINTF(bf, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) " PerfTop:%8.0f irqs/sec kernel:%4.1f%%"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) " exact: %4.1f%% lost: %" PRIu64 "/%" PRIu64 " drop: %" PRIu64 "/%" PRIu64 " [",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) samples_per_sec, ksamples_percent, esamples_percent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) top->lost, top->lost_total, top->drop, top->drop_total);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) float us_samples_per_sec = top->us_samples / top->delay_secs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) float guest_kernel_samples_per_sec = top->guest_kernel_samples / top->delay_secs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) float guest_us_samples_per_sec = top->guest_us_samples / top->delay_secs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) ret = SNPRINTF(bf, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) " PerfTop:%8.0f irqs/sec kernel:%4.1f%% us:%4.1f%%"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) " guest kernel:%4.1f%% guest us:%4.1f%%"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) " exact: %4.1f%% [", samples_per_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) 100.0 - (100.0 * ((samples_per_sec - ksamples_per_sec) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) samples_per_sec)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 100.0 - (100.0 * ((samples_per_sec - us_samples_per_sec) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) samples_per_sec)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) 100.0 - (100.0 * ((samples_per_sec -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) guest_kernel_samples_per_sec) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) samples_per_sec)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) 100.0 - (100.0 * ((samples_per_sec -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) guest_us_samples_per_sec) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) samples_per_sec)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) esamples_percent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (top->evlist->core.nr_entries == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct evsel *first = evlist__first(top->evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) ret += SNPRINTF(bf + ret, size - ret, "%" PRIu64 "%s ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) (uint64_t)first->core.attr.sample_period,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) opts->freq ? "Hz" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) ret += SNPRINTF(bf + ret, size - ret, "%s", evsel__name(top->sym_evsel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) ret += SNPRINTF(bf + ret, size - ret, "], ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (target->pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ret += SNPRINTF(bf + ret, size - ret, " (target_pid: %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) target->pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) else if (target->tid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) ret += SNPRINTF(bf + ret, size - ret, " (target_tid: %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) target->tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) else if (target->uid_str != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) ret += SNPRINTF(bf + ret, size - ret, " (uid: %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) target->uid_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) ret += SNPRINTF(bf + ret, size - ret, " (all");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (target->cpu_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) ret += SNPRINTF(bf + ret, size - ret, ", CPU%s: %s)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) top->evlist->core.cpus->nr > 1 ? "s" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) target->cpu_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (target->tid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) ret += SNPRINTF(bf + ret, size - ret, ")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) ret += SNPRINTF(bf + ret, size - ret, ", %d CPU%s)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) top->evlist->core.cpus->nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) top->evlist->core.cpus->nr > 1 ? "s" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) perf_top__reset_sample_counters(top);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) void perf_top__reset_sample_counters(struct perf_top *top)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) top->samples = top->us_samples = top->kernel_samples =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) top->exact_samples = top->guest_kernel_samples =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) top->guest_us_samples = top->lost = top->drop = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }