aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-kmem.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2012-09-24 09:46:54 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2012-09-24 09:52:03 -0400
commit0f7d2f1b65e3415854bbe842705f698a3350d7da (patch)
treec8fc00abf4c00460d4c4c29259e1555c8d5de352 /tools/perf/builtin-kmem.c
parent14907e73830a256ad726a35a93789a9bc9595490 (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.c90
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
214static int perf_evsel__process_alloc_event(struct perf_evsel *evsel, 215static 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
234static 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
247static int ptr_cmp(struct alloc_stat *, struct alloc_stat *); 250static int ptr_cmp(struct alloc_stat *, struct alloc_stat *);
@@ -275,8 +278,7 @@ static struct alloc_stat *search_alloc_stat(unsigned long ptr,
275static int perf_evsel__process_free_event(struct perf_evsel *evsel, 278static 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
300static int perf_evsel__process_kmem_event(struct perf_evsel *evsel, 302typedef 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
323static int process_sample_event(struct perf_tool *tool __maybe_unused, 305static 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
342static struct perf_tool perf_kmem = { 329static 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)