From 0f7d2f1b65e3415854bbe842705f698a3350d7da Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 24 Sep 2012 10:46:54 -0300 Subject: 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 Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-v9x3q9rv4caxtox7wtjpchq5@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-kmem.c | 90 +++++++++++++++++++++++------------------------ 1 file 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 @@ #include "builtin.h" #include "perf.h" +#include "util/evlist.h" #include "util/evsel.h" #include "util/util.h" #include "util/cache.h" @@ -212,36 +213,38 @@ static int insert_caller_stat(unsigned long call_site, } static int perf_evsel__process_alloc_event(struct perf_evsel *evsel, - struct perf_sample *sample, int node) + struct perf_sample *sample) { - struct event_format *event = evsel->tp_format; - void *data = sample->raw_data; - unsigned long call_site; - unsigned long ptr; - int bytes_req, cpu = sample->cpu; - int bytes_alloc; - int node1, node2; - - ptr = raw_field_value(event, "ptr", data); - call_site = raw_field_value(event, "call_site", data); - bytes_req = raw_field_value(event, "bytes_req", data); - bytes_alloc = raw_field_value(event, "bytes_alloc", data); - - if (insert_alloc_stat(call_site, ptr, bytes_req, bytes_alloc, cpu) || + unsigned long ptr = perf_evsel__intval(evsel, sample, "ptr"), + call_site = perf_evsel__intval(evsel, sample, "call_site"); + int bytes_req = perf_evsel__intval(evsel, sample, "bytes_req"), + bytes_alloc = perf_evsel__intval(evsel, sample, "bytes_alloc"); + + if (insert_alloc_stat(call_site, ptr, bytes_req, bytes_alloc, sample->cpu) || insert_caller_stat(call_site, bytes_req, bytes_alloc)) return -1; total_requested += bytes_req; total_allocated += bytes_alloc; - if (node) { - node1 = cpunode_map[cpu]; - node2 = raw_field_value(event, "node", data); + nr_allocs++; + return 0; +} + +static int perf_evsel__process_alloc_node_event(struct perf_evsel *evsel, + struct perf_sample *sample) +{ + int ret = perf_evsel__process_alloc_event(evsel, sample); + + if (!ret) { + int node1 = cpunode_map[sample->cpu], + node2 = perf_evsel__intval(evsel, sample, "node"); + if (node1 != node2) nr_cross_allocs++; } - nr_allocs++; - return 0; + + return ret; } static int ptr_cmp(struct alloc_stat *, struct alloc_stat *); @@ -275,8 +278,7 @@ static struct alloc_stat *search_alloc_stat(unsigned long ptr, static int perf_evsel__process_free_event(struct perf_evsel *evsel, struct perf_sample *sample) { - unsigned long ptr = raw_field_value(evsel->tp_format, "ptr", - sample->raw_data); + unsigned long ptr = perf_evsel__intval(evsel, sample, "ptr"); struct alloc_stat *s_alloc, *s_caller; 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, return 0; } -static int perf_evsel__process_kmem_event(struct perf_evsel *evsel, - struct perf_sample *sample) -{ - struct event_format *event = evsel->tp_format; - - if (!strcmp(event->name, "kmalloc") || - !strcmp(event->name, "kmem_cache_alloc")) { - return perf_evsel__process_alloc_event(evsel, sample, 0); - } - - if (!strcmp(event->name, "kmalloc_node") || - !strcmp(event->name, "kmem_cache_alloc_node")) { - return perf_evsel__process_alloc_event(evsel, sample, 1); - } - - if (!strcmp(event->name, "kfree") || - !strcmp(event->name, "kmem_cache_free")) { - return perf_evsel__process_free_event(evsel, sample); - } - - return 0; -} +typedef int (*tracepoint_handler)(struct perf_evsel *evsel, + struct perf_sample *sample); static int process_sample_event(struct perf_tool *tool __maybe_unused, union perf_event *event, @@ -336,7 +318,12 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused, dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); - return perf_evsel__process_kmem_event(evsel, sample); + if (evsel->handler.func != NULL) { + tracepoint_handler f = evsel->handler.func; + return f(evsel, sample); + } + + return 0; } static struct perf_tool perf_kmem = { @@ -498,6 +485,14 @@ static int __cmd_kmem(void) { int err = -EINVAL; struct perf_session *session; + const struct perf_evsel_str_handler kmem_tracepoints[] = { + { "kmem:kmalloc", perf_evsel__process_alloc_event, }, + { "kmem:kmem_cache_alloc", perf_evsel__process_alloc_event, }, + { "kmem:kmalloc_node", perf_evsel__process_alloc_node_event, }, + { "kmem:kmem_cache_alloc_node", perf_evsel__process_alloc_node_event, }, + { "kmem:kfree", perf_evsel__process_free_event, }, + { "kmem:kmem_cache_free", perf_evsel__process_free_event, }, + }; session = perf_session__new(input_name, O_RDONLY, 0, false, &perf_kmem); if (session == NULL) @@ -509,6 +504,11 @@ static int __cmd_kmem(void) if (!perf_session__has_traces(session, "kmem record")) goto out_delete; + if (perf_session__set_tracepoints_handlers(session, kmem_tracepoints)) { + pr_err("Initializing perf session tracepoint handlers failed\n"); + return -1; + } + setup_pager(); err = perf_session__process_events(session, &perf_kmem); if (err != 0) -- cgit v1.2.3-55-g7522