aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util')
-rw-r--r--tools/perf/util/event.h1
-rw-r--r--tools/perf/util/evsel.c10
-rw-r--r--tools/perf/util/hist.c23
-rw-r--r--tools/perf/util/hist.h8
-rw-r--r--tools/perf/util/session.c3
-rw-r--r--tools/perf/util/sort.c45
-rw-r--r--tools/perf/util/sort.h3
7 files changed, 84 insertions, 9 deletions
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 0d573ff4771a..a97fbbe6b3b3 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -88,6 +88,7 @@ struct perf_sample {
88 u64 id; 88 u64 id;
89 u64 stream_id; 89 u64 stream_id;
90 u64 period; 90 u64 period;
91 u64 weight;
91 u32 cpu; 92 u32 cpu;
92 u32 raw_size; 93 u32 raw_size;
93 void *raw_data; 94 void *raw_data;
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 1adb824610f0..23061a6ccd77 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -563,6 +563,9 @@ void perf_evsel__config(struct perf_evsel *evsel,
563 attr->branch_sample_type = opts->branch_stack; 563 attr->branch_sample_type = opts->branch_stack;
564 } 564 }
565 565
566 if (opts->sample_weight)
567 attr->sample_type |= PERF_SAMPLE_WEIGHT;
568
566 attr->mmap = track; 569 attr->mmap = track;
567 attr->comm = track; 570 attr->comm = track;
568 571
@@ -1017,6 +1020,7 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
1017 data->cpu = data->pid = data->tid = -1; 1020 data->cpu = data->pid = data->tid = -1;
1018 data->stream_id = data->id = data->time = -1ULL; 1021 data->stream_id = data->id = data->time = -1ULL;
1019 data->period = 1; 1022 data->period = 1;
1023 data->weight = 0;
1020 1024
1021 if (event->header.type != PERF_RECORD_SAMPLE) { 1025 if (event->header.type != PERF_RECORD_SAMPLE) {
1022 if (!evsel->attr.sample_id_all) 1026 if (!evsel->attr.sample_id_all)
@@ -1167,6 +1171,12 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
1167 } 1171 }
1168 } 1172 }
1169 1173
1174 data->weight = 0;
1175 if (type & PERF_SAMPLE_WEIGHT) {
1176 data->weight = *array;
1177 array++;
1178 }
1179
1170 return 0; 1180 return 0;
1171} 1181}
1172 1182
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index f855941bebea..97ddd18acd7c 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -155,9 +155,11 @@ static void hist_entry__add_cpumode_period(struct hist_entry *he,
155 } 155 }
156} 156}
157 157
158static void he_stat__add_period(struct he_stat *he_stat, u64 period) 158static void he_stat__add_period(struct he_stat *he_stat, u64 period,
159 u64 weight)
159{ 160{
160 he_stat->period += period; 161 he_stat->period += period;
162 he_stat->weight += weight;
161 he_stat->nr_events += 1; 163 he_stat->nr_events += 1;
162} 164}
163 165
@@ -169,12 +171,14 @@ static void he_stat__add_stat(struct he_stat *dest, struct he_stat *src)
169 dest->period_guest_sys += src->period_guest_sys; 171 dest->period_guest_sys += src->period_guest_sys;
170 dest->period_guest_us += src->period_guest_us; 172 dest->period_guest_us += src->period_guest_us;
171 dest->nr_events += src->nr_events; 173 dest->nr_events += src->nr_events;
174 dest->weight += src->weight;
172} 175}
173 176
174static void hist_entry__decay(struct hist_entry *he) 177static void hist_entry__decay(struct hist_entry *he)
175{ 178{
176 he->stat.period = (he->stat.period * 7) / 8; 179 he->stat.period = (he->stat.period * 7) / 8;
177 he->stat.nr_events = (he->stat.nr_events * 7) / 8; 180 he->stat.nr_events = (he->stat.nr_events * 7) / 8;
181 /* XXX need decay for weight too? */
178} 182}
179 183
180static bool hists__decay_entry(struct hists *hists, struct hist_entry *he) 184static bool hists__decay_entry(struct hists *hists, struct hist_entry *he)
@@ -282,7 +286,8 @@ static u8 symbol__parent_filter(const struct symbol *parent)
282static struct hist_entry *add_hist_entry(struct hists *hists, 286static struct hist_entry *add_hist_entry(struct hists *hists,
283 struct hist_entry *entry, 287 struct hist_entry *entry,
284 struct addr_location *al, 288 struct addr_location *al,
285 u64 period) 289 u64 period,
290 u64 weight)
286{ 291{
287 struct rb_node **p; 292 struct rb_node **p;
288 struct rb_node *parent = NULL; 293 struct rb_node *parent = NULL;
@@ -306,7 +311,7 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
306 cmp = hist_entry__cmp(he, entry); 311 cmp = hist_entry__cmp(he, entry);
307 312
308 if (!cmp) { 313 if (!cmp) {
309 he_stat__add_period(&he->stat, period); 314 he_stat__add_period(&he->stat, period, weight);
310 315
311 /* If the map of an existing hist_entry has 316 /* If the map of an existing hist_entry has
312 * become out-of-date due to an exec() or 317 * become out-of-date due to an exec() or
@@ -345,7 +350,8 @@ struct hist_entry *__hists__add_branch_entry(struct hists *self,
345 struct addr_location *al, 350 struct addr_location *al,
346 struct symbol *sym_parent, 351 struct symbol *sym_parent,
347 struct branch_info *bi, 352 struct branch_info *bi,
348 u64 period) 353 u64 period,
354 u64 weight)
349{ 355{
350 struct hist_entry entry = { 356 struct hist_entry entry = {
351 .thread = al->thread, 357 .thread = al->thread,
@@ -359,6 +365,7 @@ struct hist_entry *__hists__add_branch_entry(struct hists *self,
359 .stat = { 365 .stat = {
360 .period = period, 366 .period = period,
361 .nr_events = 1, 367 .nr_events = 1,
368 .weight = weight,
362 }, 369 },
363 .parent = sym_parent, 370 .parent = sym_parent,
364 .filtered = symbol__parent_filter(sym_parent), 371 .filtered = symbol__parent_filter(sym_parent),
@@ -366,12 +373,13 @@ struct hist_entry *__hists__add_branch_entry(struct hists *self,
366 .hists = self, 373 .hists = self,
367 }; 374 };
368 375
369 return add_hist_entry(self, &entry, al, period); 376 return add_hist_entry(self, &entry, al, period, weight);
370} 377}
371 378
372struct hist_entry *__hists__add_entry(struct hists *self, 379struct hist_entry *__hists__add_entry(struct hists *self,
373 struct addr_location *al, 380 struct addr_location *al,
374 struct symbol *sym_parent, u64 period) 381 struct symbol *sym_parent, u64 period,
382 u64 weight)
375{ 383{
376 struct hist_entry entry = { 384 struct hist_entry entry = {
377 .thread = al->thread, 385 .thread = al->thread,
@@ -385,13 +393,14 @@ struct hist_entry *__hists__add_entry(struct hists *self,
385 .stat = { 393 .stat = {
386 .period = period, 394 .period = period,
387 .nr_events = 1, 395 .nr_events = 1,
396 .weight = weight,
388 }, 397 },
389 .parent = sym_parent, 398 .parent = sym_parent,
390 .filtered = symbol__parent_filter(sym_parent), 399 .filtered = symbol__parent_filter(sym_parent),
391 .hists = self, 400 .hists = self,
392 }; 401 };
393 402
394 return add_hist_entry(self, &entry, al, period); 403 return add_hist_entry(self, &entry, al, period, weight);
395} 404}
396 405
397int64_t 406int64_t
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 848331377bdb..121cc14b6041 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -49,6 +49,8 @@ enum hist_column {
49 HISTC_DSO_FROM, 49 HISTC_DSO_FROM,
50 HISTC_DSO_TO, 50 HISTC_DSO_TO,
51 HISTC_SRCLINE, 51 HISTC_SRCLINE,
52 HISTC_LOCAL_WEIGHT,
53 HISTC_GLOBAL_WEIGHT,
52 HISTC_NR_COLS, /* Last entry */ 54 HISTC_NR_COLS, /* Last entry */
53}; 55};
54 56
@@ -73,7 +75,8 @@ struct hists {
73 75
74struct hist_entry *__hists__add_entry(struct hists *self, 76struct hist_entry *__hists__add_entry(struct hists *self,
75 struct addr_location *al, 77 struct addr_location *al,
76 struct symbol *parent, u64 period); 78 struct symbol *parent, u64 period,
79 u64 weight);
77int64_t hist_entry__cmp(struct hist_entry *left, struct hist_entry *right); 80int64_t hist_entry__cmp(struct hist_entry *left, struct hist_entry *right);
78int64_t hist_entry__collapse(struct hist_entry *left, struct hist_entry *right); 81int64_t hist_entry__collapse(struct hist_entry *left, struct hist_entry *right);
79int hist_entry__sort_snprintf(struct hist_entry *self, char *bf, size_t size, 82int hist_entry__sort_snprintf(struct hist_entry *self, char *bf, size_t size,
@@ -84,7 +87,8 @@ struct hist_entry *__hists__add_branch_entry(struct hists *self,
84 struct addr_location *al, 87 struct addr_location *al,
85 struct symbol *sym_parent, 88 struct symbol *sym_parent,
86 struct branch_info *bi, 89 struct branch_info *bi,
87 u64 period); 90 u64 period,
91 u64 weight);
88 92
89void hists__output_resort(struct hists *self); 93void hists__output_resort(struct hists *self);
90void hists__output_resort_threaded(struct hists *hists); 94void hists__output_resort_threaded(struct hists *hists);
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index c8ba120b0dbe..627be09b479e 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -798,6 +798,9 @@ static void dump_sample(struct perf_evsel *evsel, union perf_event *event,
798 798
799 if (sample_type & PERF_SAMPLE_STACK_USER) 799 if (sample_type & PERF_SAMPLE_STACK_USER)
800 stack_user__printf(&sample->user_stack); 800 stack_user__printf(&sample->user_stack);
801
802 if (sample_type & PERF_SAMPLE_WEIGHT)
803 printf("... weight: %" PRIu64 "\n", sample->weight);
801} 804}
802 805
803static struct machine * 806static struct machine *
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index d41926cb9e3f..d66bcd33248c 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -464,6 +464,49 @@ struct sort_entry sort_mispredict = {
464 .se_width_idx = HISTC_MISPREDICT, 464 .se_width_idx = HISTC_MISPREDICT,
465}; 465};
466 466
467static u64 he_weight(struct hist_entry *he)
468{
469 return he->stat.nr_events ? he->stat.weight / he->stat.nr_events : 0;
470}
471
472static int64_t
473sort__local_weight_cmp(struct hist_entry *left, struct hist_entry *right)
474{
475 return he_weight(left) - he_weight(right);
476}
477
478static int hist_entry__local_weight_snprintf(struct hist_entry *self, char *bf,
479 size_t size, unsigned int width)
480{
481 return repsep_snprintf(bf, size, "%-*llu", width, he_weight(self));
482}
483
484struct sort_entry sort_local_weight = {
485 .se_header = "Local Weight",
486 .se_cmp = sort__local_weight_cmp,
487 .se_snprintf = hist_entry__local_weight_snprintf,
488 .se_width_idx = HISTC_LOCAL_WEIGHT,
489};
490
491static int64_t
492sort__global_weight_cmp(struct hist_entry *left, struct hist_entry *right)
493{
494 return left->stat.weight - right->stat.weight;
495}
496
497static int hist_entry__global_weight_snprintf(struct hist_entry *self, char *bf,
498 size_t size, unsigned int width)
499{
500 return repsep_snprintf(bf, size, "%-*llu", width, self->stat.weight);
501}
502
503struct sort_entry sort_global_weight = {
504 .se_header = "Weight",
505 .se_cmp = sort__global_weight_cmp,
506 .se_snprintf = hist_entry__global_weight_snprintf,
507 .se_width_idx = HISTC_GLOBAL_WEIGHT,
508};
509
467struct sort_dimension { 510struct sort_dimension {
468 const char *name; 511 const char *name;
469 struct sort_entry *entry; 512 struct sort_entry *entry;
@@ -480,6 +523,8 @@ static struct sort_dimension common_sort_dimensions[] = {
480 DIM(SORT_PARENT, "parent", sort_parent), 523 DIM(SORT_PARENT, "parent", sort_parent),
481 DIM(SORT_CPU, "cpu", sort_cpu), 524 DIM(SORT_CPU, "cpu", sort_cpu),
482 DIM(SORT_SRCLINE, "srcline", sort_srcline), 525 DIM(SORT_SRCLINE, "srcline", sort_srcline),
526 DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight),
527 DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight),
483}; 528};
484 529
485#undef DIM 530#undef DIM
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index b13e56f6ccbe..393925012796 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -49,6 +49,7 @@ struct he_stat {
49 u64 period_us; 49 u64 period_us;
50 u64 period_guest_sys; 50 u64 period_guest_sys;
51 u64 period_guest_us; 51 u64 period_guest_us;
52 u64 weight;
52 u32 nr_events; 53 u32 nr_events;
53}; 54};
54 55
@@ -130,6 +131,8 @@ enum sort_type {
130 SORT_PARENT, 131 SORT_PARENT,
131 SORT_CPU, 132 SORT_CPU,
132 SORT_SRCLINE, 133 SORT_SRCLINE,
134 SORT_LOCAL_WEIGHT,
135 SORT_GLOBAL_WEIGHT,
133 136
134 /* branch stack specific sort keys */ 137 /* branch stack specific sort keys */
135 __SORT_BRANCH_STACK, 138 __SORT_BRANCH_STACK,