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