diff options
author | Namhyung Kim <namhyung@kernel.org> | 2012-09-11 00:34:27 -0400 |
---|---|---|
committer | Jiri Olsa <jolsa@kernel.org> | 2014-06-01 08:34:56 -0400 |
commit | a0b51af367a6831330564c96dc4cc1ac63413701 (patch) | |
tree | dfaee76ff1dc0937725182803242899f36a51e05 | |
parent | f8be1c8c48c8469d1ce95ccdc77b1e2c6a29700e (diff) |
perf hists: Check if accumulated when adding a hist entry
To support callchain accumulation, @entry should be recognized if it's
accumulated or not when add_hist_entry() called. The period of an
accumulated entry should be added to ->stat_acc but not ->stat. Add
@sample_self arg for that.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Arun Sharma <asharma@fb.com>
Tested-by: Rodrigo Campos <rodrigo@sdfg.com.ar>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Link: http://lkml.kernel.org/r/1401335910-16832-5-git-send-email-namhyung@kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
-rw-r--r-- | tools/perf/builtin-annotate.c | 3 | ||||
-rw-r--r-- | tools/perf/builtin-diff.c | 2 | ||||
-rw-r--r-- | tools/perf/builtin-top.c | 2 | ||||
-rw-r--r-- | tools/perf/tests/hists_link.c | 4 | ||||
-rw-r--r-- | tools/perf/util/hist.c | 29 | ||||
-rw-r--r-- | tools/perf/util/hist.h | 3 |
6 files changed, 26 insertions, 17 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index bf52461a88bd..1ec429fef2be 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
@@ -65,7 +65,8 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel, | |||
65 | return 0; | 65 | return 0; |
66 | } | 66 | } |
67 | 67 | ||
68 | he = __hists__add_entry(&evsel->hists, al, NULL, NULL, NULL, 1, 1, 0); | 68 | he = __hists__add_entry(&evsel->hists, al, NULL, NULL, NULL, 1, 1, 0, |
69 | true); | ||
69 | if (he == NULL) | 70 | if (he == NULL) |
70 | return -ENOMEM; | 71 | return -ENOMEM; |
71 | 72 | ||
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 8bff543acaab..9a5a035cb426 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c | |||
@@ -315,7 +315,7 @@ static int hists__add_entry(struct hists *hists, | |||
315 | u64 weight, u64 transaction) | 315 | u64 weight, u64 transaction) |
316 | { | 316 | { |
317 | if (__hists__add_entry(hists, al, NULL, NULL, NULL, period, weight, | 317 | if (__hists__add_entry(hists, al, NULL, NULL, NULL, period, weight, |
318 | transaction) != NULL) | 318 | transaction, true) != NULL) |
319 | return 0; | 319 | return 0; |
320 | return -ENOMEM; | 320 | return -ENOMEM; |
321 | } | 321 | } |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 51309264d210..12e2e1227e47 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -247,7 +247,7 @@ static struct hist_entry *perf_evsel__add_hist_entry(struct perf_evsel *evsel, | |||
247 | pthread_mutex_lock(&evsel->hists.lock); | 247 | pthread_mutex_lock(&evsel->hists.lock); |
248 | he = __hists__add_entry(&evsel->hists, al, NULL, NULL, NULL, | 248 | he = __hists__add_entry(&evsel->hists, al, NULL, NULL, NULL, |
249 | sample->period, sample->weight, | 249 | sample->period, sample->weight, |
250 | sample->transaction); | 250 | sample->transaction, true); |
251 | pthread_mutex_unlock(&evsel->hists.lock); | 251 | pthread_mutex_unlock(&evsel->hists.lock); |
252 | if (he == NULL) | 252 | if (he == NULL) |
253 | return NULL; | 253 | return NULL; |
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index 5ffa2c3eb77d..ca6693b37cd7 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c | |||
@@ -88,7 +88,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine) | |||
88 | goto out; | 88 | goto out; |
89 | 89 | ||
90 | he = __hists__add_entry(&evsel->hists, &al, NULL, | 90 | he = __hists__add_entry(&evsel->hists, &al, NULL, |
91 | NULL, NULL, 1, 1, 0); | 91 | NULL, NULL, 1, 1, 0, true); |
92 | if (he == NULL) | 92 | if (he == NULL) |
93 | goto out; | 93 | goto out; |
94 | 94 | ||
@@ -112,7 +112,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine) | |||
112 | goto out; | 112 | goto out; |
113 | 113 | ||
114 | he = __hists__add_entry(&evsel->hists, &al, NULL, | 114 | he = __hists__add_entry(&evsel->hists, &al, NULL, |
115 | NULL, NULL, 1, 1, 0); | 115 | NULL, NULL, 1, 1, 0, true); |
116 | if (he == NULL) | 116 | if (he == NULL) |
117 | goto out; | 117 | goto out; |
118 | 118 | ||
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index dfff2ee8effb..b9facf33b224 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -279,7 +279,8 @@ void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel) | |||
279 | * histogram, sorted on item, collects periods | 279 | * histogram, sorted on item, collects periods |
280 | */ | 280 | */ |
281 | 281 | ||
282 | static struct hist_entry *hist_entry__new(struct hist_entry *template) | 282 | static struct hist_entry *hist_entry__new(struct hist_entry *template, |
283 | bool sample_self) | ||
283 | { | 284 | { |
284 | size_t callchain_size = 0; | 285 | size_t callchain_size = 0; |
285 | struct hist_entry *he; | 286 | struct hist_entry *he; |
@@ -299,6 +300,8 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template) | |||
299 | return NULL; | 300 | return NULL; |
300 | } | 301 | } |
301 | memcpy(he->stat_acc, &he->stat, sizeof(he->stat)); | 302 | memcpy(he->stat_acc, &he->stat, sizeof(he->stat)); |
303 | if (!sample_self) | ||
304 | memset(&he->stat, 0, sizeof(he->stat)); | ||
302 | } | 305 | } |
303 | 306 | ||
304 | if (he->ms.map) | 307 | if (he->ms.map) |
@@ -351,7 +354,8 @@ static u8 symbol__parent_filter(const struct symbol *parent) | |||
351 | 354 | ||
352 | static struct hist_entry *add_hist_entry(struct hists *hists, | 355 | static struct hist_entry *add_hist_entry(struct hists *hists, |
353 | struct hist_entry *entry, | 356 | struct hist_entry *entry, |
354 | struct addr_location *al) | 357 | struct addr_location *al, |
358 | bool sample_self) | ||
355 | { | 359 | { |
356 | struct rb_node **p; | 360 | struct rb_node **p; |
357 | struct rb_node *parent = NULL; | 361 | struct rb_node *parent = NULL; |
@@ -375,7 +379,8 @@ static struct hist_entry *add_hist_entry(struct hists *hists, | |||
375 | cmp = hist_entry__cmp(he, entry); | 379 | cmp = hist_entry__cmp(he, entry); |
376 | 380 | ||
377 | if (!cmp) { | 381 | if (!cmp) { |
378 | he_stat__add_period(&he->stat, period, weight); | 382 | if (sample_self) |
383 | he_stat__add_period(&he->stat, period, weight); | ||
379 | if (symbol_conf.cumulate_callchain) | 384 | if (symbol_conf.cumulate_callchain) |
380 | he_stat__add_period(he->stat_acc, period, weight); | 385 | he_stat__add_period(he->stat_acc, period, weight); |
381 | 386 | ||
@@ -405,14 +410,15 @@ static struct hist_entry *add_hist_entry(struct hists *hists, | |||
405 | p = &(*p)->rb_right; | 410 | p = &(*p)->rb_right; |
406 | } | 411 | } |
407 | 412 | ||
408 | he = hist_entry__new(entry); | 413 | he = hist_entry__new(entry, sample_self); |
409 | if (!he) | 414 | if (!he) |
410 | return NULL; | 415 | return NULL; |
411 | 416 | ||
412 | rb_link_node(&he->rb_node_in, parent, p); | 417 | rb_link_node(&he->rb_node_in, parent, p); |
413 | rb_insert_color(&he->rb_node_in, hists->entries_in); | 418 | rb_insert_color(&he->rb_node_in, hists->entries_in); |
414 | out: | 419 | out: |
415 | he_stat__add_cpumode_period(&he->stat, al->cpumode, period); | 420 | if (sample_self) |
421 | he_stat__add_cpumode_period(&he->stat, al->cpumode, period); | ||
416 | if (symbol_conf.cumulate_callchain) | 422 | if (symbol_conf.cumulate_callchain) |
417 | he_stat__add_cpumode_period(he->stat_acc, al->cpumode, period); | 423 | he_stat__add_cpumode_period(he->stat_acc, al->cpumode, period); |
418 | return he; | 424 | return he; |
@@ -423,7 +429,8 @@ struct hist_entry *__hists__add_entry(struct hists *hists, | |||
423 | struct symbol *sym_parent, | 429 | struct symbol *sym_parent, |
424 | struct branch_info *bi, | 430 | struct branch_info *bi, |
425 | struct mem_info *mi, | 431 | struct mem_info *mi, |
426 | u64 period, u64 weight, u64 transaction) | 432 | u64 period, u64 weight, u64 transaction, |
433 | bool sample_self) | ||
427 | { | 434 | { |
428 | struct hist_entry entry = { | 435 | struct hist_entry entry = { |
429 | .thread = al->thread, | 436 | .thread = al->thread, |
@@ -448,7 +455,7 @@ struct hist_entry *__hists__add_entry(struct hists *hists, | |||
448 | .transaction = transaction, | 455 | .transaction = transaction, |
449 | }; | 456 | }; |
450 | 457 | ||
451 | return add_hist_entry(hists, &entry, al); | 458 | return add_hist_entry(hists, &entry, al, sample_self); |
452 | } | 459 | } |
453 | 460 | ||
454 | static int | 461 | static int |
@@ -501,7 +508,7 @@ iter_add_single_mem_entry(struct hist_entry_iter *iter, struct addr_location *al | |||
501 | * and the he_stat__add_period() function. | 508 | * and the he_stat__add_period() function. |
502 | */ | 509 | */ |
503 | he = __hists__add_entry(&iter->evsel->hists, al, iter->parent, NULL, mi, | 510 | he = __hists__add_entry(&iter->evsel->hists, al, iter->parent, NULL, mi, |
504 | cost, cost, 0); | 511 | cost, cost, 0, true); |
505 | if (!he) | 512 | if (!he) |
506 | return -ENOMEM; | 513 | return -ENOMEM; |
507 | 514 | ||
@@ -608,7 +615,7 @@ iter_add_next_branch_entry(struct hist_entry_iter *iter, struct addr_location *a | |||
608 | * and not events sampled. Thus we use a pseudo period of 1. | 615 | * and not events sampled. Thus we use a pseudo period of 1. |
609 | */ | 616 | */ |
610 | he = __hists__add_entry(&evsel->hists, al, iter->parent, &bi[i], NULL, | 617 | he = __hists__add_entry(&evsel->hists, al, iter->parent, &bi[i], NULL, |
611 | 1, 1, 0); | 618 | 1, 1, 0, true); |
612 | if (he == NULL) | 619 | if (he == NULL) |
613 | return -ENOMEM; | 620 | return -ENOMEM; |
614 | 621 | ||
@@ -657,7 +664,7 @@ iter_add_single_normal_entry(struct hist_entry_iter *iter, struct addr_location | |||
657 | 664 | ||
658 | he = __hists__add_entry(&evsel->hists, al, iter->parent, NULL, NULL, | 665 | he = __hists__add_entry(&evsel->hists, al, iter->parent, NULL, NULL, |
659 | sample->period, sample->weight, | 666 | sample->period, sample->weight, |
660 | sample->transaction); | 667 | sample->transaction, true); |
661 | if (he == NULL) | 668 | if (he == NULL) |
662 | return -ENOMEM; | 669 | return -ENOMEM; |
663 | 670 | ||
@@ -1161,7 +1168,7 @@ static struct hist_entry *hists__add_dummy_entry(struct hists *hists, | |||
1161 | p = &(*p)->rb_right; | 1168 | p = &(*p)->rb_right; |
1162 | } | 1169 | } |
1163 | 1170 | ||
1164 | he = hist_entry__new(pair); | 1171 | he = hist_entry__new(pair, true); |
1165 | if (he) { | 1172 | if (he) { |
1166 | memset(&he->stat, 0, sizeof(he->stat)); | 1173 | memset(&he->stat, 0, sizeof(he->stat)); |
1167 | he->hists = hists; | 1174 | he->hists = hists; |
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 8894f184357c..bedb24d3643c 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
@@ -130,7 +130,8 @@ struct hist_entry *__hists__add_entry(struct hists *hists, | |||
130 | struct symbol *parent, | 130 | struct symbol *parent, |
131 | struct branch_info *bi, | 131 | struct branch_info *bi, |
132 | struct mem_info *mi, u64 period, | 132 | struct mem_info *mi, u64 period, |
133 | u64 weight, u64 transaction); | 133 | u64 weight, u64 transaction, |
134 | bool sample_self); | ||
134 | int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al, | 135 | int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al, |
135 | struct perf_evsel *evsel, struct perf_sample *sample, | 136 | struct perf_evsel *evsel, struct perf_sample *sample, |
136 | int max_stack_depth); | 137 | int max_stack_depth); |