aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2013-10-24 02:48:11 -0400
committerIngo Molnar <mingo@kernel.org>2013-10-24 02:48:11 -0400
commit2f5e98802350627ad6f2e3cee4d177059fc0c2f2 (patch)
treed4bbd2fadb55737c20e96ed0f2db9101c9ba24a0 /tools/perf
parentaa30a2e03a453aad9fd96c3f2d4a82c3497674e5 (diff)
parentc1fb5651bb40f9efaf32d280f39e06df7e352673 (diff)
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: * Show progress on histogram collapsing, that can take a long time, from Namhyung Kim. * Support "$vars" meta argument syntax for local variables, allowing asking for all possible variables at a given probe point to be collected when it hits, from Masami Hiramatsu. * Address the root cause of that 'perf sched' stack initialization build slowdown, by programmatically setting a big array after moving the global variable back to the stack. Fix from Adrian Hunter. * Do not repipe attributes to a perf.data file in 'perf inject', fix from Adrian Hunter * Change the procps visible command-name of invididual benchmark tests plus cleanups, from Ingo Molnar. * Do not accept parse_tag_value() overflow, fix from Adrian Hunter. * Validate that mmap_pages is not too big. From Adrian Hunter. * Fix non-debug build, from Adrian Hunter. * Clarify the "sample parsing" test entry, from Arnaldo Carvalho de Melo. * Consider PERF_SAMPLE_TRANSACTION in the "sample parsing" test, from Arnaldo Carvalho de Melo. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/Makefile.perf1
-rw-r--r--tools/perf/builtin-annotate.c6
-rw-r--r--tools/perf/builtin-bench.c239
-rw-r--r--tools/perf/builtin-diff.c7
-rw-r--r--tools/perf/builtin-inject.c27
-rw-r--r--tools/perf/builtin-report.c24
-rw-r--r--tools/perf/builtin-sched.c44
-rw-r--r--tools/perf/builtin-script.c40
-rw-r--r--tools/perf/builtin-top.c4
-rw-r--r--tools/perf/config/Makefile4
-rw-r--r--tools/perf/tests/hists_link.c2
-rw-r--r--tools/perf/tests/sample-parsing.c4
-rw-r--r--tools/perf/ui/gtk/gtk.h2
-rw-r--r--tools/perf/ui/gtk/progress.c20
-rw-r--r--tools/perf/ui/gtk/setup.c2
-rw-r--r--tools/perf/ui/progress.c32
-rw-r--r--tools/perf/ui/progress.h19
-rw-r--r--tools/perf/ui/tui/progress.c15
-rw-r--r--tools/perf/ui/tui/setup.c3
-rw-r--r--tools/perf/ui/tui/tui.h6
-rw-r--r--tools/perf/util/build-id.c6
-rw-r--r--tools/perf/util/evlist.c14
-rw-r--r--tools/perf/util/hist.c23
-rw-r--r--tools/perf/util/hist.h3
-rw-r--r--tools/perf/util/probe-event.c1
-rw-r--r--tools/perf/util/probe-finder.c133
-rw-r--r--tools/perf/util/probe-finder.h1
-rw-r--r--tools/perf/util/session.c24
-rw-r--r--tools/perf/util/sort.c124
-rw-r--r--tools/perf/util/strfilter.c46
-rw-r--r--tools/perf/util/thread.c72
-rw-r--r--tools/perf/util/util.c2
32 files changed, 560 insertions, 390 deletions
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 326a26e5fc1c..8a9ca3836043 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -487,6 +487,7 @@ ifndef NO_SLANG
487 LIB_OBJS += $(OUTPUT)ui/tui/util.o 487 LIB_OBJS += $(OUTPUT)ui/tui/util.o
488 LIB_OBJS += $(OUTPUT)ui/tui/helpline.o 488 LIB_OBJS += $(OUTPUT)ui/tui/helpline.o
489 LIB_OBJS += $(OUTPUT)ui/tui/progress.o 489 LIB_OBJS += $(OUTPUT)ui/tui/progress.o
490 LIB_H += ui/tui/tui.h
490 LIB_H += ui/browser.h 491 LIB_H += ui/browser.h
491 LIB_H += ui/browsers/map.h 492 LIB_H += ui/browsers/map.h
492 LIB_H += ui/keysyms.h 493 LIB_H += ui/keysyms.h
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 03cfa592071f..6c5ae57831f6 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -118,11 +118,11 @@ static int hist_entry__tty_annotate(struct hist_entry *he,
118 ann->print_line, ann->full_paths, 0, 0); 118 ann->print_line, ann->full_paths, 0, 0);
119} 119}
120 120
121static void hists__find_annotations(struct hists *self, 121static void hists__find_annotations(struct hists *hists,
122 struct perf_evsel *evsel, 122 struct perf_evsel *evsel,
123 struct perf_annotate *ann) 123 struct perf_annotate *ann)
124{ 124{
125 struct rb_node *nd = rb_first(&self->entries), *next; 125 struct rb_node *nd = rb_first(&hists->entries), *next;
126 int key = K_RIGHT; 126 int key = K_RIGHT;
127 127
128 while (nd) { 128 while (nd) {
@@ -247,7 +247,7 @@ static int __cmd_annotate(struct perf_annotate *ann)
247 247
248 if (nr_samples > 0) { 248 if (nr_samples > 0) {
249 total_nr_samples += nr_samples; 249 total_nr_samples += nr_samples;
250 hists__collapse_resort(hists); 250 hists__collapse_resort(hists, NULL);
251 hists__output_resort(hists); 251 hists__output_resort(hists);
252 252
253 if (symbol_conf.event_group && 253 if (symbol_conf.event_group &&
diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c
index 33af80fa49cf..e47f90cc7b98 100644
--- a/tools/perf/builtin-bench.c
+++ b/tools/perf/builtin-bench.c
@@ -1,21 +1,18 @@
1/* 1/*
2 *
3 * builtin-bench.c 2 * builtin-bench.c
4 * 3 *
5 * General benchmarking subsystem provided by perf 4 * General benchmarking collections provided by perf
6 * 5 *
7 * Copyright (C) 2009, Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp> 6 * Copyright (C) 2009, Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
8 *
9 */ 7 */
10 8
11/* 9/*
10 * Available benchmark collection list:
12 * 11 *
13 * Available subsystem list: 12 * sched ... scheduler and IPC performance
14 * sched ... scheduler and IPC mechanism
15 * mem ... memory access performance 13 * mem ... memory access performance
16 * 14 * numa ... NUMA scheduling and MM performance
17 */ 15 */
18
19#include "perf.h" 16#include "perf.h"
20#include "util/util.h" 17#include "util/util.h"
21#include "util/parse-options.h" 18#include "util/parse-options.h"
@@ -25,112 +22,92 @@
25#include <stdio.h> 22#include <stdio.h>
26#include <stdlib.h> 23#include <stdlib.h>
27#include <string.h> 24#include <string.h>
25#include <sys/prctl.h>
28 26
29struct bench_suite { 27typedef int (*bench_fn_t)(int argc, const char **argv, const char *prefix);
30 const char *name; 28
31 const char *summary; 29struct bench {
32 int (*fn)(int, const char **, const char *); 30 const char *name;
31 const char *summary;
32 bench_fn_t fn;
33}; 33};
34 \
35/* sentinel: easy for help */
36#define suite_all { "all", "Test all benchmark suites", NULL }
37 34
38#ifdef HAVE_LIBNUMA_SUPPORT 35#ifdef HAVE_LIBNUMA_SUPPORT
39static struct bench_suite numa_suites[] = { 36static struct bench numa_benchmarks[] = {
40 { "mem", 37 { "mem", "Benchmark for NUMA workloads", bench_numa },
41 "Benchmark for NUMA workloads", 38 { "all", "Test all NUMA benchmarks", NULL },
42 bench_numa }, 39 { NULL, NULL, NULL }
43 suite_all,
44 { NULL,
45 NULL,
46 NULL }
47}; 40};
48#endif 41#endif
49 42
50static struct bench_suite sched_suites[] = { 43static struct bench sched_benchmarks[] = {
51 { "messaging", 44 { "messaging", "Benchmark for scheduling and IPC", bench_sched_messaging },
52 "Benchmark for scheduler and IPC mechanisms", 45 { "pipe", "Benchmark for pipe() between two processes", bench_sched_pipe },
53 bench_sched_messaging }, 46 { "all", "Test all scheduler benchmarks", NULL },
54 { "pipe", 47 { NULL, NULL, NULL }
55 "Flood of communication over pipe() between two processes",
56 bench_sched_pipe },
57 suite_all,
58 { NULL,
59 NULL,
60 NULL }
61}; 48};
62 49
63static struct bench_suite mem_suites[] = { 50static struct bench mem_benchmarks[] = {
64 { "memcpy", 51 { "memcpy", "Benchmark for memcpy()", bench_mem_memcpy },
65 "Simple memory copy in various ways", 52 { "memset", "Benchmark for memset() tests", bench_mem_memset },
66 bench_mem_memcpy }, 53 { "all", "Test all memory benchmarks", NULL },
67 { "memset", 54 { NULL, NULL, NULL }
68 "Simple memory set in various ways",
69 bench_mem_memset },
70 suite_all,
71 { NULL,
72 NULL,
73 NULL }
74}; 55};
75 56
76struct bench_subsys { 57struct collection {
77 const char *name; 58 const char *name;
78 const char *summary; 59 const char *summary;
79 struct bench_suite *suites; 60 struct bench *benchmarks;
80}; 61};
81 62
82static struct bench_subsys subsystems[] = { 63static struct collection collections[] = {
64 { "sched", "Scheduler and IPC benchmarks", sched_benchmarks },
65 { "mem", "Memory access benchmarks", mem_benchmarks },
83#ifdef HAVE_LIBNUMA_SUPPORT 66#ifdef HAVE_LIBNUMA_SUPPORT
84 { "numa", 67 { "numa", "NUMA scheduling and MM benchmarks", numa_benchmarks },
85 "NUMA scheduling and MM behavior",
86 numa_suites },
87#endif 68#endif
88 { "sched", 69 { "all", "All benchmarks", NULL },
89 "scheduler and IPC mechanism", 70 { NULL, NULL, NULL }
90 sched_suites },
91 { "mem",
92 "memory access performance",
93 mem_suites },
94 { "all", /* sentinel: easy for help */
95 "all benchmark subsystem",
96 NULL },
97 { NULL,
98 NULL,
99 NULL }
100}; 71};
101 72
102static void dump_suites(int subsys_index) 73/* Iterate over all benchmark collections: */
74#define for_each_collection(coll) \
75 for (coll = collections; coll->name; coll++)
76
77/* Iterate over all benchmarks within a collection: */
78#define for_each_bench(coll, bench) \
79 for (bench = coll->benchmarks; bench->name; bench++)
80
81static void dump_benchmarks(struct collection *coll)
103{ 82{
104 int i; 83 struct bench *bench;
105 84
106 printf("# List of available suites for %s...\n\n", 85 printf("\n # List of available benchmarks for collection '%s':\n\n", coll->name);
107 subsystems[subsys_index].name);
108 86
109 for (i = 0; subsystems[subsys_index].suites[i].name; i++) 87 for_each_bench(coll, bench)
110 printf("%14s: %s\n", 88 printf("%14s: %s\n", bench->name, bench->summary);
111 subsystems[subsys_index].suites[i].name,
112 subsystems[subsys_index].suites[i].summary);
113 89
114 printf("\n"); 90 printf("\n");
115 return;
116} 91}
117 92
118static const char *bench_format_str; 93static const char *bench_format_str;
94
95/* Output/formatting style, exported to benchmark modules: */
119int bench_format = BENCH_FORMAT_DEFAULT; 96int bench_format = BENCH_FORMAT_DEFAULT;
120 97
121static const struct option bench_options[] = { 98static const struct option bench_options[] = {
122 OPT_STRING('f', "format", &bench_format_str, "default", 99 OPT_STRING('f', "format", &bench_format_str, "default", "Specify format style"),
123 "Specify format style"),
124 OPT_END() 100 OPT_END()
125}; 101};
126 102
127static const char * const bench_usage[] = { 103static const char * const bench_usage[] = {
128 "perf bench [<common options>] <subsystem> <suite> [<options>]", 104 "perf bench [<common options>] <collection> <benchmark> [<options>]",
129 NULL 105 NULL
130}; 106};
131 107
132static void print_usage(void) 108static void print_usage(void)
133{ 109{
110 struct collection *coll;
134 int i; 111 int i;
135 112
136 printf("Usage: \n"); 113 printf("Usage: \n");
@@ -138,11 +115,10 @@ static void print_usage(void)
138 printf("\t%s\n", bench_usage[i]); 115 printf("\t%s\n", bench_usage[i]);
139 printf("\n"); 116 printf("\n");
140 117
141 printf("# List of available subsystems...\n\n"); 118 printf(" # List of all available benchmark collections:\n\n");
142 119
143 for (i = 0; subsystems[i].name; i++) 120 for_each_collection(coll)
144 printf("%14s: %s\n", 121 printf("%14s: %s\n", coll->name, coll->summary);
145 subsystems[i].name, subsystems[i].summary);
146 printf("\n"); 122 printf("\n");
147} 123}
148 124
@@ -159,44 +135,74 @@ static int bench_str2int(const char *str)
159 return BENCH_FORMAT_UNKNOWN; 135 return BENCH_FORMAT_UNKNOWN;
160} 136}
161 137
162static void all_suite(struct bench_subsys *subsys) /* FROM HERE */ 138/*
139 * Run a specific benchmark but first rename the running task's ->comm[]
140 * to something meaningful:
141 */
142static int run_bench(const char *coll_name, const char *bench_name, bench_fn_t fn,
143 int argc, const char **argv, const char *prefix)
163{ 144{
164 int i; 145 int size;
146 char *name;
147 int ret;
148
149 size = strlen(coll_name) + 1 + strlen(bench_name) + 1;
150
151 name = zalloc(size);
152 BUG_ON(!name);
153
154 scnprintf(name, size, "%s-%s", coll_name, bench_name);
155
156 prctl(PR_SET_NAME, name);
157 argv[0] = name;
158
159 ret = fn(argc, argv, prefix);
160
161 free(name);
162
163 return ret;
164}
165
166static void run_collection(struct collection *coll)
167{
168 struct bench *bench;
165 const char *argv[2]; 169 const char *argv[2];
166 struct bench_suite *suites = subsys->suites;
167 170
168 argv[1] = NULL; 171 argv[1] = NULL;
169 /* 172 /*
170 * TODO: 173 * TODO:
171 * preparing preset parameters for 174 *
175 * Preparing preset parameters for
172 * embedded, ordinary PC, HPC, etc... 176 * embedded, ordinary PC, HPC, etc...
173 * will be helpful 177 * would be helpful.
174 */ 178 */
175 for (i = 0; suites[i].fn; i++) { 179 for_each_bench(coll, bench) {
176 printf("# Running %s/%s benchmark...\n", 180 if (!bench->fn)
177 subsys->name, 181 break;
178 suites[i].name); 182 printf("# Running %s/%s benchmark...\n", coll->name, bench->name);
179 fflush(stdout); 183 fflush(stdout);
180 184
181 argv[1] = suites[i].name; 185 argv[1] = bench->name;
182 suites[i].fn(1, argv, NULL); 186 run_bench(coll->name, bench->name, bench->fn, 1, argv, NULL);
183 printf("\n"); 187 printf("\n");
184 } 188 }
185} 189}
186 190
187static void all_subsystem(void) 191static void run_all_collections(void)
188{ 192{
189 int i; 193 struct collection *coll;
190 for (i = 0; subsystems[i].suites; i++) 194
191 all_suite(&subsystems[i]); 195 for_each_collection(coll)
196 run_collection(coll);
192} 197}
193 198
194int cmd_bench(int argc, const char **argv, const char *prefix __maybe_unused) 199int cmd_bench(int argc, const char **argv, const char *prefix __maybe_unused)
195{ 200{
196 int i, j, status = 0; 201 struct collection *coll;
202 int ret = 0;
197 203
198 if (argc < 2) { 204 if (argc < 2) {
199 /* No subsystem specified. */ 205 /* No collection specified. */
200 print_usage(); 206 print_usage();
201 goto end; 207 goto end;
202 } 208 }
@@ -206,7 +212,7 @@ int cmd_bench(int argc, const char **argv, const char *prefix __maybe_unused)
206 212
207 bench_format = bench_str2int(bench_format_str); 213 bench_format = bench_str2int(bench_format_str);
208 if (bench_format == BENCH_FORMAT_UNKNOWN) { 214 if (bench_format == BENCH_FORMAT_UNKNOWN) {
209 printf("Unknown format descriptor:%s\n", bench_format_str); 215 printf("Unknown format descriptor: '%s'\n", bench_format_str);
210 goto end; 216 goto end;
211 } 217 }
212 218
@@ -216,52 +222,51 @@ int cmd_bench(int argc, const char **argv, const char *prefix __maybe_unused)
216 } 222 }
217 223
218 if (!strcmp(argv[0], "all")) { 224 if (!strcmp(argv[0], "all")) {
219 all_subsystem(); 225 run_all_collections();
220 goto end; 226 goto end;
221 } 227 }
222 228
223 for (i = 0; subsystems[i].name; i++) { 229 for_each_collection(coll) {
224 if (strcmp(subsystems[i].name, argv[0])) 230 struct bench *bench;
231
232 if (strcmp(coll->name, argv[0]))
225 continue; 233 continue;
226 234
227 if (argc < 2) { 235 if (argc < 2) {
228 /* No suite specified. */ 236 /* No bench specified. */
229 dump_suites(i); 237 dump_benchmarks(coll);
230 goto end; 238 goto end;
231 } 239 }
232 240
233 if (!strcmp(argv[1], "all")) { 241 if (!strcmp(argv[1], "all")) {
234 all_suite(&subsystems[i]); 242 run_collection(coll);
235 goto end; 243 goto end;
236 } 244 }
237 245
238 for (j = 0; subsystems[i].suites[j].name; j++) { 246 for_each_bench(coll, bench) {
239 if (strcmp(subsystems[i].suites[j].name, argv[1])) 247 if (strcmp(bench->name, argv[1]))
240 continue; 248 continue;
241 249
242 if (bench_format == BENCH_FORMAT_DEFAULT) 250 if (bench_format == BENCH_FORMAT_DEFAULT)
243 printf("# Running %s/%s benchmark...\n", 251 printf("# Running '%s/%s' benchmark:\n", coll->name, bench->name);
244 subsystems[i].name,
245 subsystems[i].suites[j].name);
246 fflush(stdout); 252 fflush(stdout);
247 status = subsystems[i].suites[j].fn(argc - 1, 253 ret = run_bench(coll->name, bench->name, bench->fn, argc-1, argv+1, prefix);
248 argv + 1, prefix);
249 goto end; 254 goto end;
250 } 255 }
251 256
252 if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) { 257 if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
253 dump_suites(i); 258 dump_benchmarks(coll);
254 goto end; 259 goto end;
255 } 260 }
256 261
257 printf("Unknown suite:%s for %s\n", argv[1], argv[0]); 262 printf("Unknown benchmark: '%s' for collection '%s'\n", argv[1], argv[0]);
258 status = 1; 263 ret = 1;
259 goto end; 264 goto end;
260 } 265 }
261 266
262 printf("Unknown subsystem:%s\n", argv[0]); 267 printf("Unknown collection: '%s'\n", argv[0]);
263 status = 1; 268 ret = 1;
264 269
265end: 270end:
266 return status; 271 return ret;
267} 272}
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 419d27dd708b..b605009e803f 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -303,12 +303,11 @@ static int formula_fprintf(struct hist_entry *he, struct hist_entry *pair,
303 return -1; 303 return -1;
304} 304}
305 305
306static int hists__add_entry(struct hists *self, 306static int hists__add_entry(struct hists *hists,
307 struct addr_location *al, u64 period, 307 struct addr_location *al, u64 period,
308 u64 weight, u64 transaction) 308 u64 weight, u64 transaction)
309{ 309{
310 if (__hists__add_entry(self, al, NULL, period, weight, transaction) 310 if (__hists__add_entry(hists, al, NULL, period, weight, transaction) != NULL)
311 != NULL)
312 return 0; 311 return 0;
313 return -ENOMEM; 312 return -ENOMEM;
314} 313}
@@ -370,7 +369,7 @@ static void perf_evlist__collapse_resort(struct perf_evlist *evlist)
370 list_for_each_entry(evsel, &evlist->entries, node) { 369 list_for_each_entry(evsel, &evlist->entries, node) {
371 struct hists *hists = &evsel->hists; 370 struct hists *hists = &evsel->hists;
372 371
373 hists__collapse_resort(hists); 372 hists__collapse_resort(hists, NULL);
374 } 373 }
375} 374}
376 375
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 4aa6d7850bcc..409ceaf3b9b9 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -72,12 +72,17 @@ static int perf_event__repipe_attr(struct perf_tool *tool,
72 union perf_event *event, 72 union perf_event *event,
73 struct perf_evlist **pevlist) 73 struct perf_evlist **pevlist)
74{ 74{
75 struct perf_inject *inject = container_of(tool, struct perf_inject,
76 tool);
75 int ret; 77 int ret;
76 78
77 ret = perf_event__process_attr(tool, event, pevlist); 79 ret = perf_event__process_attr(tool, event, pevlist);
78 if (ret) 80 if (ret)
79 return ret; 81 return ret;
80 82
83 if (!inject->pipe_output)
84 return 0;
85
81 return perf_event__repipe_synth(tool, event); 86 return perf_event__repipe_synth(tool, event);
82} 87}
83 88
@@ -162,38 +167,38 @@ static int perf_event__repipe_tracing_data(struct perf_tool *tool,
162 return err; 167 return err;
163} 168}
164 169
165static int dso__read_build_id(struct dso *self) 170static int dso__read_build_id(struct dso *dso)
166{ 171{
167 if (self->has_build_id) 172 if (dso->has_build_id)
168 return 0; 173 return 0;
169 174
170 if (filename__read_build_id(self->long_name, self->build_id, 175 if (filename__read_build_id(dso->long_name, dso->build_id,
171 sizeof(self->build_id)) > 0) { 176 sizeof(dso->build_id)) > 0) {
172 self->has_build_id = true; 177 dso->has_build_id = true;
173 return 0; 178 return 0;
174 } 179 }
175 180
176 return -1; 181 return -1;
177} 182}
178 183
179static int dso__inject_build_id(struct dso *self, struct perf_tool *tool, 184static int dso__inject_build_id(struct dso *dso, struct perf_tool *tool,
180 struct machine *machine) 185 struct machine *machine)
181{ 186{
182 u16 misc = PERF_RECORD_MISC_USER; 187 u16 misc = PERF_RECORD_MISC_USER;
183 int err; 188 int err;
184 189
185 if (dso__read_build_id(self) < 0) { 190 if (dso__read_build_id(dso) < 0) {
186 pr_debug("no build_id found for %s\n", self->long_name); 191 pr_debug("no build_id found for %s\n", dso->long_name);
187 return -1; 192 return -1;
188 } 193 }
189 194
190 if (self->kernel) 195 if (dso->kernel)
191 misc = PERF_RECORD_MISC_KERNEL; 196 misc = PERF_RECORD_MISC_KERNEL;
192 197
193 err = perf_event__synthesize_build_id(tool, self, misc, perf_event__repipe, 198 err = perf_event__synthesize_build_id(tool, dso, misc, perf_event__repipe,
194 machine); 199 machine);
195 if (err) { 200 if (err) {
196 pr_err("Can't synthesize build_id event for %s\n", self->long_name); 201 pr_err("Can't synthesize build_id event for %s\n", dso->long_name);
197 return -1; 202 return -1;
198 } 203 }
199 204
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 81addcabb356..98d3891392e2 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -373,9 +373,9 @@ static int process_read_event(struct perf_tool *tool,
373/* For pipe mode, sample_type is not currently set */ 373/* For pipe mode, sample_type is not currently set */
374static int perf_report__setup_sample_type(struct perf_report *rep) 374static int perf_report__setup_sample_type(struct perf_report *rep)
375{ 375{
376 struct perf_session *self = rep->session; 376 struct perf_session *session = rep->session;
377 u64 sample_type = perf_evlist__combined_sample_type(self->evlist); 377 u64 sample_type = perf_evlist__combined_sample_type(session->evlist);
378 bool is_pipe = perf_data_file__is_pipe(self->file); 378 bool is_pipe = perf_data_file__is_pipe(session->file);
379 379
380 if (!is_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) { 380 if (!is_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) {
381 if (sort__has_parent) { 381 if (sort__has_parent) {
@@ -417,14 +417,14 @@ static void sig_handler(int sig __maybe_unused)
417} 417}
418 418
419static size_t hists__fprintf_nr_sample_events(struct perf_report *rep, 419static size_t hists__fprintf_nr_sample_events(struct perf_report *rep,
420 struct hists *self, 420 struct hists *hists,
421 const char *evname, FILE *fp) 421 const char *evname, FILE *fp)
422{ 422{
423 size_t ret; 423 size_t ret;
424 char unit; 424 char unit;
425 unsigned long nr_samples = self->stats.nr_events[PERF_RECORD_SAMPLE]; 425 unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];
426 u64 nr_events = self->stats.total_period; 426 u64 nr_events = hists->stats.total_period;
427 struct perf_evsel *evsel = hists_to_evsel(self); 427 struct perf_evsel *evsel = hists_to_evsel(hists);
428 char buf[512]; 428 char buf[512];
429 size_t size = sizeof(buf); 429 size_t size = sizeof(buf);
430 430
@@ -496,6 +496,7 @@ static int __cmd_report(struct perf_report *rep)
496 struct map *kernel_map; 496 struct map *kernel_map;
497 struct kmap *kernel_kmap; 497 struct kmap *kernel_kmap;
498 const char *help = "For a higher level overview, try: perf report --sort comm,dso"; 498 const char *help = "For a higher level overview, try: perf report --sort comm,dso";
499 struct ui_progress prog;
499 struct perf_data_file *file = session->file; 500 struct perf_data_file *file = session->file;
500 501
501 signal(SIGINT, sig_handler); 502 signal(SIGINT, sig_handler);
@@ -558,13 +559,19 @@ static int __cmd_report(struct perf_report *rep)
558 } 559 }
559 560
560 nr_samples = 0; 561 nr_samples = 0;
562 list_for_each_entry(pos, &session->evlist->entries, node)
563 nr_samples += pos->hists.nr_entries;
564
565 ui_progress__init(&prog, nr_samples, "Merging related events...");
566
567 nr_samples = 0;
561 list_for_each_entry(pos, &session->evlist->entries, node) { 568 list_for_each_entry(pos, &session->evlist->entries, node) {
562 struct hists *hists = &pos->hists; 569 struct hists *hists = &pos->hists;
563 570
564 if (pos->idx == 0) 571 if (pos->idx == 0)
565 hists->symbol_filter_str = rep->symbol_filter_str; 572 hists->symbol_filter_str = rep->symbol_filter_str;
566 573
567 hists__collapse_resort(hists); 574 hists__collapse_resort(hists, &prog);
568 nr_samples += hists->stats.nr_events[PERF_RECORD_SAMPLE]; 575 nr_samples += hists->stats.nr_events[PERF_RECORD_SAMPLE];
569 576
570 /* Non-group events are considered as leader */ 577 /* Non-group events are considered as leader */
@@ -576,6 +583,7 @@ static int __cmd_report(struct perf_report *rep)
576 hists__link(leader_hists, hists); 583 hists__link(leader_hists, hists);
577 } 584 }
578 } 585 }
586 ui_progress__finish();
579 587
580 if (session_done()) 588 if (session_done())
581 return 0; 589 return 0;
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 5a46b102eb08..ddb5dc15be17 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1655,29 +1655,27 @@ static int __cmd_record(int argc, const char **argv)
1655 return cmd_record(i, rec_argv, NULL); 1655 return cmd_record(i, rec_argv, NULL);
1656} 1656}
1657 1657
1658static const char default_sort_order[] = "avg, max, switch, runtime";
1659static struct perf_sched sched = {
1660 .tool = {
1661 .sample = perf_sched__process_tracepoint_sample,
1662 .comm = perf_event__process_comm,
1663 .lost = perf_event__process_lost,
1664 .fork = perf_sched__process_fork_event,
1665 .ordered_samples = true,
1666 },
1667 .cmp_pid = LIST_HEAD_INIT(sched.cmp_pid),
1668 .sort_list = LIST_HEAD_INIT(sched.sort_list),
1669 .start_work_mutex = PTHREAD_MUTEX_INITIALIZER,
1670 .work_done_wait_mutex = PTHREAD_MUTEX_INITIALIZER,
1671 .curr_pid = { [0 ... MAX_CPUS - 1] = -1 },
1672 .sort_order = default_sort_order,
1673 .replay_repeat = 10,
1674 .profile_cpu = -1,
1675 .next_shortname1 = 'A',
1676 .next_shortname2 = '0',
1677};
1678
1679int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused) 1658int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
1680{ 1659{
1660 const char default_sort_order[] = "avg, max, switch, runtime";
1661 struct perf_sched sched = {
1662 .tool = {
1663 .sample = perf_sched__process_tracepoint_sample,
1664 .comm = perf_event__process_comm,
1665 .lost = perf_event__process_lost,
1666 .fork = perf_sched__process_fork_event,
1667 .ordered_samples = true,
1668 },
1669 .cmp_pid = LIST_HEAD_INIT(sched.cmp_pid),
1670 .sort_list = LIST_HEAD_INIT(sched.sort_list),
1671 .start_work_mutex = PTHREAD_MUTEX_INITIALIZER,
1672 .work_done_wait_mutex = PTHREAD_MUTEX_INITIALIZER,
1673 .sort_order = default_sort_order,
1674 .replay_repeat = 10,
1675 .profile_cpu = -1,
1676 .next_shortname1 = 'A',
1677 .next_shortname2 = '0',
1678 };
1681 const struct option latency_options[] = { 1679 const struct option latency_options[] = {
1682 OPT_STRING('s', "sort", &sched.sort_order, "key[,key2...]", 1680 OPT_STRING('s', "sort", &sched.sort_order, "key[,key2...]",
1683 "sort by key(s): runtime, switch, avg, max"), 1681 "sort by key(s): runtime, switch, avg, max"),
@@ -1733,6 +1731,10 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
1733 .switch_event = replay_switch_event, 1731 .switch_event = replay_switch_event,
1734 .fork_event = replay_fork_event, 1732 .fork_event = replay_fork_event,
1735 }; 1733 };
1734 unsigned int i;
1735
1736 for (i = 0; i < ARRAY_SIZE(sched.curr_pid); i++)
1737 sched.curr_pid[i] = -1;
1736 1738
1737 argc = parse_options(argc, argv, sched_options, sched_usage, 1739 argc = parse_options(argc, argv, sched_options, sched_usage,
1738 PARSE_OPT_STOP_AT_NON_OPTION); 1740 PARSE_OPT_STOP_AT_NON_OPTION);
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 27de6068049d..0ae88c2538a1 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -542,18 +542,9 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
542 return 0; 542 return 0;
543} 543}
544 544
545static struct perf_tool perf_script = { 545struct perf_script {
546 .sample = process_sample_event, 546 struct perf_tool tool;
547 .mmap = perf_event__process_mmap, 547 struct perf_session *session;
548 .mmap2 = perf_event__process_mmap2,
549 .comm = perf_event__process_comm,
550 .exit = perf_event__process_exit,
551 .fork = perf_event__process_fork,
552 .attr = perf_event__process_attr,
553 .tracing_data = perf_event__process_tracing_data,
554 .build_id = perf_event__process_build_id,
555 .ordered_samples = true,
556 .ordering_requires_timestamps = true,
557}; 548};
558 549
559static void sig_handler(int sig __maybe_unused) 550static void sig_handler(int sig __maybe_unused)
@@ -561,13 +552,13 @@ static void sig_handler(int sig __maybe_unused)
561 session_done = 1; 552 session_done = 1;
562} 553}
563 554
564static int __cmd_script(struct perf_session *session) 555static int __cmd_script(struct perf_script *script)
565{ 556{
566 int ret; 557 int ret;
567 558
568 signal(SIGINT, sig_handler); 559 signal(SIGINT, sig_handler);
569 560
570 ret = perf_session__process_events(session, &perf_script); 561 ret = perf_session__process_events(script->session, &script->tool);
571 562
572 if (debug_mode) 563 if (debug_mode)
573 pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered); 564 pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
@@ -1273,6 +1264,21 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1273 char *script_path = NULL; 1264 char *script_path = NULL;
1274 const char **__argv; 1265 const char **__argv;
1275 int i, j, err; 1266 int i, j, err;
1267 struct perf_script script = {
1268 .tool = {
1269 .sample = process_sample_event,
1270 .mmap = perf_event__process_mmap,
1271 .mmap2 = perf_event__process_mmap2,
1272 .comm = perf_event__process_comm,
1273 .exit = perf_event__process_exit,
1274 .fork = perf_event__process_fork,
1275 .attr = perf_event__process_attr,
1276 .tracing_data = perf_event__process_tracing_data,
1277 .build_id = perf_event__process_build_id,
1278 .ordered_samples = true,
1279 .ordering_requires_timestamps = true,
1280 },
1281 };
1276 const struct option options[] = { 1282 const struct option options[] = {
1277 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 1283 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
1278 "dump raw trace in ASCII"), 1284 "dump raw trace in ASCII"),
@@ -1498,10 +1504,12 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1498 if (!script_name) 1504 if (!script_name)
1499 setup_pager(); 1505 setup_pager();
1500 1506
1501 session = perf_session__new(&file, false, &perf_script); 1507 session = perf_session__new(&file, false, &script.tool);
1502 if (session == NULL) 1508 if (session == NULL)
1503 return -ENOMEM; 1509 return -ENOMEM;
1504 1510
1511 script.session = session;
1512
1505 if (cpu_list) { 1513 if (cpu_list) {
1506 if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap)) 1514 if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap))
1507 return -1; 1515 return -1;
@@ -1565,7 +1573,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1565 if (err < 0) 1573 if (err < 0)
1566 goto out; 1574 goto out;
1567 1575
1568 err = __cmd_script(session); 1576 err = __cmd_script(&script);
1569 1577
1570 perf_session__delete(session); 1578 perf_session__delete(session);
1571 cleanup_scripting(); 1579 cleanup_scripting();
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 386d83324a8d..76c9264ed070 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -286,7 +286,7 @@ static void perf_top__print_sym_table(struct perf_top *top)
286 return; 286 return;
287 } 287 }
288 288
289 hists__collapse_resort(&top->sym_evsel->hists); 289 hists__collapse_resort(&top->sym_evsel->hists, NULL);
290 hists__output_resort(&top->sym_evsel->hists); 290 hists__output_resort(&top->sym_evsel->hists);
291 hists__decay_entries(&top->sym_evsel->hists, 291 hists__decay_entries(&top->sym_evsel->hists,
292 top->hide_user_symbols, 292 top->hide_user_symbols,
@@ -552,7 +552,7 @@ static void perf_top__sort_new_samples(void *arg)
552 if (t->evlist->selected != NULL) 552 if (t->evlist->selected != NULL)
553 t->sym_evsel = t->evlist->selected; 553 t->sym_evsel = t->evlist->selected;
554 554
555 hists__collapse_resort(&t->sym_evsel->hists); 555 hists__collapse_resort(&t->sym_evsel->hists, NULL);
556 hists__output_resort(&t->sym_evsel->hists); 556 hists__output_resort(&t->sym_evsel->hists);
557 hists__decay_entries(&t->sym_evsel->hists, 557 hists__decay_entries(&t->sym_evsel->hists,
558 t->hide_user_symbols, 558 t->hide_user_symbols,
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index c516d6ba6716..543aa953bab1 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -66,6 +66,10 @@ ifneq ($(WERROR),0)
66 CFLAGS += -Werror 66 CFLAGS += -Werror
67endif 67endif
68 68
69ifndef DEBUG
70 DEBUG := 0
71endif
72
69ifeq ($(DEBUG),0) 73ifeq ($(DEBUG),0)
70 CFLAGS += -O6 74 CFLAGS += -O6
71endif 75endif
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c
index 025503a22ff7..b51abcb2c243 100644
--- a/tools/perf/tests/hists_link.c
+++ b/tools/perf/tests/hists_link.c
@@ -467,7 +467,7 @@ int test__hists_link(void)
467 goto out; 467 goto out;
468 468
469 list_for_each_entry(evsel, &evlist->entries, node) { 469 list_for_each_entry(evsel, &evlist->entries, node) {
470 hists__collapse_resort(&evsel->hists); 470 hists__collapse_resort(&evsel->hists, NULL);
471 471
472 if (verbose > 2) 472 if (verbose > 2)
473 print_hists(&evsel->hists); 473 print_hists(&evsel->hists);
diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c
index 77f598dbd97a..61c9da2eb3a9 100644
--- a/tools/perf/tests/sample-parsing.c
+++ b/tools/perf/tests/sample-parsing.c
@@ -275,8 +275,8 @@ int test__sample_parsing(void)
275 * Fail the test if it has not been updated when new sample format bits 275 * Fail the test if it has not been updated when new sample format bits
276 * were added. 276 * were added.
277 */ 277 */
278 if (PERF_SAMPLE_MAX > PERF_SAMPLE_IDENTIFIER << 1) { 278 if (PERF_SAMPLE_MAX > PERF_SAMPLE_TRANSACTION << 1) {
279 pr_debug("sample format has changed - test needs updating\n"); 279 pr_debug("sample format has changed, some new PERF_SAMPLE_ bit was introduced - test needs updating\n");
280 return -1; 280 return -1;
281 } 281 }
282 282
diff --git a/tools/perf/ui/gtk/gtk.h b/tools/perf/ui/gtk/gtk.h
index 8576cf194872..0a9173ff9a61 100644
--- a/tools/perf/ui/gtk/gtk.h
+++ b/tools/perf/ui/gtk/gtk.h
@@ -34,7 +34,7 @@ struct perf_gtk_context *perf_gtk__activate_context(GtkWidget *window);
34int perf_gtk__deactivate_context(struct perf_gtk_context **ctx); 34int perf_gtk__deactivate_context(struct perf_gtk_context **ctx);
35 35
36void perf_gtk__init_helpline(void); 36void perf_gtk__init_helpline(void);
37void perf_gtk__init_progress(void); 37void gtk_ui_progress__init(void);
38void perf_gtk__init_hpp(void); 38void perf_gtk__init_hpp(void);
39 39
40void perf_gtk__signal(int sig); 40void perf_gtk__signal(int sig);
diff --git a/tools/perf/ui/gtk/progress.c b/tools/perf/ui/gtk/progress.c
index 482bcf3df9b7..b656655fbc39 100644
--- a/tools/perf/ui/gtk/progress.c
+++ b/tools/perf/ui/gtk/progress.c
@@ -7,14 +7,14 @@
7static GtkWidget *dialog; 7static GtkWidget *dialog;
8static GtkWidget *progress; 8static GtkWidget *progress;
9 9
10static void gtk_progress_update(u64 curr, u64 total, const char *title) 10static void gtk_ui_progress__update(struct ui_progress *p)
11{ 11{
12 double fraction = total ? 1.0 * curr / total : 0.0; 12 double fraction = p->total ? 1.0 * p->curr / p->total : 0.0;
13 char buf[1024]; 13 char buf[1024];
14 14
15 if (dialog == NULL) { 15 if (dialog == NULL) {
16 GtkWidget *vbox = gtk_vbox_new(TRUE, 5); 16 GtkWidget *vbox = gtk_vbox_new(TRUE, 5);
17 GtkWidget *label = gtk_label_new(title); 17 GtkWidget *label = gtk_label_new(p->title);
18 18
19 dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); 19 dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
20 progress = gtk_progress_bar_new(); 20 progress = gtk_progress_bar_new();
@@ -32,7 +32,7 @@ static void gtk_progress_update(u64 curr, u64 total, const char *title)
32 } 32 }
33 33
34 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), fraction); 34 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), fraction);
35 snprintf(buf, sizeof(buf), "%"PRIu64" / %"PRIu64, curr, total); 35 snprintf(buf, sizeof(buf), "%"PRIu64" / %"PRIu64, p->curr, p->total);
36 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress), buf); 36 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress), buf);
37 37
38 /* we didn't call gtk_main yet, so do it manually */ 38 /* we didn't call gtk_main yet, so do it manually */
@@ -40,7 +40,7 @@ static void gtk_progress_update(u64 curr, u64 total, const char *title)
40 gtk_main_iteration(); 40 gtk_main_iteration();
41} 41}
42 42
43static void gtk_progress_finish(void) 43static void gtk_ui_progress__finish(void)
44{ 44{
45 /* this will also destroy all of its children */ 45 /* this will also destroy all of its children */
46 gtk_widget_destroy(dialog); 46 gtk_widget_destroy(dialog);
@@ -48,12 +48,12 @@ static void gtk_progress_finish(void)
48 dialog = NULL; 48 dialog = NULL;
49} 49}
50 50
51static struct ui_progress gtk_progress_fns = { 51static struct ui_progress_ops gtk_ui_progress__ops = {
52 .update = gtk_progress_update, 52 .update = gtk_ui_progress__update,
53 .finish = gtk_progress_finish, 53 .finish = gtk_ui_progress__finish,
54}; 54};
55 55
56void perf_gtk__init_progress(void) 56void gtk_ui_progress__init(void)
57{ 57{
58 progress_fns = &gtk_progress_fns; 58 ui_progress__ops = &gtk_ui_progress__ops;
59} 59}
diff --git a/tools/perf/ui/gtk/setup.c b/tools/perf/ui/gtk/setup.c
index 6c2dd2e423f3..1d57676f8212 100644
--- a/tools/perf/ui/gtk/setup.c
+++ b/tools/perf/ui/gtk/setup.c
@@ -8,7 +8,7 @@ int perf_gtk__init(void)
8{ 8{
9 perf_error__register(&perf_gtk_eops); 9 perf_error__register(&perf_gtk_eops);
10 perf_gtk__init_helpline(); 10 perf_gtk__init_helpline();
11 perf_gtk__init_progress(); 11 gtk_ui_progress__init();
12 perf_gtk__init_hpp(); 12 perf_gtk__init_hpp();
13 13
14 return gtk_init_check(NULL, NULL) ? 0 : -1; 14 return gtk_init_check(NULL, NULL) ? 0 : -1;
diff --git a/tools/perf/ui/progress.c b/tools/perf/ui/progress.c
index 3ec695607a4d..a0f24c7115c5 100644
--- a/tools/perf/ui/progress.c
+++ b/tools/perf/ui/progress.c
@@ -1,26 +1,38 @@
1#include "../cache.h" 1#include "../cache.h"
2#include "progress.h" 2#include "progress.h"
3 3
4static void nop_progress_update(u64 curr __maybe_unused, 4static void null_progress__update(struct ui_progress *p __maybe_unused)
5 u64 total __maybe_unused,
6 const char *title __maybe_unused)
7{ 5{
8} 6}
9 7
10static struct ui_progress default_progress_fns = 8static struct ui_progress_ops null_progress__ops =
11{ 9{
12 .update = nop_progress_update, 10 .update = null_progress__update,
13}; 11};
14 12
15struct ui_progress *progress_fns = &default_progress_fns; 13struct ui_progress_ops *ui_progress__ops = &null_progress__ops;
16 14
17void ui_progress__update(u64 curr, u64 total, const char *title) 15void ui_progress__update(struct ui_progress *p, u64 adv)
18{ 16{
19 return progress_fns->update(curr, total, title); 17 p->curr += adv;
18
19 if (p->curr >= p->next) {
20 p->next += p->step;
21 ui_progress__ops->update(p);
22 }
23}
24
25void ui_progress__init(struct ui_progress *p, u64 total, const char *title)
26{
27 p->curr = 0;
28 p->next = p->step = total / 16;
29 p->total = total;
30 p->title = title;
31
20} 32}
21 33
22void ui_progress__finish(void) 34void ui_progress__finish(void)
23{ 35{
24 if (progress_fns->finish) 36 if (ui_progress__ops->finish)
25 progress_fns->finish(); 37 ui_progress__ops->finish();
26} 38}
diff --git a/tools/perf/ui/progress.h b/tools/perf/ui/progress.h
index 257cc224f9cf..29ec8efffefb 100644
--- a/tools/perf/ui/progress.h
+++ b/tools/perf/ui/progress.h
@@ -3,16 +3,21 @@
3 3
4#include <../types.h> 4#include <../types.h>
5 5
6void ui_progress__finish(void);
7
6struct ui_progress { 8struct ui_progress {
7 void (*update)(u64, u64, const char *); 9 const char *title;
8 void (*finish)(void); 10 u64 curr, next, step, total;
9}; 11};
12
13void ui_progress__init(struct ui_progress *p, u64 total, const char *title);
14void ui_progress__update(struct ui_progress *p, u64 adv);
10 15
11extern struct ui_progress *progress_fns; 16struct ui_progress_ops {
12 17 void (*update)(struct ui_progress *p);
13void ui_progress__init(void); 18 void (*finish)(void);
19};
14 20
15void ui_progress__update(u64 curr, u64 total, const char *title); 21extern struct ui_progress_ops *ui_progress__ops;
16void ui_progress__finish(void);
17 22
18#endif 23#endif
diff --git a/tools/perf/ui/tui/progress.c b/tools/perf/ui/tui/progress.c
index 6c2184d53cbf..3e2d936d7443 100644
--- a/tools/perf/ui/tui/progress.c
+++ b/tools/perf/ui/tui/progress.c
@@ -2,9 +2,10 @@
2#include "../progress.h" 2#include "../progress.h"
3#include "../libslang.h" 3#include "../libslang.h"
4#include "../ui.h" 4#include "../ui.h"
5#include "tui.h"
5#include "../browser.h" 6#include "../browser.h"
6 7
7static void tui_progress__update(u64 curr, u64 total, const char *title) 8static void tui_progress__update(struct ui_progress *p)
8{ 9{
9 int bar, y; 10 int bar, y;
10 /* 11 /*
@@ -14,7 +15,7 @@ static void tui_progress__update(u64 curr, u64 total, const char *title)
14 if (use_browser <= 0) 15 if (use_browser <= 0)
15 return; 16 return;
16 17
17 if (total == 0) 18 if (p->total == 0)
18 return; 19 return;
19 20
20 ui__refresh_dimensions(true); 21 ui__refresh_dimensions(true);
@@ -23,20 +24,20 @@ static void tui_progress__update(u64 curr, u64 total, const char *title)
23 SLsmg_set_color(0); 24 SLsmg_set_color(0);
24 SLsmg_draw_box(y, 0, 3, SLtt_Screen_Cols); 25 SLsmg_draw_box(y, 0, 3, SLtt_Screen_Cols);
25 SLsmg_gotorc(y++, 1); 26 SLsmg_gotorc(y++, 1);
26 SLsmg_write_string((char *)title); 27 SLsmg_write_string((char *)p->title);
27 SLsmg_set_color(HE_COLORSET_SELECTED); 28 SLsmg_set_color(HE_COLORSET_SELECTED);
28 bar = ((SLtt_Screen_Cols - 2) * curr) / total; 29 bar = ((SLtt_Screen_Cols - 2) * p->curr) / p->total;
29 SLsmg_fill_region(y, 1, 1, bar, ' '); 30 SLsmg_fill_region(y, 1, 1, bar, ' ');
30 SLsmg_refresh(); 31 SLsmg_refresh();
31 pthread_mutex_unlock(&ui__lock); 32 pthread_mutex_unlock(&ui__lock);
32} 33}
33 34
34static struct ui_progress tui_progress_fns = 35static struct ui_progress_ops tui_progress__ops =
35{ 36{
36 .update = tui_progress__update, 37 .update = tui_progress__update,
37}; 38};
38 39
39void ui_progress__init(void) 40void tui_progress__init(void)
40{ 41{
41 progress_fns = &tui_progress_fns; 42 ui_progress__ops = &tui_progress__ops;
42} 43}
diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c
index b9401482d110..2f612562978c 100644
--- a/tools/perf/ui/tui/setup.c
+++ b/tools/perf/ui/tui/setup.c
@@ -9,6 +9,7 @@
9#include "../util.h" 9#include "../util.h"
10#include "../libslang.h" 10#include "../libslang.h"
11#include "../keysyms.h" 11#include "../keysyms.h"
12#include "tui.h"
12 13
13static volatile int ui__need_resize; 14static volatile int ui__need_resize;
14 15
@@ -119,7 +120,7 @@ int ui__init(void)
119 120
120 ui_helpline__init(); 121 ui_helpline__init();
121 ui_browser__init(); 122 ui_browser__init();
122 ui_progress__init(); 123 tui_progress__init();
123 124
124 signal(SIGSEGV, ui__signal); 125 signal(SIGSEGV, ui__signal);
125 signal(SIGFPE, ui__signal); 126 signal(SIGFPE, ui__signal);
diff --git a/tools/perf/ui/tui/tui.h b/tools/perf/ui/tui/tui.h
new file mode 100644
index 000000000000..18961c7b6ec5
--- /dev/null
+++ b/tools/perf/ui/tui/tui.h
@@ -0,0 +1,6 @@
1#ifndef _PERF_TUI_H_
2#define _PERF_TUI_H_ 1
3
4void tui_progress__init(void);
5
6#endif /* _PERF_TUI_H_ */
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 7ded71d19d75..a92770c98cc7 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -89,14 +89,14 @@ int build_id__sprintf(const u8 *build_id, int len, char *bf)
89 return raw - build_id; 89 return raw - build_id;
90} 90}
91 91
92char *dso__build_id_filename(struct dso *self, char *bf, size_t size) 92char *dso__build_id_filename(struct dso *dso, char *bf, size_t size)
93{ 93{
94 char build_id_hex[BUILD_ID_SIZE * 2 + 1]; 94 char build_id_hex[BUILD_ID_SIZE * 2 + 1];
95 95
96 if (!self->has_build_id) 96 if (!dso->has_build_id)
97 return NULL; 97 return NULL;
98 98
99 build_id__sprintf(self->build_id, sizeof(self->build_id), build_id_hex); 99 build_id__sprintf(dso->build_id, sizeof(dso->build_id), build_id_hex);
100 if (bf == NULL) { 100 if (bf == NULL) {
101 if (asprintf(&bf, "%s/.build-id/%.2s/%s", buildid_dir, 101 if (asprintf(&bf, "%s/.build-id/%.2s/%s", buildid_dir,
102 build_id_hex, build_id_hex + 2) < 0) 102 build_id_hex, build_id_hex + 2) < 0)
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 85c4c80bcac8..2ce92eceb424 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -698,7 +698,8 @@ static size_t perf_evlist__mmap_size(unsigned long pages)
698int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str, 698int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str,
699 int unset __maybe_unused) 699 int unset __maybe_unused)
700{ 700{
701 unsigned int pages, val, *mmap_pages = opt->value; 701 unsigned int *mmap_pages = opt->value;
702 unsigned long pages, val;
702 size_t size; 703 size_t size;
703 static struct parse_tag tags[] = { 704 static struct parse_tag tags[] = {
704 { .tag = 'B', .mult = 1 }, 705 { .tag = 'B', .mult = 1 },
@@ -709,12 +710,12 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str,
709 }; 710 };
710 711
711 val = parse_tag_value(str, tags); 712 val = parse_tag_value(str, tags);
712 if (val != (unsigned int) -1) { 713 if (val != (unsigned long) -1) {
713 /* we got file size value */ 714 /* we got file size value */
714 pages = PERF_ALIGN(val, page_size) / page_size; 715 pages = PERF_ALIGN(val, page_size) / page_size;
715 if (!is_power_of_2(pages)) { 716 if (pages < (1UL << 31) && !is_power_of_2(pages)) {
716 pages = next_pow2(pages); 717 pages = next_pow2(pages);
717 pr_info("rounding mmap pages size to %u (%u pages)\n", 718 pr_info("rounding mmap pages size to %lu (%lu pages)\n",
718 pages * page_size, pages); 719 pages * page_size, pages);
719 } 720 }
720 } else { 721 } else {
@@ -727,6 +728,11 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str,
727 } 728 }
728 } 729 }
729 730
731 if (pages > UINT_MAX || pages > SIZE_MAX / page_size) {
732 pr_err("--mmap_pages/-m value too big\n");
733 return -1;
734 }
735
730 size = perf_evlist__mmap_size(pages); 736 size = perf_evlist__mmap_size(pages);
731 if (!size) { 737 if (!size) {
732 pr_err("--mmap_pages/-m value must be a power of two."); 738 pr_err("--mmap_pages/-m value must be a power of two.");
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index cca03831f41a..7e80253074b0 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -399,6 +399,7 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
399 if (!he) 399 if (!he)
400 return NULL; 400 return NULL;
401 401
402 hists->nr_entries++;
402 rb_link_node(&he->rb_node_in, parent, p); 403 rb_link_node(&he->rb_node_in, parent, p);
403 rb_insert_color(&he->rb_node_in, hists->entries_in); 404 rb_insert_color(&he->rb_node_in, hists->entries_in);
404out: 405out:
@@ -406,7 +407,7 @@ out:
406 return he; 407 return he;
407} 408}
408 409
409struct hist_entry *__hists__add_mem_entry(struct hists *self, 410struct hist_entry *__hists__add_mem_entry(struct hists *hists,
410 struct addr_location *al, 411 struct addr_location *al,
411 struct symbol *sym_parent, 412 struct symbol *sym_parent,
412 struct mem_info *mi, 413 struct mem_info *mi,
@@ -429,14 +430,14 @@ struct hist_entry *__hists__add_mem_entry(struct hists *self,
429 .level = al->level, 430 .level = al->level,
430 .parent = sym_parent, 431 .parent = sym_parent,
431 .filtered = symbol__parent_filter(sym_parent), 432 .filtered = symbol__parent_filter(sym_parent),
432 .hists = self, 433 .hists = hists,
433 .mem_info = mi, 434 .mem_info = mi,
434 .branch_info = NULL, 435 .branch_info = NULL,
435 }; 436 };
436 return add_hist_entry(self, &entry, al, period, weight); 437 return add_hist_entry(hists, &entry, al, period, weight);
437} 438}
438 439
439struct hist_entry *__hists__add_branch_entry(struct hists *self, 440struct hist_entry *__hists__add_branch_entry(struct hists *hists,
440 struct addr_location *al, 441 struct addr_location *al,
441 struct symbol *sym_parent, 442 struct symbol *sym_parent,
442 struct branch_info *bi, 443 struct branch_info *bi,
@@ -460,14 +461,14 @@ struct hist_entry *__hists__add_branch_entry(struct hists *self,
460 .parent = sym_parent, 461 .parent = sym_parent,
461 .filtered = symbol__parent_filter(sym_parent), 462 .filtered = symbol__parent_filter(sym_parent),
462 .branch_info = bi, 463 .branch_info = bi,
463 .hists = self, 464 .hists = hists,
464 .mem_info = NULL, 465 .mem_info = NULL,
465 }; 466 };
466 467
467 return add_hist_entry(self, &entry, al, period, weight); 468 return add_hist_entry(hists, &entry, al, period, weight);
468} 469}
469 470
470struct hist_entry *__hists__add_entry(struct hists *self, 471struct hist_entry *__hists__add_entry(struct hists *hists,
471 struct addr_location *al, 472 struct addr_location *al,
472 struct symbol *sym_parent, u64 period, 473 struct symbol *sym_parent, u64 period,
473 u64 weight, u64 transaction) 474 u64 weight, u64 transaction)
@@ -488,13 +489,13 @@ struct hist_entry *__hists__add_entry(struct hists *self,
488 }, 489 },
489 .parent = sym_parent, 490 .parent = sym_parent,
490 .filtered = symbol__parent_filter(sym_parent), 491 .filtered = symbol__parent_filter(sym_parent),
491 .hists = self, 492 .hists = hists,
492 .branch_info = NULL, 493 .branch_info = NULL,
493 .mem_info = NULL, 494 .mem_info = NULL,
494 .transaction = transaction, 495 .transaction = transaction,
495 }; 496 };
496 497
497 return add_hist_entry(self, &entry, al, period, weight); 498 return add_hist_entry(hists, &entry, al, period, weight);
498} 499}
499 500
500int64_t 501int64_t
@@ -604,7 +605,7 @@ static void hists__apply_filters(struct hists *hists, struct hist_entry *he)
604 hists__filter_entry_by_symbol(hists, he); 605 hists__filter_entry_by_symbol(hists, he);
605} 606}
606 607
607void hists__collapse_resort(struct hists *hists) 608void hists__collapse_resort(struct hists *hists, struct ui_progress *prog)
608{ 609{
609 struct rb_root *root; 610 struct rb_root *root;
610 struct rb_node *next; 611 struct rb_node *next;
@@ -631,6 +632,8 @@ void hists__collapse_resort(struct hists *hists)
631 */ 632 */
632 hists__apply_filters(hists, n); 633 hists__apply_filters(hists, n);
633 } 634 }
635 if (prog)
636 ui_progress__update(prog, 1);
634 } 637 }
635} 638}
636 639
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 20b175808cd3..0c7ce8bb8eba 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -5,6 +5,7 @@
5#include <pthread.h> 5#include <pthread.h>
6#include "callchain.h" 6#include "callchain.h"
7#include "header.h" 7#include "header.h"
8#include "ui/progress.h"
8 9
9extern struct callchain_param callchain_param; 10extern struct callchain_param callchain_param;
10 11
@@ -108,7 +109,7 @@ struct hist_entry *__hists__add_mem_entry(struct hists *self,
108 u64 weight); 109 u64 weight);
109 110
110void hists__output_resort(struct hists *self); 111void hists__output_resort(struct hists *self);
111void hists__collapse_resort(struct hists *self); 112void hists__collapse_resort(struct hists *self, struct ui_progress *prog);
112 113
113void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel); 114void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel);
114void hists__output_recalc_col_len(struct hists *hists, int max_rows); 115void hists__output_recalc_col_len(struct hists *hists, int max_rows);
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 779b2dacd43f..9c6989ca2bea 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -47,7 +47,6 @@
47#include "session.h" 47#include "session.h"
48 48
49#define MAX_CMDLEN 256 49#define MAX_CMDLEN 256
50#define MAX_PROBE_ARGS 128
51#define PERFPROBE_GROUP "probe" 50#define PERFPROBE_GROUP "probe"
52 51
53bool probe_event_dry_run; /* Dry run flag */ 52bool probe_event_dry_run; /* Dry run flag */
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index c09e0a9fdf4c..c04405296e5b 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -273,12 +273,15 @@ static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs)
273/* 273/*
274 * Convert a location into trace_arg. 274 * Convert a location into trace_arg.
275 * If tvar == NULL, this just checks variable can be converted. 275 * If tvar == NULL, this just checks variable can be converted.
276 * If fentry == true and vr_die is a parameter, do huristic search
277 * for the location fuzzed by function entry mcount.
276 */ 278 */
277static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr, 279static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
278 Dwarf_Op *fb_ops, 280 Dwarf_Op *fb_ops, Dwarf_Die *sp_die,
279 struct probe_trace_arg *tvar) 281 struct probe_trace_arg *tvar)
280{ 282{
281 Dwarf_Attribute attr; 283 Dwarf_Attribute attr;
284 Dwarf_Addr tmp = 0;
282 Dwarf_Op *op; 285 Dwarf_Op *op;
283 size_t nops; 286 size_t nops;
284 unsigned int regn; 287 unsigned int regn;
@@ -291,12 +294,29 @@ static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
291 goto static_var; 294 goto static_var;
292 295
293 /* TODO: handle more than 1 exprs */ 296 /* TODO: handle more than 1 exprs */
294 if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL || 297 if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL)
295 dwarf_getlocation_addr(&attr, addr, &op, &nops, 1) <= 0 || 298 return -EINVAL; /* Broken DIE ? */
296 nops == 0) { 299 if (dwarf_getlocation_addr(&attr, addr, &op, &nops, 1) <= 0) {
297 /* TODO: Support const_value */ 300 ret = dwarf_entrypc(sp_die, &tmp);
301 if (ret || addr != tmp ||
302 dwarf_tag(vr_die) != DW_TAG_formal_parameter ||
303 dwarf_highpc(sp_die, &tmp))
304 return -ENOENT;
305 /*
306 * This is fuzzed by fentry mcount. We try to find the
307 * parameter location at the earliest address.
308 */
309 for (addr += 1; addr <= tmp; addr++) {
310 if (dwarf_getlocation_addr(&attr, addr, &op,
311 &nops, 1) > 0)
312 goto found;
313 }
298 return -ENOENT; 314 return -ENOENT;
299 } 315 }
316found:
317 if (nops == 0)
318 /* TODO: Support const_value */
319 return -ENOENT;
300 320
301 if (op->atom == DW_OP_addr) { 321 if (op->atom == DW_OP_addr) {
302static_var: 322static_var:
@@ -600,7 +620,7 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
600 dwarf_diename(vr_die)); 620 dwarf_diename(vr_die));
601 621
602 ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops, 622 ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops,
603 pf->tvar); 623 &pf->sp_die, pf->tvar);
604 if (ret == -ENOENT) 624 if (ret == -ENOENT)
605 pr_err("Failed to find the location of %s at this address.\n" 625 pr_err("Failed to find the location of %s at this address.\n"
606 " Perhaps, it has been optimized out.\n", pf->pvar->var); 626 " Perhaps, it has been optimized out.\n", pf->pvar->var);
@@ -1136,12 +1156,80 @@ found:
1136 return ret; 1156 return ret;
1137} 1157}
1138 1158
1159struct local_vars_finder {
1160 struct probe_finder *pf;
1161 struct perf_probe_arg *args;
1162 int max_args;
1163 int nargs;
1164 int ret;
1165};
1166
1167/* Collect available variables in this scope */
1168static int copy_variables_cb(Dwarf_Die *die_mem, void *data)
1169{
1170 struct local_vars_finder *vf = data;
1171 struct probe_finder *pf = vf->pf;
1172 int tag;
1173
1174 tag = dwarf_tag(die_mem);
1175 if (tag == DW_TAG_formal_parameter ||
1176 tag == DW_TAG_variable) {
1177 if (convert_variable_location(die_mem, vf->pf->addr,
1178 vf->pf->fb_ops, &pf->sp_die,
1179 NULL) == 0) {
1180 vf->args[vf->nargs].var = (char *)dwarf_diename(die_mem);
1181 if (vf->args[vf->nargs].var == NULL) {
1182 vf->ret = -ENOMEM;
1183 return DIE_FIND_CB_END;
1184 }
1185 pr_debug(" %s", vf->args[vf->nargs].var);
1186 vf->nargs++;
1187 }
1188 }
1189
1190 if (dwarf_haspc(die_mem, vf->pf->addr))
1191 return DIE_FIND_CB_CONTINUE;
1192 else
1193 return DIE_FIND_CB_SIBLING;
1194}
1195
1196static int expand_probe_args(Dwarf_Die *sc_die, struct probe_finder *pf,
1197 struct perf_probe_arg *args)
1198{
1199 Dwarf_Die die_mem;
1200 int i;
1201 int n = 0;
1202 struct local_vars_finder vf = {.pf = pf, .args = args,
1203 .max_args = MAX_PROBE_ARGS, .ret = 0};
1204
1205 for (i = 0; i < pf->pev->nargs; i++) {
1206 /* var never be NULL */
1207 if (strcmp(pf->pev->args[i].var, "$vars") == 0) {
1208 pr_debug("Expanding $vars into:");
1209 vf.nargs = n;
1210 /* Special local variables */
1211 die_find_child(sc_die, copy_variables_cb, (void *)&vf,
1212 &die_mem);
1213 pr_debug(" (%d)\n", vf.nargs - n);
1214 if (vf.ret < 0)
1215 return vf.ret;
1216 n = vf.nargs;
1217 } else {
1218 /* Copy normal argument */
1219 args[n] = pf->pev->args[i];
1220 n++;
1221 }
1222 }
1223 return n;
1224}
1225
1139/* Add a found probe point into trace event list */ 1226/* Add a found probe point into trace event list */
1140static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf) 1227static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
1141{ 1228{
1142 struct trace_event_finder *tf = 1229 struct trace_event_finder *tf =
1143 container_of(pf, struct trace_event_finder, pf); 1230 container_of(pf, struct trace_event_finder, pf);
1144 struct probe_trace_event *tev; 1231 struct probe_trace_event *tev;
1232 struct perf_probe_arg *args;
1145 int ret, i; 1233 int ret, i;
1146 1234
1147 /* Check number of tevs */ 1235 /* Check number of tevs */
@@ -1161,21 +1249,35 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
1161 pr_debug("Probe point found: %s+%lu\n", tev->point.symbol, 1249 pr_debug("Probe point found: %s+%lu\n", tev->point.symbol,
1162 tev->point.offset); 1250 tev->point.offset);
1163 1251
1164 /* Find each argument */ 1252 /* Expand special probe argument if exist */
1165 tev->nargs = pf->pev->nargs; 1253 args = zalloc(sizeof(struct perf_probe_arg) * MAX_PROBE_ARGS);
1166 tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); 1254 if (args == NULL)
1167 if (tev->args == NULL)
1168 return -ENOMEM; 1255 return -ENOMEM;
1169 for (i = 0; i < pf->pev->nargs; i++) { 1256
1170 pf->pvar = &pf->pev->args[i]; 1257 ret = expand_probe_args(sc_die, pf, args);
1258 if (ret < 0)
1259 goto end;
1260
1261 tev->nargs = ret;
1262 tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
1263 if (tev->args == NULL) {
1264 ret = -ENOMEM;
1265 goto end;
1266 }
1267
1268 /* Find each argument */
1269 for (i = 0; i < tev->nargs; i++) {
1270 pf->pvar = &args[i];
1171 pf->tvar = &tev->args[i]; 1271 pf->tvar = &tev->args[i];
1172 /* Variable should be found from scope DIE */ 1272 /* Variable should be found from scope DIE */
1173 ret = find_variable(sc_die, pf); 1273 ret = find_variable(sc_die, pf);
1174 if (ret != 0) 1274 if (ret != 0)
1175 return ret; 1275 break;
1176 } 1276 }
1177 1277
1178 return 0; 1278end:
1279 free(args);
1280 return ret;
1179} 1281}
1180 1282
1181/* Find probe_trace_events specified by perf_probe_event from debuginfo */ 1283/* Find probe_trace_events specified by perf_probe_event from debuginfo */
@@ -1222,7 +1324,8 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
1222 if (tag == DW_TAG_formal_parameter || 1324 if (tag == DW_TAG_formal_parameter ||
1223 tag == DW_TAG_variable) { 1325 tag == DW_TAG_variable) {
1224 ret = convert_variable_location(die_mem, af->pf.addr, 1326 ret = convert_variable_location(die_mem, af->pf.addr,
1225 af->pf.fb_ops, NULL); 1327 af->pf.fb_ops, &af->pf.sp_die,
1328 NULL);
1226 if (ret == 0) { 1329 if (ret == 0) {
1227 ret = die_get_varname(die_mem, buf, MAX_VAR_LEN); 1330 ret = die_get_varname(die_mem, buf, MAX_VAR_LEN);
1228 pr_debug2("Add new var: %s\n", buf); 1331 pr_debug2("Add new var: %s\n", buf);
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index 3f0c29dd6ac5..d6dab0e0a937 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -7,6 +7,7 @@
7 7
8#define MAX_PROBE_BUFFER 1024 8#define MAX_PROBE_BUFFER 1024
9#define MAX_PROBES 128 9#define MAX_PROBES 128
10#define MAX_PROBE_ARGS 128
10 11
11static inline int is_c_varname(const char *name) 12static inline int is_c_varname(const char *name)
12{ 13{
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 854c5aa4db0d..4ba7b548e055 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -503,13 +503,16 @@ static int flush_sample_queue(struct perf_session *s,
503 struct perf_sample sample; 503 struct perf_sample sample;
504 u64 limit = os->next_flush; 504 u64 limit = os->next_flush;
505 u64 last_ts = os->last_sample ? os->last_sample->timestamp : 0ULL; 505 u64 last_ts = os->last_sample ? os->last_sample->timestamp : 0ULL;
506 unsigned idx = 0, progress_next = os->nr_samples / 16;
507 bool show_progress = limit == ULLONG_MAX; 506 bool show_progress = limit == ULLONG_MAX;
507 struct ui_progress prog;
508 int ret; 508 int ret;
509 509
510 if (!tool->ordered_samples || !limit) 510 if (!tool->ordered_samples || !limit)
511 return 0; 511 return 0;
512 512
513 if (show_progress)
514 ui_progress__init(&prog, os->nr_samples, "Processing time ordered events...");
515
513 list_for_each_entry_safe(iter, tmp, head, list) { 516 list_for_each_entry_safe(iter, tmp, head, list) {
514 if (session_done()) 517 if (session_done())
515 return 0; 518 return 0;
@@ -530,11 +533,9 @@ static int flush_sample_queue(struct perf_session *s,
530 os->last_flush = iter->timestamp; 533 os->last_flush = iter->timestamp;
531 list_del(&iter->list); 534 list_del(&iter->list);
532 list_add(&iter->list, &os->sample_cache); 535 list_add(&iter->list, &os->sample_cache);
533 if (show_progress && (++idx >= progress_next)) { 536
534 progress_next += os->nr_samples / 16; 537 if (show_progress)
535 ui_progress__update(idx, os->nr_samples, 538 ui_progress__update(&prog, 1);
536 "Processing time ordered events...");
537 }
538 } 539 }
539 540
540 if (list_empty(head)) { 541 if (list_empty(head)) {
@@ -1285,12 +1286,13 @@ int __perf_session__process_events(struct perf_session *session,
1285 u64 file_size, struct perf_tool *tool) 1286 u64 file_size, struct perf_tool *tool)
1286{ 1287{
1287 int fd = perf_data_file__fd(session->file); 1288 int fd = perf_data_file__fd(session->file);
1288 u64 head, page_offset, file_offset, file_pos, progress_next; 1289 u64 head, page_offset, file_offset, file_pos;
1289 int err, mmap_prot, mmap_flags, map_idx = 0; 1290 int err, mmap_prot, mmap_flags, map_idx = 0;
1290 size_t mmap_size; 1291 size_t mmap_size;
1291 char *buf, *mmaps[NUM_MMAPS]; 1292 char *buf, *mmaps[NUM_MMAPS];
1292 union perf_event *event; 1293 union perf_event *event;
1293 uint32_t size; 1294 uint32_t size;
1295 struct ui_progress prog;
1294 1296
1295 perf_tool__fill_defaults(tool); 1297 perf_tool__fill_defaults(tool);
1296 1298
@@ -1301,7 +1303,7 @@ int __perf_session__process_events(struct perf_session *session,
1301 if (data_size && (data_offset + data_size < file_size)) 1303 if (data_size && (data_offset + data_size < file_size))
1302 file_size = data_offset + data_size; 1304 file_size = data_offset + data_size;
1303 1305
1304 progress_next = file_size / 16; 1306 ui_progress__init(&prog, file_size, "Processing events...");
1305 1307
1306 mmap_size = MMAP_SIZE; 1308 mmap_size = MMAP_SIZE;
1307 if (mmap_size > file_size) 1309 if (mmap_size > file_size)
@@ -1356,11 +1358,7 @@ more:
1356 head += size; 1358 head += size;
1357 file_pos += size; 1359 file_pos += size;
1358 1360
1359 if (file_pos >= progress_next) { 1361 ui_progress__update(&prog, size);
1360 progress_next += file_size / 16;
1361 ui_progress__update(file_pos, file_size,
1362 "Processing events...");
1363 }
1364 1362
1365 if (session_done()) 1363 if (session_done())
1366 goto out; 1364 goto out;
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 1f9821db9e77..19b4aa279d1e 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -60,11 +60,11 @@ sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
60 return right->thread->tid - left->thread->tid; 60 return right->thread->tid - left->thread->tid;
61} 61}
62 62
63static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf, 63static int hist_entry__thread_snprintf(struct hist_entry *he, char *bf,
64 size_t size, unsigned int width) 64 size_t size, unsigned int width)
65{ 65{
66 return repsep_snprintf(bf, size, "%*s:%5d", width - 6, 66 return repsep_snprintf(bf, size, "%*s:%5d", width - 6,
67 self->thread->comm ?: "", self->thread->tid); 67 he->thread->comm ?: "", he->thread->tid);
68} 68}
69 69
70struct sort_entry sort_thread = { 70struct sort_entry sort_thread = {
@@ -94,10 +94,10 @@ sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
94 return strcmp(comm_l, comm_r); 94 return strcmp(comm_l, comm_r);
95} 95}
96 96
97static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf, 97static int hist_entry__comm_snprintf(struct hist_entry *he, char *bf,
98 size_t size, unsigned int width) 98 size_t size, unsigned int width)
99{ 99{
100 return repsep_snprintf(bf, size, "%*s", width, self->thread->comm); 100 return repsep_snprintf(bf, size, "%*s", width, he->thread->comm);
101} 101}
102 102
103struct sort_entry sort_comm = { 103struct sort_entry sort_comm = {
@@ -148,10 +148,10 @@ static int _hist_entry__dso_snprintf(struct map *map, char *bf,
148 return repsep_snprintf(bf, size, "%-*s", width, "[unknown]"); 148 return repsep_snprintf(bf, size, "%-*s", width, "[unknown]");
149} 149}
150 150
151static int hist_entry__dso_snprintf(struct hist_entry *self, char *bf, 151static int hist_entry__dso_snprintf(struct hist_entry *he, char *bf,
152 size_t size, unsigned int width) 152 size_t size, unsigned int width)
153{ 153{
154 return _hist_entry__dso_snprintf(self->ms.map, bf, size, width); 154 return _hist_entry__dso_snprintf(he->ms.map, bf, size, width);
155} 155}
156 156
157struct sort_entry sort_dso = { 157struct sort_entry sort_dso = {
@@ -234,11 +234,11 @@ static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym,
234 return ret; 234 return ret;
235} 235}
236 236
237static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf, 237static int hist_entry__sym_snprintf(struct hist_entry *he, char *bf,
238 size_t size, unsigned int width) 238 size_t size, unsigned int width)
239{ 239{
240 return _hist_entry__sym_snprintf(self->ms.map, self->ms.sym, self->ip, 240 return _hist_entry__sym_snprintf(he->ms.map, he->ms.sym, he->ip,
241 self->level, bf, size, width); 241 he->level, bf, size, width);
242} 242}
243 243
244struct sort_entry sort_sym = { 244struct sort_entry sort_sym = {
@@ -274,11 +274,11 @@ sort__srcline_cmp(struct hist_entry *left, struct hist_entry *right)
274 return strcmp(left->srcline, right->srcline); 274 return strcmp(left->srcline, right->srcline);
275} 275}
276 276
277static int hist_entry__srcline_snprintf(struct hist_entry *self, char *bf, 277static int hist_entry__srcline_snprintf(struct hist_entry *he, char *bf,
278 size_t size, 278 size_t size,
279 unsigned int width __maybe_unused) 279 unsigned int width __maybe_unused)
280{ 280{
281 return repsep_snprintf(bf, size, "%s", self->srcline); 281 return repsep_snprintf(bf, size, "%s", he->srcline);
282} 282}
283 283
284struct sort_entry sort_srcline = { 284struct sort_entry sort_srcline = {
@@ -302,11 +302,11 @@ sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)
302 return strcmp(sym_l->name, sym_r->name); 302 return strcmp(sym_l->name, sym_r->name);
303} 303}
304 304
305static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf, 305static int hist_entry__parent_snprintf(struct hist_entry *he, char *bf,
306 size_t size, unsigned int width) 306 size_t size, unsigned int width)
307{ 307{
308 return repsep_snprintf(bf, size, "%-*s", width, 308 return repsep_snprintf(bf, size, "%-*s", width,
309 self->parent ? self->parent->name : "[other]"); 309 he->parent ? he->parent->name : "[other]");
310} 310}
311 311
312struct sort_entry sort_parent = { 312struct sort_entry sort_parent = {
@@ -324,10 +324,10 @@ sort__cpu_cmp(struct hist_entry *left, struct hist_entry *right)
324 return right->cpu - left->cpu; 324 return right->cpu - left->cpu;
325} 325}
326 326
327static int hist_entry__cpu_snprintf(struct hist_entry *self, char *bf, 327static int hist_entry__cpu_snprintf(struct hist_entry *he, char *bf,
328 size_t size, unsigned int width) 328 size_t size, unsigned int width)
329{ 329{
330 return repsep_snprintf(bf, size, "%*d", width, self->cpu); 330 return repsep_snprintf(bf, size, "%*d", width, he->cpu);
331} 331}
332 332
333struct sort_entry sort_cpu = { 333struct sort_entry sort_cpu = {
@@ -346,10 +346,10 @@ sort__dso_from_cmp(struct hist_entry *left, struct hist_entry *right)
346 right->branch_info->from.map); 346 right->branch_info->from.map);
347} 347}
348 348
349static int hist_entry__dso_from_snprintf(struct hist_entry *self, char *bf, 349static int hist_entry__dso_from_snprintf(struct hist_entry *he, char *bf,
350 size_t size, unsigned int width) 350 size_t size, unsigned int width)
351{ 351{
352 return _hist_entry__dso_snprintf(self->branch_info->from.map, 352 return _hist_entry__dso_snprintf(he->branch_info->from.map,
353 bf, size, width); 353 bf, size, width);
354} 354}
355 355
@@ -360,10 +360,10 @@ sort__dso_to_cmp(struct hist_entry *left, struct hist_entry *right)
360 right->branch_info->to.map); 360 right->branch_info->to.map);
361} 361}
362 362
363static int hist_entry__dso_to_snprintf(struct hist_entry *self, char *bf, 363static int hist_entry__dso_to_snprintf(struct hist_entry *he, char *bf,
364 size_t size, unsigned int width) 364 size_t size, unsigned int width)
365{ 365{
366 return _hist_entry__dso_snprintf(self->branch_info->to.map, 366 return _hist_entry__dso_snprintf(he->branch_info->to.map,
367 bf, size, width); 367 bf, size, width);
368} 368}
369 369
@@ -391,21 +391,21 @@ sort__sym_to_cmp(struct hist_entry *left, struct hist_entry *right)
391 return _sort__sym_cmp(to_l->sym, to_r->sym); 391 return _sort__sym_cmp(to_l->sym, to_r->sym);
392} 392}
393 393
394static int hist_entry__sym_from_snprintf(struct hist_entry *self, char *bf, 394static int hist_entry__sym_from_snprintf(struct hist_entry *he, char *bf,
395 size_t size, unsigned int width) 395 size_t size, unsigned int width)
396{ 396{
397 struct addr_map_symbol *from = &self->branch_info->from; 397 struct addr_map_symbol *from = &he->branch_info->from;
398 return _hist_entry__sym_snprintf(from->map, from->sym, from->addr, 398 return _hist_entry__sym_snprintf(from->map, from->sym, from->addr,
399 self->level, bf, size, width); 399 he->level, bf, size, width);
400 400
401} 401}
402 402
403static int hist_entry__sym_to_snprintf(struct hist_entry *self, char *bf, 403static int hist_entry__sym_to_snprintf(struct hist_entry *he, char *bf,
404 size_t size, unsigned int width) 404 size_t size, unsigned int width)
405{ 405{
406 struct addr_map_symbol *to = &self->branch_info->to; 406 struct addr_map_symbol *to = &he->branch_info->to;
407 return _hist_entry__sym_snprintf(to->map, to->sym, to->addr, 407 return _hist_entry__sym_snprintf(to->map, to->sym, to->addr,
408 self->level, bf, size, width); 408 he->level, bf, size, width);
409 409
410} 410}
411 411
@@ -448,13 +448,13 @@ sort__mispredict_cmp(struct hist_entry *left, struct hist_entry *right)
448 return mp || p; 448 return mp || p;
449} 449}
450 450
451static int hist_entry__mispredict_snprintf(struct hist_entry *self, char *bf, 451static int hist_entry__mispredict_snprintf(struct hist_entry *he, char *bf,
452 size_t size, unsigned int width){ 452 size_t size, unsigned int width){
453 static const char *out = "N/A"; 453 static const char *out = "N/A";
454 454
455 if (self->branch_info->flags.predicted) 455 if (he->branch_info->flags.predicted)
456 out = "N"; 456 out = "N";
457 else if (self->branch_info->flags.mispred) 457 else if (he->branch_info->flags.mispred)
458 out = "Y"; 458 out = "Y";
459 459
460 return repsep_snprintf(bf, size, "%-*s", width, out); 460 return repsep_snprintf(bf, size, "%-*s", width, out);
@@ -474,19 +474,19 @@ sort__daddr_cmp(struct hist_entry *left, struct hist_entry *right)
474 return (int64_t)(r - l); 474 return (int64_t)(r - l);
475} 475}
476 476
477static int hist_entry__daddr_snprintf(struct hist_entry *self, char *bf, 477static int hist_entry__daddr_snprintf(struct hist_entry *he, char *bf,
478 size_t size, unsigned int width) 478 size_t size, unsigned int width)
479{ 479{
480 uint64_t addr = 0; 480 uint64_t addr = 0;
481 struct map *map = NULL; 481 struct map *map = NULL;
482 struct symbol *sym = NULL; 482 struct symbol *sym = NULL;
483 483
484 if (self->mem_info) { 484 if (he->mem_info) {
485 addr = self->mem_info->daddr.addr; 485 addr = he->mem_info->daddr.addr;
486 map = self->mem_info->daddr.map; 486 map = he->mem_info->daddr.map;
487 sym = self->mem_info->daddr.sym; 487 sym = he->mem_info->daddr.sym;
488 } 488 }
489 return _hist_entry__sym_snprintf(map, sym, addr, self->level, bf, size, 489 return _hist_entry__sym_snprintf(map, sym, addr, he->level, bf, size,
490 width); 490 width);
491} 491}
492 492
@@ -504,13 +504,13 @@ sort__dso_daddr_cmp(struct hist_entry *left, struct hist_entry *right)
504 return _sort__dso_cmp(map_l, map_r); 504 return _sort__dso_cmp(map_l, map_r);
505} 505}
506 506
507static int hist_entry__dso_daddr_snprintf(struct hist_entry *self, char *bf, 507static int hist_entry__dso_daddr_snprintf(struct hist_entry *he, char *bf,
508 size_t size, unsigned int width) 508 size_t size, unsigned int width)
509{ 509{
510 struct map *map = NULL; 510 struct map *map = NULL;
511 511
512 if (self->mem_info) 512 if (he->mem_info)
513 map = self->mem_info->daddr.map; 513 map = he->mem_info->daddr.map;
514 514
515 return _hist_entry__dso_snprintf(map, bf, size, width); 515 return _hist_entry__dso_snprintf(map, bf, size, width);
516} 516}
@@ -534,14 +534,14 @@ sort__locked_cmp(struct hist_entry *left, struct hist_entry *right)
534 return (int64_t)(data_src_r.mem_lock - data_src_l.mem_lock); 534 return (int64_t)(data_src_r.mem_lock - data_src_l.mem_lock);
535} 535}
536 536
537static int hist_entry__locked_snprintf(struct hist_entry *self, char *bf, 537static int hist_entry__locked_snprintf(struct hist_entry *he, char *bf,
538 size_t size, unsigned int width) 538 size_t size, unsigned int width)
539{ 539{
540 const char *out; 540 const char *out;
541 u64 mask = PERF_MEM_LOCK_NA; 541 u64 mask = PERF_MEM_LOCK_NA;
542 542
543 if (self->mem_info) 543 if (he->mem_info)
544 mask = self->mem_info->data_src.mem_lock; 544 mask = he->mem_info->data_src.mem_lock;
545 545
546 if (mask & PERF_MEM_LOCK_NA) 546 if (mask & PERF_MEM_LOCK_NA)
547 out = "N/A"; 547 out = "N/A";
@@ -583,7 +583,7 @@ static const char * const tlb_access[] = {
583}; 583};
584#define NUM_TLB_ACCESS (sizeof(tlb_access)/sizeof(const char *)) 584#define NUM_TLB_ACCESS (sizeof(tlb_access)/sizeof(const char *))
585 585
586static int hist_entry__tlb_snprintf(struct hist_entry *self, char *bf, 586static int hist_entry__tlb_snprintf(struct hist_entry *he, char *bf,
587 size_t size, unsigned int width) 587 size_t size, unsigned int width)
588{ 588{
589 char out[64]; 589 char out[64];
@@ -594,8 +594,8 @@ static int hist_entry__tlb_snprintf(struct hist_entry *self, char *bf,
594 594
595 out[0] = '\0'; 595 out[0] = '\0';
596 596
597 if (self->mem_info) 597 if (he->mem_info)
598 m = self->mem_info->data_src.mem_dtlb; 598 m = he->mem_info->data_src.mem_dtlb;
599 599
600 hit = m & PERF_MEM_TLB_HIT; 600 hit = m & PERF_MEM_TLB_HIT;
601 miss = m & PERF_MEM_TLB_MISS; 601 miss = m & PERF_MEM_TLB_MISS;
@@ -660,7 +660,7 @@ static const char * const mem_lvl[] = {
660}; 660};
661#define NUM_MEM_LVL (sizeof(mem_lvl)/sizeof(const char *)) 661#define NUM_MEM_LVL (sizeof(mem_lvl)/sizeof(const char *))
662 662
663static int hist_entry__lvl_snprintf(struct hist_entry *self, char *bf, 663static int hist_entry__lvl_snprintf(struct hist_entry *he, char *bf,
664 size_t size, unsigned int width) 664 size_t size, unsigned int width)
665{ 665{
666 char out[64]; 666 char out[64];
@@ -669,8 +669,8 @@ static int hist_entry__lvl_snprintf(struct hist_entry *self, char *bf,
669 u64 m = PERF_MEM_LVL_NA; 669 u64 m = PERF_MEM_LVL_NA;
670 u64 hit, miss; 670 u64 hit, miss;
671 671
672 if (self->mem_info) 672 if (he->mem_info)
673 m = self->mem_info->data_src.mem_lvl; 673 m = he->mem_info->data_src.mem_lvl;
674 674
675 out[0] = '\0'; 675 out[0] = '\0';
676 676
@@ -728,7 +728,7 @@ static const char * const snoop_access[] = {
728}; 728};
729#define NUM_SNOOP_ACCESS (sizeof(snoop_access)/sizeof(const char *)) 729#define NUM_SNOOP_ACCESS (sizeof(snoop_access)/sizeof(const char *))
730 730
731static int hist_entry__snoop_snprintf(struct hist_entry *self, char *bf, 731static int hist_entry__snoop_snprintf(struct hist_entry *he, char *bf,
732 size_t size, unsigned int width) 732 size_t size, unsigned int width)
733{ 733{
734 char out[64]; 734 char out[64];
@@ -738,8 +738,8 @@ static int hist_entry__snoop_snprintf(struct hist_entry *self, char *bf,
738 738
739 out[0] = '\0'; 739 out[0] = '\0';
740 740
741 if (self->mem_info) 741 if (he->mem_info)
742 m = self->mem_info->data_src.mem_snoop; 742 m = he->mem_info->data_src.mem_snoop;
743 743
744 for (i = 0; m && i < NUM_SNOOP_ACCESS; i++, m >>= 1) { 744 for (i = 0; m && i < NUM_SNOOP_ACCESS; i++, m >>= 1) {
745 if (!(m & 0x1)) 745 if (!(m & 0x1))
@@ -776,10 +776,10 @@ sort__local_weight_cmp(struct hist_entry *left, struct hist_entry *right)
776 return he_weight(left) - he_weight(right); 776 return he_weight(left) - he_weight(right);
777} 777}
778 778
779static int hist_entry__local_weight_snprintf(struct hist_entry *self, char *bf, 779static int hist_entry__local_weight_snprintf(struct hist_entry *he, char *bf,
780 size_t size, unsigned int width) 780 size_t size, unsigned int width)
781{ 781{
782 return repsep_snprintf(bf, size, "%-*llu", width, he_weight(self)); 782 return repsep_snprintf(bf, size, "%-*llu", width, he_weight(he));
783} 783}
784 784
785struct sort_entry sort_local_weight = { 785struct sort_entry sort_local_weight = {
@@ -795,10 +795,10 @@ sort__global_weight_cmp(struct hist_entry *left, struct hist_entry *right)
795 return left->stat.weight - right->stat.weight; 795 return left->stat.weight - right->stat.weight;
796} 796}
797 797
798static int hist_entry__global_weight_snprintf(struct hist_entry *self, char *bf, 798static int hist_entry__global_weight_snprintf(struct hist_entry *he, char *bf,
799 size_t size, unsigned int width) 799 size_t size, unsigned int width)
800{ 800{
801 return repsep_snprintf(bf, size, "%-*llu", width, self->stat.weight); 801 return repsep_snprintf(bf, size, "%-*llu", width, he->stat.weight);
802} 802}
803 803
804struct sort_entry sort_global_weight = { 804struct sort_entry sort_global_weight = {
@@ -857,12 +857,12 @@ sort__abort_cmp(struct hist_entry *left, struct hist_entry *right)
857 right->branch_info->flags.abort; 857 right->branch_info->flags.abort;
858} 858}
859 859
860static int hist_entry__abort_snprintf(struct hist_entry *self, char *bf, 860static int hist_entry__abort_snprintf(struct hist_entry *he, char *bf,
861 size_t size, unsigned int width) 861 size_t size, unsigned int width)
862{ 862{
863 static const char *out = "."; 863 static const char *out = ".";
864 864
865 if (self->branch_info->flags.abort) 865 if (he->branch_info->flags.abort)
866 out = "A"; 866 out = "A";
867 return repsep_snprintf(bf, size, "%-*s", width, out); 867 return repsep_snprintf(bf, size, "%-*s", width, out);
868} 868}
@@ -881,12 +881,12 @@ sort__in_tx_cmp(struct hist_entry *left, struct hist_entry *right)
881 right->branch_info->flags.in_tx; 881 right->branch_info->flags.in_tx;
882} 882}
883 883
884static int hist_entry__in_tx_snprintf(struct hist_entry *self, char *bf, 884static int hist_entry__in_tx_snprintf(struct hist_entry *he, char *bf,
885 size_t size, unsigned int width) 885 size_t size, unsigned int width)
886{ 886{
887 static const char *out = "."; 887 static const char *out = ".";
888 888
889 if (self->branch_info->flags.in_tx) 889 if (he->branch_info->flags.in_tx)
890 out = "T"; 890 out = "T";
891 891
892 return repsep_snprintf(bf, size, "%-*s", width, out); 892 return repsep_snprintf(bf, size, "%-*s", width, out);
@@ -940,10 +940,10 @@ int hist_entry__transaction_len(void)
940 return len; 940 return len;
941} 941}
942 942
943static int hist_entry__transaction_snprintf(struct hist_entry *self, char *bf, 943static int hist_entry__transaction_snprintf(struct hist_entry *he, char *bf,
944 size_t size, unsigned int width) 944 size_t size, unsigned int width)
945{ 945{
946 u64 t = self->transaction; 946 u64 t = he->transaction;
947 char buf[128]; 947 char buf[128];
948 char *p = buf; 948 char *p = buf;
949 int i; 949 int i;
@@ -1125,7 +1125,7 @@ int setup_sorting(void)
1125 return ret; 1125 return ret;
1126} 1126}
1127 1127
1128static void sort_entry__setup_elide(struct sort_entry *self, 1128static void sort_entry__setup_elide(struct sort_entry *se,
1129 struct strlist *list, 1129 struct strlist *list,
1130 const char *list_name, FILE *fp) 1130 const char *list_name, FILE *fp)
1131{ 1131{
@@ -1133,7 +1133,7 @@ static void sort_entry__setup_elide(struct sort_entry *self,
1133 if (fp != NULL) 1133 if (fp != NULL)
1134 fprintf(fp, "# %s: %s\n", list_name, 1134 fprintf(fp, "# %s: %s\n", list_name,
1135 strlist__entry(list, 0)->s); 1135 strlist__entry(list, 0)->s);
1136 self->elide = true; 1136 se->elide = true;
1137 } 1137 }
1138} 1138}
1139 1139
diff --git a/tools/perf/util/strfilter.c b/tools/perf/util/strfilter.c
index 834c8ebfe38e..67e4a0082822 100644
--- a/tools/perf/util/strfilter.c
+++ b/tools/perf/util/strfilter.c
@@ -10,22 +10,22 @@ static const char *OP_not = "!"; /* Logical NOT */
10#define is_operator(c) ((c) == '|' || (c) == '&' || (c) == '!') 10#define is_operator(c) ((c) == '|' || (c) == '&' || (c) == '!')
11#define is_separator(c) (is_operator(c) || (c) == '(' || (c) == ')') 11#define is_separator(c) (is_operator(c) || (c) == '(' || (c) == ')')
12 12
13static void strfilter_node__delete(struct strfilter_node *self) 13static void strfilter_node__delete(struct strfilter_node *node)
14{ 14{
15 if (self) { 15 if (node) {
16 if (self->p && !is_operator(*self->p)) 16 if (node->p && !is_operator(*node->p))
17 free((char *)self->p); 17 free((char *)node->p);
18 strfilter_node__delete(self->l); 18 strfilter_node__delete(node->l);
19 strfilter_node__delete(self->r); 19 strfilter_node__delete(node->r);
20 free(self); 20 free(node);
21 } 21 }
22} 22}
23 23
24void strfilter__delete(struct strfilter *self) 24void strfilter__delete(struct strfilter *filter)
25{ 25{
26 if (self) { 26 if (filter) {
27 strfilter_node__delete(self->root); 27 strfilter_node__delete(filter->root);
28 free(self); 28 free(filter);
29 } 29 }
30} 30}
31 31
@@ -170,30 +170,30 @@ struct strfilter *strfilter__new(const char *rules, const char **err)
170 return ret; 170 return ret;
171} 171}
172 172
173static bool strfilter_node__compare(struct strfilter_node *self, 173static bool strfilter_node__compare(struct strfilter_node *node,
174 const char *str) 174 const char *str)
175{ 175{
176 if (!self || !self->p) 176 if (!node || !node->p)
177 return false; 177 return false;
178 178
179 switch (*self->p) { 179 switch (*node->p) {
180 case '|': /* OR */ 180 case '|': /* OR */
181 return strfilter_node__compare(self->l, str) || 181 return strfilter_node__compare(node->l, str) ||
182 strfilter_node__compare(self->r, str); 182 strfilter_node__compare(node->r, str);
183 case '&': /* AND */ 183 case '&': /* AND */
184 return strfilter_node__compare(self->l, str) && 184 return strfilter_node__compare(node->l, str) &&
185 strfilter_node__compare(self->r, str); 185 strfilter_node__compare(node->r, str);
186 case '!': /* NOT */ 186 case '!': /* NOT */
187 return !strfilter_node__compare(self->r, str); 187 return !strfilter_node__compare(node->r, str);
188 default: 188 default:
189 return strglobmatch(str, self->p); 189 return strglobmatch(str, node->p);
190 } 190 }
191} 191}
192 192
193/* Return true if STR matches the filter rules */ 193/* Return true if STR matches the filter rules */
194bool strfilter__compare(struct strfilter *self, const char *str) 194bool strfilter__compare(struct strfilter *node, const char *str)
195{ 195{
196 if (!self) 196 if (!node)
197 return false; 197 return false;
198 return strfilter_node__compare(self->root, str); 198 return strfilter_node__compare(node->root, str);
199} 199}
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index e3d4a550a703..80d19a086072 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -9,51 +9,51 @@
9 9
10struct thread *thread__new(pid_t pid, pid_t tid) 10struct thread *thread__new(pid_t pid, pid_t tid)
11{ 11{
12 struct thread *self = zalloc(sizeof(*self)); 12 struct thread *thread = zalloc(sizeof(*thread));
13 13
14 if (self != NULL) { 14 if (thread != NULL) {
15 map_groups__init(&self->mg); 15 map_groups__init(&thread->mg);
16 self->pid_ = pid; 16 thread->pid_ = pid;
17 self->tid = tid; 17 thread->tid = tid;
18 self->ppid = -1; 18 thread->ppid = -1;
19 self->comm = malloc(32); 19 thread->comm = malloc(32);
20 if (self->comm) 20 if (thread->comm)
21 snprintf(self->comm, 32, ":%d", self->tid); 21 snprintf(thread->comm, 32, ":%d", thread->tid);
22 } 22 }
23 23
24 return self; 24 return thread;
25} 25}
26 26
27void thread__delete(struct thread *self) 27void thread__delete(struct thread *thread)
28{ 28{
29 map_groups__exit(&self->mg); 29 map_groups__exit(&thread->mg);
30 free(self->comm); 30 free(thread->comm);
31 free(self); 31 free(thread);
32} 32}
33 33
34int thread__set_comm(struct thread *self, const char *comm) 34int thread__set_comm(struct thread *thread, const char *comm)
35{ 35{
36 int err; 36 int err;
37 37
38 if (self->comm) 38 if (thread->comm)
39 free(self->comm); 39 free(thread->comm);
40 self->comm = strdup(comm); 40 thread->comm = strdup(comm);
41 err = self->comm == NULL ? -ENOMEM : 0; 41 err = thread->comm == NULL ? -ENOMEM : 0;
42 if (!err) { 42 if (!err) {
43 self->comm_set = true; 43 thread->comm_set = true;
44 } 44 }
45 return err; 45 return err;
46} 46}
47 47
48int thread__comm_len(struct thread *self) 48int thread__comm_len(struct thread *thread)
49{ 49{
50 if (!self->comm_len) { 50 if (!thread->comm_len) {
51 if (!self->comm) 51 if (!thread->comm)
52 return 0; 52 return 0;
53 self->comm_len = strlen(self->comm); 53 thread->comm_len = strlen(thread->comm);
54 } 54 }
55 55
56 return self->comm_len; 56 return thread->comm_len;
57} 57}
58 58
59size_t thread__fprintf(struct thread *thread, FILE *fp) 59size_t thread__fprintf(struct thread *thread, FILE *fp)
@@ -62,30 +62,30 @@ size_t thread__fprintf(struct thread *thread, FILE *fp)
62 map_groups__fprintf(&thread->mg, verbose, fp); 62 map_groups__fprintf(&thread->mg, verbose, fp);
63} 63}
64 64
65void thread__insert_map(struct thread *self, struct map *map) 65void thread__insert_map(struct thread *thread, struct map *map)
66{ 66{
67 map_groups__fixup_overlappings(&self->mg, map, verbose, stderr); 67 map_groups__fixup_overlappings(&thread->mg, map, verbose, stderr);
68 map_groups__insert(&self->mg, map); 68 map_groups__insert(&thread->mg, map);
69} 69}
70 70
71int thread__fork(struct thread *self, struct thread *parent) 71int thread__fork(struct thread *thread, struct thread *parent)
72{ 72{
73 int i; 73 int i;
74 74
75 if (parent->comm_set) { 75 if (parent->comm_set) {
76 if (self->comm) 76 if (thread->comm)
77 free(self->comm); 77 free(thread->comm);
78 self->comm = strdup(parent->comm); 78 thread->comm = strdup(parent->comm);
79 if (!self->comm) 79 if (!thread->comm)
80 return -ENOMEM; 80 return -ENOMEM;
81 self->comm_set = true; 81 thread->comm_set = true;
82 } 82 }
83 83
84 for (i = 0; i < MAP__NR_TYPES; ++i) 84 for (i = 0; i < MAP__NR_TYPES; ++i)
85 if (map_groups__clone(&self->mg, &parent->mg, i) < 0) 85 if (map_groups__clone(&thread->mg, &parent->mg, i) < 0)
86 return -ENOMEM; 86 return -ENOMEM;
87 87
88 self->ppid = parent->tid; 88 thread->ppid = parent->tid;
89 89
90 return 0; 90 return 0;
91} 91}
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index c25e57b3acb2..28a0a89c1f73 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -386,6 +386,8 @@ unsigned long parse_tag_value(const char *str, struct parse_tag *tags)
386 if (s != endptr) 386 if (s != endptr)
387 break; 387 break;
388 388
389 if (value > ULONG_MAX / i->mult)
390 break;
389 value *= i->mult; 391 value *= i->mult;
390 return value; 392 return value;
391 } 393 }