aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/Documentation/perf-record.txt6
-rw-r--r--tools/perf/Documentation/perf-report.txt2
-rw-r--r--tools/perf/Documentation/perf-top.txt2
-rw-r--r--tools/perf/builtin-annotate.c2
-rw-r--r--tools/perf/builtin-diff.c7
-rw-r--r--tools/perf/builtin-record.c2
-rw-r--r--tools/perf/builtin-report.c8
-rw-r--r--tools/perf/builtin-top.c5
-rw-r--r--tools/perf/perf.h1
-rw-r--r--tools/perf/tests/hists_link.c4
-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
17 files changed, 110 insertions, 22 deletions
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index 938e8904f64d..d4da111ef53d 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -182,6 +182,12 @@ is enabled for all the sampling events. The sampled branch type is the same for
182The various filters must be specified as a comma separated list: --branch-filter any_ret,u,k 182The various filters must be specified as a comma separated list: --branch-filter any_ret,u,k
183Note that this feature may not be available on all processors. 183Note that this feature may not be available on all processors.
184 184
185-W::
186--weight::
187Enable weightened sampling. An additional weight is recorded per sample and can be
188displayed with the weight and local_weight sort keys. This currently works for TSX
189abort events and some memory events in precise mode on modern Intel CPUs.
190
185SEE ALSO 191SEE ALSO
186-------- 192--------
187linkperf:perf-stat[1], linkperf:perf-list[1] 193linkperf:perf-stat[1], linkperf:perf-list[1]
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index 71f15510ca0b..7d5f4f38aa52 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -59,7 +59,7 @@ OPTIONS
59--sort=:: 59--sort=::
60 Sort histogram entries by given key(s) - multiple keys can be specified 60 Sort histogram entries by given key(s) - multiple keys can be specified
61 in CSV format. Following sort keys are available: 61 in CSV format. Following sort keys are available:
62 pid, comm, dso, symbol, parent, cpu, srcline. 62 pid, comm, dso, symbol, parent, cpu, srcline, weight, local_weight.
63 63
64 Each key has following meaning: 64 Each key has following meaning:
65 65
diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt
index a414bc95fd52..9f1a2fe54757 100644
--- a/tools/perf/Documentation/perf-top.txt
+++ b/tools/perf/Documentation/perf-top.txt
@@ -112,7 +112,7 @@ Default is to monitor all CPUS.
112 112
113-s:: 113-s::
114--sort:: 114--sort::
115 Sort by key(s): pid, comm, dso, symbol, parent, srcline. 115 Sort by key(s): pid, comm, dso, symbol, parent, srcline, weight, local_weight.
116 116
117-n:: 117-n::
118--show-nr-samples:: 118--show-nr-samples::
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index ae36f3cb5410..db491e9a812b 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -63,7 +63,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,
63 return 0; 63 return 0;
64 } 64 }
65 65
66 he = __hists__add_entry(&evsel->hists, al, NULL, 1); 66 he = __hists__add_entry(&evsel->hists, al, NULL, 1, 1);
67 if (he == NULL) 67 if (he == NULL)
68 return -ENOMEM; 68 return -ENOMEM;
69 69
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index d207a97a2db1..2d0462d89a97 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -231,9 +231,10 @@ int perf_diff__formula(struct hist_entry *he, struct hist_entry *pair,
231} 231}
232 232
233static int hists__add_entry(struct hists *self, 233static int hists__add_entry(struct hists *self,
234 struct addr_location *al, u64 period) 234 struct addr_location *al, u64 period,
235 u64 weight)
235{ 236{
236 if (__hists__add_entry(self, al, NULL, period) != NULL) 237 if (__hists__add_entry(self, al, NULL, period, weight) != NULL)
237 return 0; 238 return 0;
238 return -ENOMEM; 239 return -ENOMEM;
239} 240}
@@ -255,7 +256,7 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused,
255 if (al.filtered) 256 if (al.filtered)
256 return 0; 257 return 0;
257 258
258 if (hists__add_entry(&evsel->hists, &al, sample->period)) { 259 if (hists__add_entry(&evsel->hists, &al, sample->period, sample->weight)) {
259 pr_warning("problem incrementing symbol period, skipping event\n"); 260 pr_warning("problem incrementing symbol period, skipping event\n");
260 return -1; 261 return -1;
261 } 262 }
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 78a41fdbe56c..cdf58ecc04b1 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -953,6 +953,8 @@ const struct option record_options[] = {
953 OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack, 953 OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack,
954 "branch filter mask", "branch stack filter modes", 954 "branch filter mask", "branch stack filter modes",
955 parse_branch_stack), 955 parse_branch_stack),
956 OPT_BOOLEAN('W', "weight", &record.opts.sample_weight,
957 "sample by weight (on special events only)"),
956 OPT_END() 958 OPT_END()
957}; 959};
958 960
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index b5ea26cc7eb1..e31f070abe2f 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -98,7 +98,7 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,
98 * and not events sampled. Thus we use a pseudo period of 1. 98 * and not events sampled. Thus we use a pseudo period of 1.
99 */ 99 */
100 he = __hists__add_branch_entry(&evsel->hists, al, parent, 100 he = __hists__add_branch_entry(&evsel->hists, al, parent,
101 &bi[i], 1); 101 &bi[i], 1, 1);
102 if (he) { 102 if (he) {
103 struct annotation *notes; 103 struct annotation *notes;
104 err = -ENOMEM; 104 err = -ENOMEM;
@@ -156,7 +156,8 @@ static int perf_evsel__add_hist_entry(struct perf_evsel *evsel,
156 return err; 156 return err;
157 } 157 }
158 158
159 he = __hists__add_entry(&evsel->hists, al, parent, sample->period); 159 he = __hists__add_entry(&evsel->hists, al, parent, sample->period,
160 sample->weight);
160 if (he == NULL) 161 if (he == NULL)
161 return -ENOMEM; 162 return -ENOMEM;
162 163
@@ -644,7 +645,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
644 "Use the stdio interface"), 645 "Use the stdio interface"),
645 OPT_STRING('s', "sort", &sort_order, "key[,key2...]", 646 OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
646 "sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline," 647 "sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline,"
647 " dso_to, dso_from, symbol_to, symbol_from, mispredict"), 648 " dso_to, dso_from, symbol_to, symbol_from, mispredict,"
649 " weight, local_weight"),
648 OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization, 650 OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization,
649 "Show sample percentage for different cpu modes"), 651 "Show sample percentage for different cpu modes"),
650 OPT_STRING('p', "parent", &parent_pattern, "regex", 652 OPT_STRING('p', "parent", &parent_pattern, "regex",
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index b5520ad0dbb8..67bdb9f14ad6 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -251,7 +251,8 @@ static struct hist_entry *perf_evsel__add_hist_entry(struct perf_evsel *evsel,
251{ 251{
252 struct hist_entry *he; 252 struct hist_entry *he;
253 253
254 he = __hists__add_entry(&evsel->hists, al, NULL, sample->period); 254 he = __hists__add_entry(&evsel->hists, al, NULL, sample->period,
255 sample->weight);
255 if (he == NULL) 256 if (he == NULL)
256 return NULL; 257 return NULL;
257 258
@@ -1088,7 +1089,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
1088 OPT_INCR('v', "verbose", &verbose, 1089 OPT_INCR('v', "verbose", &verbose,
1089 "be more verbose (show counter open errors, etc)"), 1090 "be more verbose (show counter open errors, etc)"),
1090 OPT_STRING('s', "sort", &sort_order, "key[,key2...]", 1091 OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
1091 "sort by key(s): pid, comm, dso, symbol, parent"), 1092 "sort by key(s): pid, comm, dso, symbol, parent, weight, local_weight"),
1092 OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples, 1093 OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
1093 "Show a column with the number of samples"), 1094 "Show a column with the number of samples"),
1094 OPT_CALLBACK_DEFAULT('G', "call-graph", &top.record_opts, 1095 OPT_CALLBACK_DEFAULT('G', "call-graph", &top.record_opts,
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index 74659ecf93e0..32bd102c32b6 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -218,6 +218,7 @@ struct perf_record_opts {
218 bool pipe_output; 218 bool pipe_output;
219 bool raw_samples; 219 bool raw_samples;
220 bool sample_address; 220 bool sample_address;
221 bool sample_weight;
221 bool sample_time; 222 bool sample_time;
222 bool period; 223 bool period;
223 unsigned int freq; 224 unsigned int freq;
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c
index e0c0267858a1..89085a9615e2 100644
--- a/tools/perf/tests/hists_link.c
+++ b/tools/perf/tests/hists_link.c
@@ -223,7 +223,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
223 &sample, 0) < 0) 223 &sample, 0) < 0)
224 goto out; 224 goto out;
225 225
226 he = __hists__add_entry(&evsel->hists, &al, NULL, 1); 226 he = __hists__add_entry(&evsel->hists, &al, NULL, 1, 1);
227 if (he == NULL) 227 if (he == NULL)
228 goto out; 228 goto out;
229 229
@@ -247,7 +247,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
247 &sample, 0) < 0) 247 &sample, 0) < 0)
248 goto out; 248 goto out;
249 249
250 he = __hists__add_entry(&evsel->hists, &al, NULL, 1); 250 he = __hists__add_entry(&evsel->hists, &al, NULL, 1, 1);
251 if (he == NULL) 251 if (he == NULL)
252 goto out; 252 goto out;
253 253
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,