.. | .. |
---|
3 | 3 | #include "util/kvm-stat.h" |
---|
4 | 4 | #include "util/parse-events.h" |
---|
5 | 5 | #include "util/debug.h" |
---|
| 6 | +#include "util/evsel.h" |
---|
| 7 | +#include "util/evlist.h" |
---|
| 8 | +#include "util/pmu.h" |
---|
6 | 9 | |
---|
7 | 10 | #include "book3s_hv_exits.h" |
---|
8 | 11 | #include "book3s_hcalls.h" |
---|
| 12 | +#include <subcmd/parse-options.h> |
---|
9 | 13 | |
---|
10 | 14 | #define NR_TPS 4 |
---|
11 | 15 | |
---|
.. | .. |
---|
30 | 34 | const char *kvm_events_tp[NR_TPS + 1]; |
---|
31 | 35 | const char *kvm_exit_reason; |
---|
32 | 36 | |
---|
33 | | -static void hcall_event_get_key(struct perf_evsel *evsel, |
---|
| 37 | +static void hcall_event_get_key(struct evsel *evsel, |
---|
34 | 38 | struct perf_sample *sample, |
---|
35 | 39 | struct event_key *key) |
---|
36 | 40 | { |
---|
37 | 41 | key->info = 0; |
---|
38 | | - key->key = perf_evsel__intval(evsel, sample, "req"); |
---|
| 42 | + key->key = evsel__intval(evsel, sample, "req"); |
---|
39 | 43 | } |
---|
40 | 44 | |
---|
41 | 45 | static const char *get_hcall_exit_reason(u64 exit_code) |
---|
.. | .. |
---|
53 | 57 | return "UNKNOWN"; |
---|
54 | 58 | } |
---|
55 | 59 | |
---|
56 | | -static bool hcall_event_end(struct perf_evsel *evsel, |
---|
| 60 | +static bool hcall_event_end(struct evsel *evsel, |
---|
57 | 61 | struct perf_sample *sample __maybe_unused, |
---|
58 | 62 | struct event_key *key __maybe_unused) |
---|
59 | 63 | { |
---|
60 | 64 | return (!strcmp(evsel->name, kvm_events_tp[3])); |
---|
61 | 65 | } |
---|
62 | 66 | |
---|
63 | | -static bool hcall_event_begin(struct perf_evsel *evsel, |
---|
| 67 | +static bool hcall_event_begin(struct evsel *evsel, |
---|
64 | 68 | struct perf_sample *sample, struct event_key *key) |
---|
65 | 69 | { |
---|
66 | 70 | if (!strcmp(evsel->name, kvm_events_tp[2])) { |
---|
.. | .. |
---|
104 | 108 | }; |
---|
105 | 109 | |
---|
106 | 110 | |
---|
107 | | -static int is_tracepoint_available(const char *str, struct perf_evlist *evlist) |
---|
| 111 | +static int is_tracepoint_available(const char *str, struct evlist *evlist) |
---|
108 | 112 | { |
---|
109 | 113 | struct parse_events_error err; |
---|
110 | 114 | int ret; |
---|
111 | 115 | |
---|
112 | | - err.str = NULL; |
---|
| 116 | + bzero(&err, sizeof(err)); |
---|
113 | 117 | ret = parse_events(evlist, str, &err); |
---|
114 | 118 | if (err.str) |
---|
115 | | - pr_err("%s : %s\n", str, err.str); |
---|
| 119 | + parse_events_print_error(&err, "tracepoint"); |
---|
116 | 120 | return ret; |
---|
117 | 121 | } |
---|
118 | 122 | |
---|
119 | 123 | static int ppc__setup_book3s_hv(struct perf_kvm_stat *kvm, |
---|
120 | | - struct perf_evlist *evlist) |
---|
| 124 | + struct evlist *evlist) |
---|
121 | 125 | { |
---|
122 | 126 | const char **events_ptr; |
---|
123 | 127 | int i, nr_tp = 0, err = -1; |
---|
.. | .. |
---|
144 | 148 | /* Wrapper to setup kvm tracepoints */ |
---|
145 | 149 | static int ppc__setup_kvm_tp(struct perf_kvm_stat *kvm) |
---|
146 | 150 | { |
---|
147 | | - struct perf_evlist *evlist = perf_evlist__new(); |
---|
| 151 | + struct evlist *evlist = evlist__new(); |
---|
148 | 152 | |
---|
149 | 153 | if (evlist == NULL) |
---|
150 | 154 | return -ENOMEM; |
---|
.. | .. |
---|
170 | 174 | |
---|
171 | 175 | return ret; |
---|
172 | 176 | } |
---|
| 177 | + |
---|
| 178 | +/* |
---|
| 179 | + * Incase of powerpc architecture, pmu registers are programmable |
---|
| 180 | + * by guest kernel. So monitoring guest via host may not provide |
---|
| 181 | + * valid samples with default 'cycles' event. It is better to use |
---|
| 182 | + * 'trace_imc/trace_cycles' event for guest profiling, since it |
---|
| 183 | + * can track the guest instruction pointer in the trace-record. |
---|
| 184 | + * |
---|
| 185 | + * Function to parse the arguments and return appropriate values. |
---|
| 186 | + */ |
---|
| 187 | +int kvm_add_default_arch_event(int *argc, const char **argv) |
---|
| 188 | +{ |
---|
| 189 | + const char **tmp; |
---|
| 190 | + bool event = false; |
---|
| 191 | + int i, j = *argc; |
---|
| 192 | + |
---|
| 193 | + const struct option event_options[] = { |
---|
| 194 | + OPT_BOOLEAN('e', "event", &event, NULL), |
---|
| 195 | + OPT_END() |
---|
| 196 | + }; |
---|
| 197 | + |
---|
| 198 | + tmp = calloc(j + 1, sizeof(char *)); |
---|
| 199 | + if (!tmp) |
---|
| 200 | + return -EINVAL; |
---|
| 201 | + |
---|
| 202 | + for (i = 0; i < j; i++) |
---|
| 203 | + tmp[i] = argv[i]; |
---|
| 204 | + |
---|
| 205 | + parse_options(j, tmp, event_options, NULL, PARSE_OPT_KEEP_UNKNOWN); |
---|
| 206 | + if (!event) { |
---|
| 207 | + if (pmu_have_event("trace_imc", "trace_cycles")) { |
---|
| 208 | + argv[j++] = strdup("-e"); |
---|
| 209 | + argv[j++] = strdup("trace_imc/trace_cycles/"); |
---|
| 210 | + *argc += 2; |
---|
| 211 | + } else { |
---|
| 212 | + free(tmp); |
---|
| 213 | + return -EINVAL; |
---|
| 214 | + } |
---|
| 215 | + } |
---|
| 216 | + |
---|
| 217 | + free(tmp); |
---|
| 218 | + return 0; |
---|
| 219 | +} |
---|