diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-06-11 13:08:07 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-06-19 12:06:20 -0400 |
commit | 0b668bc9a74ce1bd3b8c5fd93e8d85ed955e11fe (patch) | |
tree | 771dbfc4676c223d19c27127f1ad8518e3b9a8b0 /tools/perf/util/evsel.c | |
parent | 27f18617b01dbbc928e9bd3731d1766222fb7e0d (diff) |
perf tools: Reconstruct hw cache event with modifiers from perf_event_attr
[root@sandy ~]# perf record -a -e dTLB-load-misses:u usleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.486 MB perf.data (~21216 samples) ]
Before:
[root@sandy ~]# perf evlist
dTLB-load-misses
[root@sandy ~]#
After:
[root@sandy ~]# perf evlist
dTLB-load-misses:u
[root@sandy ~]#
Ditto for other tools.
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-7x1b0e6jthkr93lfjzsuakk5@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/evsel.c')
-rw-r--r-- | tools/perf/util/evsel.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index dab893804a1..47f1fe2feab 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -128,6 +128,105 @@ static int perf_evsel__hw_name(struct perf_evsel *evsel, char *bf, size_t size) | |||
128 | return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); | 128 | return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); |
129 | } | 129 | } |
130 | 130 | ||
131 | const char *perf_evsel__hw_cache[PERF_COUNT_HW_CACHE_MAX] | ||
132 | [PERF_EVSEL__MAX_ALIASES] = { | ||
133 | { "L1-dcache", "l1-d", "l1d", "L1-data", }, | ||
134 | { "L1-icache", "l1-i", "l1i", "L1-instruction", }, | ||
135 | { "LLC", "L2", }, | ||
136 | { "dTLB", "d-tlb", "Data-TLB", }, | ||
137 | { "iTLB", "i-tlb", "Instruction-TLB", }, | ||
138 | { "branch", "branches", "bpu", "btb", "bpc", }, | ||
139 | { "node", }, | ||
140 | }; | ||
141 | |||
142 | const char *perf_evsel__hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX] | ||
143 | [PERF_EVSEL__MAX_ALIASES] = { | ||
144 | { "load", "loads", "read", }, | ||
145 | { "store", "stores", "write", }, | ||
146 | { "prefetch", "prefetches", "speculative-read", "speculative-load", }, | ||
147 | }; | ||
148 | |||
149 | const char *perf_evsel__hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX] | ||
150 | [PERF_EVSEL__MAX_ALIASES] = { | ||
151 | { "refs", "Reference", "ops", "access", }, | ||
152 | { "misses", "miss", }, | ||
153 | }; | ||
154 | |||
155 | #define C(x) PERF_COUNT_HW_CACHE_##x | ||
156 | #define CACHE_READ (1 << C(OP_READ)) | ||
157 | #define CACHE_WRITE (1 << C(OP_WRITE)) | ||
158 | #define CACHE_PREFETCH (1 << C(OP_PREFETCH)) | ||
159 | #define COP(x) (1 << x) | ||
160 | |||
161 | /* | ||
162 | * cache operartion stat | ||
163 | * L1I : Read and prefetch only | ||
164 | * ITLB and BPU : Read-only | ||
165 | */ | ||
166 | static unsigned long perf_evsel__hw_cache_stat[C(MAX)] = { | ||
167 | [C(L1D)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), | ||
168 | [C(L1I)] = (CACHE_READ | CACHE_PREFETCH), | ||
169 | [C(LL)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), | ||
170 | [C(DTLB)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), | ||
171 | [C(ITLB)] = (CACHE_READ), | ||
172 | [C(BPU)] = (CACHE_READ), | ||
173 | [C(NODE)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), | ||
174 | }; | ||
175 | |||
176 | bool perf_evsel__is_cache_op_valid(u8 type, u8 op) | ||
177 | { | ||
178 | if (perf_evsel__hw_cache_stat[type] & COP(op)) | ||
179 | return true; /* valid */ | ||
180 | else | ||
181 | return false; /* invalid */ | ||
182 | } | ||
183 | |||
184 | int __perf_evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result, | ||
185 | char *bf, size_t size) | ||
186 | { | ||
187 | if (result) { | ||
188 | return scnprintf(bf, size, "%s-%s-%s", perf_evsel__hw_cache[type][0], | ||
189 | perf_evsel__hw_cache_op[op][0], | ||
190 | perf_evsel__hw_cache_result[result][0]); | ||
191 | } | ||
192 | |||
193 | return scnprintf(bf, size, "%s-%s", perf_evsel__hw_cache[type][0], | ||
194 | perf_evsel__hw_cache_op[op][1]); | ||
195 | } | ||
196 | |||
197 | int __perf_evsel__hw_cache_name(u64 config, char *bf, size_t size) | ||
198 | { | ||
199 | u8 op, result, type = (config >> 0) & 0xff; | ||
200 | const char *err = "unknown-ext-hardware-cache-type"; | ||
201 | |||
202 | if (type > PERF_COUNT_HW_CACHE_MAX) | ||
203 | goto out_err; | ||
204 | |||
205 | op = (config >> 8) & 0xff; | ||
206 | err = "unknown-ext-hardware-cache-op"; | ||
207 | if (op > PERF_COUNT_HW_CACHE_OP_MAX) | ||
208 | goto out_err; | ||
209 | |||
210 | result = (config >> 16) & 0xff; | ||
211 | err = "unknown-ext-hardware-cache-result"; | ||
212 | if (result > PERF_COUNT_HW_CACHE_RESULT_MAX) | ||
213 | goto out_err; | ||
214 | |||
215 | err = "invalid-cache"; | ||
216 | if (!perf_evsel__is_cache_op_valid(type, op)) | ||
217 | goto out_err; | ||
218 | |||
219 | return __perf_evsel__hw_cache_type_op_res_name(type, op, result, bf, size); | ||
220 | out_err: | ||
221 | return scnprintf(bf, size, "%s", err); | ||
222 | } | ||
223 | |||
224 | static int perf_evsel__hw_cache_name(struct perf_evsel *evsel, char *bf, size_t size) | ||
225 | { | ||
226 | int ret = __perf_evsel__hw_cache_name(evsel->attr.config, bf, size); | ||
227 | return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret); | ||
228 | } | ||
229 | |||
131 | int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size) | 230 | int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size) |
132 | { | 231 | { |
133 | int ret; | 232 | int ret; |
@@ -140,6 +239,11 @@ int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size) | |||
140 | case PERF_TYPE_HARDWARE: | 239 | case PERF_TYPE_HARDWARE: |
141 | ret = perf_evsel__hw_name(evsel, bf, size); | 240 | ret = perf_evsel__hw_name(evsel, bf, size); |
142 | break; | 241 | break; |
242 | |||
243 | case PERF_TYPE_HW_CACHE: | ||
244 | ret = perf_evsel__hw_cache_name(evsel, bf, size); | ||
245 | break; | ||
246 | |||
143 | default: | 247 | default: |
144 | /* | 248 | /* |
145 | * FIXME | 249 | * FIXME |