diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-09-24 09:46:54 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-09-24 09:52:03 -0400 |
commit | 0f7d2f1b65e3415854bbe842705f698a3350d7da (patch) | |
tree | c8fc00abf4c00460d4c4c29259e1555c8d5de352 /tools/perf/builtin-kmem.c | |
parent | 14907e73830a256ad726a35a93789a9bc9595490 (diff) |
perf kmem: Use perf_evsel__intval and perf_session__set_tracepoints_handlers
Following the model of 'perf sched':
. raw_field_value searches first on the common fields, that are unused
in this tool
. Using perf_session__set_tracepoints_handlers will save all those
strcmp to find the right handler at sample processing time, do it just
once and get the handler from evsel->handler.func.
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-v9x3q9rv4caxtox7wtjpchq5@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/builtin-kmem.c')
-rw-r--r-- | tools/perf/builtin-kmem.c | 90 |
1 files changed, 45 insertions, 45 deletions
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index f5f8a6b745a3..bc912c68f49a 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c | |||
@@ -1,6 +1,7 @@ | |||
1 | #include "builtin.h" | 1 | #include "builtin.h" |
2 | #include "perf.h" | 2 | #include "perf.h" |
3 | 3 | ||
4 | #include "util/evlist.h" | ||
4 | #include "util/evsel.h" | 5 | #include "util/evsel.h" |
5 | #include "util/util.h" | 6 | #include "util/util.h" |
6 | #include "util/cache.h" | 7 | #include "util/cache.h" |
@@ -212,36 +213,38 @@ static int insert_caller_stat(unsigned long call_site, | |||
212 | } | 213 | } |
213 | 214 | ||
214 | static int perf_evsel__process_alloc_event(struct perf_evsel *evsel, | 215 | static int perf_evsel__process_alloc_event(struct perf_evsel *evsel, |
215 | struct perf_sample *sample, int node) | 216 | struct perf_sample *sample) |
216 | { | 217 | { |
217 | struct event_format *event = evsel->tp_format; | 218 | unsigned long ptr = perf_evsel__intval(evsel, sample, "ptr"), |
218 | void *data = sample->raw_data; | 219 | call_site = perf_evsel__intval(evsel, sample, "call_site"); |
219 | unsigned long call_site; | 220 | int bytes_req = perf_evsel__intval(evsel, sample, "bytes_req"), |
220 | unsigned long ptr; | 221 | bytes_alloc = perf_evsel__intval(evsel, sample, "bytes_alloc"); |
221 | int bytes_req, cpu = sample->cpu; | 222 | |
222 | int bytes_alloc; | 223 | if (insert_alloc_stat(call_site, ptr, bytes_req, bytes_alloc, sample->cpu) || |
223 | int node1, node2; | ||
224 | |||
225 | ptr = raw_field_value(event, "ptr", data); | ||
226 | call_site = raw_field_value(event, "call_site", data); | ||
227 | bytes_req = raw_field_value(event, "bytes_req", data); | ||
228 | bytes_alloc = raw_field_value(event, "bytes_alloc", data); | ||
229 | |||
230 | if (insert_alloc_stat(call_site, ptr, bytes_req, bytes_alloc, cpu) || | ||
231 | insert_caller_stat(call_site, bytes_req, bytes_alloc)) | 224 | insert_caller_stat(call_site, bytes_req, bytes_alloc)) |
232 | return -1; | 225 | return -1; |
233 | 226 | ||
234 | total_requested += bytes_req; | 227 | total_requested += bytes_req; |
235 | total_allocated += bytes_alloc; | 228 | total_allocated += bytes_alloc; |
236 | 229 | ||
237 | if (node) { | 230 | nr_allocs++; |
238 | node1 = cpunode_map[cpu]; | 231 | return 0; |
239 | node2 = raw_field_value(event, "node", data); | 232 | } |
233 | |||
234 | static int perf_evsel__process_alloc_node_event(struct perf_evsel *evsel, | ||
235 | struct perf_sample *sample) | ||
236 | { | ||
237 | int ret = perf_evsel__process_alloc_event(evsel, sample); | ||
238 | |||
239 | if (!ret) { | ||
240 | int node1 = cpunode_map[sample->cpu], | ||
241 | node2 = perf_evsel__intval(evsel, sample, "node"); | ||
242 | |||
240 | if (node1 != node2) | 243 | if (node1 != node2) |
241 | nr_cross_allocs++; | 244 | nr_cross_allocs++; |
242 | } | 245 | } |
243 | nr_allocs++; | 246 | |
244 | return 0; | 247 | return ret; |
245 | } | 248 | } |
246 | 249 | ||
247 | static int ptr_cmp(struct alloc_stat *, struct alloc_stat *); | 250 | static int ptr_cmp(struct alloc_stat *, struct alloc_stat *); |
@@ -275,8 +278,7 @@ static struct alloc_stat *search_alloc_stat(unsigned long ptr, | |||
275 | static int perf_evsel__process_free_event(struct perf_evsel *evsel, | 278 | static int perf_evsel__process_free_event(struct perf_evsel *evsel, |
276 | struct perf_sample *sample) | 279 | struct perf_sample *sample) |
277 | { | 280 | { |
278 | unsigned long ptr = raw_field_value(evsel->tp_format, "ptr", | 281 | unsigned long ptr = perf_evsel__intval(evsel, sample, "ptr"); |
279 | sample->raw_data); | ||
280 | struct alloc_stat *s_alloc, *s_caller; | 282 | struct alloc_stat *s_alloc, *s_caller; |
281 | 283 | ||
282 | s_alloc = search_alloc_stat(ptr, 0, &root_alloc_stat, ptr_cmp); | 284 | s_alloc = search_alloc_stat(ptr, 0, &root_alloc_stat, ptr_cmp); |
@@ -297,28 +299,8 @@ static int perf_evsel__process_free_event(struct perf_evsel *evsel, | |||
297 | return 0; | 299 | return 0; |
298 | } | 300 | } |
299 | 301 | ||
300 | static int perf_evsel__process_kmem_event(struct perf_evsel *evsel, | 302 | typedef int (*tracepoint_handler)(struct perf_evsel *evsel, |
301 | struct perf_sample *sample) | 303 | struct perf_sample *sample); |
302 | { | ||
303 | struct event_format *event = evsel->tp_format; | ||
304 | |||
305 | if (!strcmp(event->name, "kmalloc") || | ||
306 | !strcmp(event->name, "kmem_cache_alloc")) { | ||
307 | return perf_evsel__process_alloc_event(evsel, sample, 0); | ||
308 | } | ||
309 | |||
310 | if (!strcmp(event->name, "kmalloc_node") || | ||
311 | !strcmp(event->name, "kmem_cache_alloc_node")) { | ||
312 | return perf_evsel__process_alloc_event(evsel, sample, 1); | ||
313 | } | ||
314 | |||
315 | if (!strcmp(event->name, "kfree") || | ||
316 | !strcmp(event->name, "kmem_cache_free")) { | ||
317 | return perf_evsel__process_free_event(evsel, sample); | ||
318 | } | ||
319 | |||
320 | return 0; | ||
321 | } | ||
322 | 304 | ||
323 | static int process_sample_event(struct perf_tool *tool __maybe_unused, | 305 | static int process_sample_event(struct perf_tool *tool __maybe_unused, |
324 | union perf_event *event, | 306 | union perf_event *event, |
@@ -336,7 +318,12 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused, | |||
336 | 318 | ||
337 | dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); | 319 | dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); |
338 | 320 | ||
339 | return perf_evsel__process_kmem_event(evsel, sample); | 321 | if (evsel->handler.func != NULL) { |
322 | tracepoint_handler f = evsel->handler.func; | ||
323 | return f(evsel, sample); | ||
324 | } | ||
325 | |||
326 | return 0; | ||
340 | } | 327 | } |
341 | 328 | ||
342 | static struct perf_tool perf_kmem = { | 329 | static struct perf_tool perf_kmem = { |
@@ -498,6 +485,14 @@ static int __cmd_kmem(void) | |||
498 | { | 485 | { |
499 | int err = -EINVAL; | 486 | int err = -EINVAL; |
500 | struct perf_session *session; | 487 | struct perf_session *session; |
488 | const struct perf_evsel_str_handler kmem_tracepoints[] = { | ||
489 | { "kmem:kmalloc", perf_evsel__process_alloc_event, }, | ||
490 | { "kmem:kmem_cache_alloc", perf_evsel__process_alloc_event, }, | ||
491 | { "kmem:kmalloc_node", perf_evsel__process_alloc_node_event, }, | ||
492 | { "kmem:kmem_cache_alloc_node", perf_evsel__process_alloc_node_event, }, | ||
493 | { "kmem:kfree", perf_evsel__process_free_event, }, | ||
494 | { "kmem:kmem_cache_free", perf_evsel__process_free_event, }, | ||
495 | }; | ||
501 | 496 | ||
502 | session = perf_session__new(input_name, O_RDONLY, 0, false, &perf_kmem); | 497 | session = perf_session__new(input_name, O_RDONLY, 0, false, &perf_kmem); |
503 | if (session == NULL) | 498 | if (session == NULL) |
@@ -509,6 +504,11 @@ static int __cmd_kmem(void) | |||
509 | if (!perf_session__has_traces(session, "kmem record")) | 504 | if (!perf_session__has_traces(session, "kmem record")) |
510 | goto out_delete; | 505 | goto out_delete; |
511 | 506 | ||
507 | if (perf_session__set_tracepoints_handlers(session, kmem_tracepoints)) { | ||
508 | pr_err("Initializing perf session tracepoint handlers failed\n"); | ||
509 | return -1; | ||
510 | } | ||
511 | |||
512 | setup_pager(); | 512 | setup_pager(); |
513 | err = perf_session__process_events(session, &perf_kmem); | 513 | err = perf_session__process_events(session, &perf_kmem); |
514 | if (err != 0) | 514 | if (err != 0) |