aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/builtin-annotate.c75
-rw-r--r--tools/perf/builtin-buildid-cache.c37
-rw-r--r--tools/perf/builtin-diff.c2
-rw-r--r--tools/perf/builtin-inject.c31
-rw-r--r--tools/perf/builtin-kmem.c49
-rw-r--r--tools/perf/builtin-kvm.c24
-rw-r--r--tools/perf/builtin-lock.c3
-rw-r--r--tools/perf/builtin-mem.c2
-rw-r--r--tools/perf/builtin-record.c2
-rw-r--r--tools/perf/builtin-report.c4
-rw-r--r--tools/perf/builtin-sched.c3
-rw-r--r--tools/perf/builtin-script.c57
-rw-r--r--tools/perf/builtin-timechart.c4
-rw-r--r--tools/perf/builtin-top.c59
-rw-r--r--tools/perf/builtin-trace.c34
-rw-r--r--tools/perf/tests/builtin-test.c2
-rw-r--r--tools/perf/ui/browsers/hists.c13
-rw-r--r--tools/perf/util/cloexec.c23
-rw-r--r--tools/perf/util/comm.c7
-rw-r--r--tools/perf/util/comm.h6
-rw-r--r--tools/perf/util/event.h2
-rw-r--r--tools/perf/util/evlist.c109
-rw-r--r--tools/perf/util/evlist.h5
-rw-r--r--tools/perf/util/evsel.c34
-rw-r--r--tools/perf/util/evsel.h2
-rw-r--r--tools/perf/util/hist.c22
-rw-r--r--tools/perf/util/hist.h1
-rw-r--r--tools/perf/util/machine.c30
-rw-r--r--tools/perf/util/machine.h4
-rw-r--r--tools/perf/util/probe-event.c98
-rw-r--r--tools/perf/util/record.c40
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c114
-rw-r--r--tools/perf/util/session.c79
-rw-r--r--tools/perf/util/session.h5
-rw-r--r--tools/perf/util/symbol-elf.c9
-rw-r--r--tools/perf/util/symbol.c31
-rw-r--r--tools/perf/util/symbol.h4
-rw-r--r--tools/perf/util/thread.c24
-rw-r--r--tools/perf/util/thread.h10
-rw-r--r--tools/perf/util/util.c13
-rw-r--r--tools/perf/util/util.h2
41 files changed, 770 insertions, 305 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 952b5ece6740..d4da6929597f 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -36,7 +36,8 @@
36 36
37struct perf_annotate { 37struct perf_annotate {
38 struct perf_tool tool; 38 struct perf_tool tool;
39 bool force, use_tui, use_stdio, use_gtk; 39 struct perf_session *session;
40 bool use_tui, use_stdio, use_gtk;
40 bool full_paths; 41 bool full_paths;
41 bool print_line; 42 bool print_line;
42 bool skip_missing; 43 bool skip_missing;
@@ -188,18 +189,9 @@ find_next:
188static int __cmd_annotate(struct perf_annotate *ann) 189static int __cmd_annotate(struct perf_annotate *ann)
189{ 190{
190 int ret; 191 int ret;
191 struct perf_session *session; 192 struct perf_session *session = ann->session;
192 struct perf_evsel *pos; 193 struct perf_evsel *pos;
193 u64 total_nr_samples; 194 u64 total_nr_samples;
194 struct perf_data_file file = {
195 .path = input_name,
196 .mode = PERF_DATA_MODE_READ,
197 .force = ann->force,
198 };
199
200 session = perf_session__new(&file, false, &ann->tool);
201 if (session == NULL)
202 return -ENOMEM;
203 195
204 machines__set_symbol_filter(&session->machines, symbol__annotate_init); 196 machines__set_symbol_filter(&session->machines, symbol__annotate_init);
205 197
@@ -207,22 +199,22 @@ static int __cmd_annotate(struct perf_annotate *ann)
207 ret = perf_session__cpu_bitmap(session, ann->cpu_list, 199 ret = perf_session__cpu_bitmap(session, ann->cpu_list,
208 ann->cpu_bitmap); 200 ann->cpu_bitmap);
209 if (ret) 201 if (ret)
210 goto out_delete; 202 goto out;
211 } 203 }
212 204
213 if (!objdump_path) { 205 if (!objdump_path) {
214 ret = perf_session_env__lookup_objdump(&session->header.env); 206 ret = perf_session_env__lookup_objdump(&session->header.env);
215 if (ret) 207 if (ret)
216 goto out_delete; 208 goto out;
217 } 209 }
218 210
219 ret = perf_session__process_events(session, &ann->tool); 211 ret = perf_session__process_events(session, &ann->tool);
220 if (ret) 212 if (ret)
221 goto out_delete; 213 goto out;
222 214
223 if (dump_trace) { 215 if (dump_trace) {
224 perf_session__fprintf_nr_events(session, stdout); 216 perf_session__fprintf_nr_events(session, stdout);
225 goto out_delete; 217 goto out;
226 } 218 }
227 219
228 if (verbose > 3) 220 if (verbose > 3)
@@ -250,8 +242,8 @@ static int __cmd_annotate(struct perf_annotate *ann)
250 } 242 }
251 243
252 if (total_nr_samples == 0) { 244 if (total_nr_samples == 0) {
253 ui__error("The %s file has no samples!\n", file.path); 245 ui__error("The %s file has no samples!\n", session->file->path);
254 goto out_delete; 246 goto out;
255 } 247 }
256 248
257 if (use_browser == 2) { 249 if (use_browser == 2) {
@@ -261,24 +253,12 @@ static int __cmd_annotate(struct perf_annotate *ann)
261 "perf_gtk__show_annotations"); 253 "perf_gtk__show_annotations");
262 if (show_annotations == NULL) { 254 if (show_annotations == NULL) {
263 ui__error("GTK browser not found!\n"); 255 ui__error("GTK browser not found!\n");
264 goto out_delete; 256 goto out;
265 } 257 }
266 show_annotations(); 258 show_annotations();
267 } 259 }
268 260
269out_delete: 261out:
270 /*
271 * Speed up the exit process, for large files this can
272 * take quite a while.
273 *
274 * XXX Enable this when using valgrind or if we ever
275 * librarize this command.
276 *
277 * Also experiment with obstacks to see how much speed
278 * up we'll get here.
279 *
280 * perf_session__delete(session);
281 */
282 return ret; 262 return ret;
283} 263}
284 264
@@ -301,6 +281,10 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
301 .ordering_requires_timestamps = true, 281 .ordering_requires_timestamps = true,
302 }, 282 },
303 }; 283 };
284 struct perf_data_file file = {
285 .path = input_name,
286 .mode = PERF_DATA_MODE_READ,
287 };
304 const struct option options[] = { 288 const struct option options[] = {
305 OPT_STRING('i', "input", &input_name, "file", 289 OPT_STRING('i', "input", &input_name, "file",
306 "input file name"), 290 "input file name"),
@@ -308,7 +292,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
308 "only consider symbols in these dsos"), 292 "only consider symbols in these dsos"),
309 OPT_STRING('s', "symbol", &annotate.sym_hist_filter, "symbol", 293 OPT_STRING('s', "symbol", &annotate.sym_hist_filter, "symbol",
310 "symbol to annotate"), 294 "symbol to annotate"),
311 OPT_BOOLEAN('f', "force", &annotate.force, "don't complain, do it"), 295 OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"),
312 OPT_INCR('v', "verbose", &verbose, 296 OPT_INCR('v', "verbose", &verbose,
313 "be more verbose (show symbol address, etc)"), 297 "be more verbose (show symbol address, etc)"),
314 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 298 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
@@ -341,6 +325,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
341 "Show event group information together"), 325 "Show event group information together"),
342 OPT_END() 326 OPT_END()
343 }; 327 };
328 int ret;
344 329
345 argc = parse_options(argc, argv, options, annotate_usage, 0); 330 argc = parse_options(argc, argv, options, annotate_usage, 0);
346 331
@@ -353,11 +338,16 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
353 338
354 setup_browser(true); 339 setup_browser(true);
355 340
341 annotate.session = perf_session__new(&file, false, &annotate.tool);
342 if (annotate.session == NULL)
343 return -ENOMEM;
344
356 symbol_conf.priv_size = sizeof(struct annotation); 345 symbol_conf.priv_size = sizeof(struct annotation);
357 symbol_conf.try_vmlinux_path = true; 346 symbol_conf.try_vmlinux_path = true;
358 347
359 if (symbol__init() < 0) 348 ret = symbol__init(&annotate.session->header.env);
360 return -1; 349 if (ret < 0)
350 goto out_delete;
361 351
362 if (setup_sorting() < 0) 352 if (setup_sorting() < 0)
363 usage_with_options(annotate_usage, options); 353 usage_with_options(annotate_usage, options);
@@ -373,5 +363,20 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
373 annotate.sym_hist_filter = argv[0]; 363 annotate.sym_hist_filter = argv[0];
374 } 364 }
375 365
376 return __cmd_annotate(&annotate); 366 ret = __cmd_annotate(&annotate);
367
368out_delete:
369 /*
370 * Speed up the exit process, for large files this can
371 * take quite a while.
372 *
373 * XXX Enable this when using valgrind or if we ever
374 * librarize this command.
375 *
376 * Also experiment with obstacks to see how much speed
377 * up we'll get here.
378 *
379 * perf_session__delete(session);
380 */
381 return ret;
377} 382}
diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c
index 2a2c78f80876..ac5838e0b1bd 100644
--- a/tools/perf/builtin-buildid-cache.c
+++ b/tools/perf/builtin-buildid-cache.c
@@ -246,20 +246,9 @@ static bool dso__missing_buildid_cache(struct dso *dso, int parm __maybe_unused)
246 return true; 246 return true;
247} 247}
248 248
249static int build_id_cache__fprintf_missing(const char *filename, bool force, FILE *fp) 249static int build_id_cache__fprintf_missing(struct perf_session *session, FILE *fp)
250{ 250{
251 struct perf_data_file file = {
252 .path = filename,
253 .mode = PERF_DATA_MODE_READ,
254 .force = force,
255 };
256 struct perf_session *session = perf_session__new(&file, false, NULL);
257 if (session == NULL)
258 return -1;
259
260 perf_session__fprintf_dsos_buildid(session, fp, dso__missing_buildid_cache, 0); 251 perf_session__fprintf_dsos_buildid(session, fp, dso__missing_buildid_cache, 0);
261 perf_session__delete(session);
262
263 return 0; 252 return 0;
264} 253}
265 254
@@ -303,6 +292,11 @@ int cmd_buildid_cache(int argc, const char **argv,
303 *update_name_list_str = NULL, 292 *update_name_list_str = NULL,
304 *kcore_filename; 293 *kcore_filename;
305 294
295 struct perf_data_file file = {
296 .mode = PERF_DATA_MODE_READ,
297 };
298 struct perf_session *session = NULL;
299
306 const struct option buildid_cache_options[] = { 300 const struct option buildid_cache_options[] = {
307 OPT_STRING('a', "add", &add_name_list_str, 301 OPT_STRING('a', "add", &add_name_list_str,
308 "file list", "file(s) to add"), 302 "file list", "file(s) to add"),
@@ -326,8 +320,17 @@ int cmd_buildid_cache(int argc, const char **argv,
326 argc = parse_options(argc, argv, buildid_cache_options, 320 argc = parse_options(argc, argv, buildid_cache_options,
327 buildid_cache_usage, 0); 321 buildid_cache_usage, 0);
328 322
329 if (symbol__init() < 0) 323 if (missing_filename) {
330 return -1; 324 file.path = missing_filename;
325 file.force = force;
326
327 session = perf_session__new(&file, false, NULL);
328 if (session == NULL)
329 return -1;
330 }
331
332 if (symbol__init(session ? &session->header.env : NULL) < 0)
333 goto out;
331 334
332 setup_pager(); 335 setup_pager();
333 336
@@ -370,7 +373,7 @@ int cmd_buildid_cache(int argc, const char **argv,
370 } 373 }
371 374
372 if (missing_filename) 375 if (missing_filename)
373 ret = build_id_cache__fprintf_missing(missing_filename, force, stdout); 376 ret = build_id_cache__fprintf_missing(session, stdout);
374 377
375 if (update_name_list_str) { 378 if (update_name_list_str) {
376 list = strlist__new(true, update_name_list_str); 379 list = strlist__new(true, update_name_list_str);
@@ -394,5 +397,9 @@ int cmd_buildid_cache(int argc, const char **argv,
394 build_id_cache__add_kcore(kcore_filename, debugdir, force)) 397 build_id_cache__add_kcore(kcore_filename, debugdir, force))
395 pr_warning("Couldn't add %s\n", kcore_filename); 398 pr_warning("Couldn't add %s\n", kcore_filename);
396 399
400out:
401 if (session)
402 perf_session__delete(session);
403
397 return ret; 404 return ret;
398} 405}
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index c10cc44bae19..190d0b6b28cc 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -1143,7 +1143,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused)
1143 1143
1144 argc = parse_options(argc, argv, options, diff_usage, 0); 1144 argc = parse_options(argc, argv, options, diff_usage, 0);
1145 1145
1146 if (symbol__init() < 0) 1146 if (symbol__init(NULL) < 0)
1147 return -1; 1147 return -1;
1148 1148
1149 if (data_init(argc, argv) < 0) 1149 if (data_init(argc, argv) < 0)
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index ee875cca13b1..3a62b6b3c8fd 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -23,6 +23,7 @@
23 23
24struct perf_inject { 24struct perf_inject {
25 struct perf_tool tool; 25 struct perf_tool tool;
26 struct perf_session *session;
26 bool build_ids; 27 bool build_ids;
27 bool sched_stat; 28 bool sched_stat;
28 const char *input_name; 29 const char *input_name;
@@ -340,12 +341,8 @@ static int perf_evsel__check_stype(struct perf_evsel *evsel,
340 341
341static int __cmd_inject(struct perf_inject *inject) 342static int __cmd_inject(struct perf_inject *inject)
342{ 343{
343 struct perf_session *session;
344 int ret = -EINVAL; 344 int ret = -EINVAL;
345 struct perf_data_file file = { 345 struct perf_session *session = inject->session;
346 .path = inject->input_name,
347 .mode = PERF_DATA_MODE_READ,
348 };
349 struct perf_data_file *file_out = &inject->output; 346 struct perf_data_file *file_out = &inject->output;
350 347
351 signal(SIGINT, sig_handler); 348 signal(SIGINT, sig_handler);
@@ -357,10 +354,6 @@ static int __cmd_inject(struct perf_inject *inject)
357 inject->tool.tracing_data = perf_event__repipe_tracing_data; 354 inject->tool.tracing_data = perf_event__repipe_tracing_data;
358 } 355 }
359 356
360 session = perf_session__new(&file, true, &inject->tool);
361 if (session == NULL)
362 return -ENOMEM;
363
364 if (inject->build_ids) { 357 if (inject->build_ids) {
365 inject->tool.sample = perf_event__inject_buildid; 358 inject->tool.sample = perf_event__inject_buildid;
366 } else if (inject->sched_stat) { 359 } else if (inject->sched_stat) {
@@ -396,8 +389,6 @@ static int __cmd_inject(struct perf_inject *inject)
396 perf_session__write_header(session, session->evlist, file_out->fd, true); 389 perf_session__write_header(session, session->evlist, file_out->fd, true);
397 } 390 }
398 391
399 perf_session__delete(session);
400
401 return ret; 392 return ret;
402} 393}
403 394
@@ -427,6 +418,11 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
427 .mode = PERF_DATA_MODE_WRITE, 418 .mode = PERF_DATA_MODE_WRITE,
428 }, 419 },
429 }; 420 };
421 struct perf_data_file file = {
422 .mode = PERF_DATA_MODE_READ,
423 };
424 int ret;
425
430 const struct option options[] = { 426 const struct option options[] = {
431 OPT_BOOLEAN('b', "build-ids", &inject.build_ids, 427 OPT_BOOLEAN('b', "build-ids", &inject.build_ids,
432 "Inject build-ids into the output stream"), 428 "Inject build-ids into the output stream"),
@@ -461,8 +457,17 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
461 return -1; 457 return -1;
462 } 458 }
463 459
464 if (symbol__init() < 0) 460 file.path = inject.input_name;
461 inject.session = perf_session__new(&file, true, &inject.tool);
462 if (inject.session == NULL)
463 return -ENOMEM;
464
465 if (symbol__init(&inject.session->header.env) < 0)
465 return -1; 466 return -1;
466 467
467 return __cmd_inject(&inject); 468 ret = __cmd_inject(&inject);
469
470 perf_session__delete(inject.session);
471
472 return ret;
468} 473}
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 84b82397a28e..23762187a219 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -405,10 +405,9 @@ static void sort_result(void)
405 __sort_result(&root_caller_stat, &root_caller_sorted, &caller_sort); 405 __sort_result(&root_caller_stat, &root_caller_sorted, &caller_sort);
406} 406}
407 407
408static int __cmd_kmem(void) 408static int __cmd_kmem(struct perf_session *session)
409{ 409{
410 int err = -EINVAL; 410 int err = -EINVAL;
411 struct perf_session *session;
412 const struct perf_evsel_str_handler kmem_tracepoints[] = { 411 const struct perf_evsel_str_handler kmem_tracepoints[] = {
413 { "kmem:kmalloc", perf_evsel__process_alloc_event, }, 412 { "kmem:kmalloc", perf_evsel__process_alloc_event, },
414 { "kmem:kmem_cache_alloc", perf_evsel__process_alloc_event, }, 413 { "kmem:kmem_cache_alloc", perf_evsel__process_alloc_event, },
@@ -417,31 +416,22 @@ static int __cmd_kmem(void)
417 { "kmem:kfree", perf_evsel__process_free_event, }, 416 { "kmem:kfree", perf_evsel__process_free_event, },
418 { "kmem:kmem_cache_free", perf_evsel__process_free_event, }, 417 { "kmem:kmem_cache_free", perf_evsel__process_free_event, },
419 }; 418 };
420 struct perf_data_file file = {
421 .path = input_name,
422 .mode = PERF_DATA_MODE_READ,
423 };
424
425 session = perf_session__new(&file, false, &perf_kmem);
426 if (session == NULL)
427 return -ENOMEM;
428 419
429 if (!perf_session__has_traces(session, "kmem record")) 420 if (!perf_session__has_traces(session, "kmem record"))
430 goto out_delete; 421 goto out;
431 422
432 if (perf_session__set_tracepoints_handlers(session, kmem_tracepoints)) { 423 if (perf_session__set_tracepoints_handlers(session, kmem_tracepoints)) {
433 pr_err("Initializing perf session tracepoint handlers failed\n"); 424 pr_err("Initializing perf session tracepoint handlers failed\n");
434 return -1; 425 goto out;
435 } 426 }
436 427
437 setup_pager(); 428 setup_pager();
438 err = perf_session__process_events(session, &perf_kmem); 429 err = perf_session__process_events(session, &perf_kmem);
439 if (err != 0) 430 if (err != 0)
440 goto out_delete; 431 goto out;
441 sort_result(); 432 sort_result();
442 print_result(session); 433 print_result(session);
443out_delete: 434out:
444 perf_session__delete(session);
445 return err; 435 return err;
446} 436}
447 437
@@ -688,29 +678,46 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused)
688 NULL, 678 NULL,
689 NULL 679 NULL
690 }; 680 };
681 struct perf_session *session;
682 struct perf_data_file file = {
683 .path = input_name,
684 .mode = PERF_DATA_MODE_READ,
685 };
686 int ret = -1;
687
691 argc = parse_options_subcommand(argc, argv, kmem_options, 688 argc = parse_options_subcommand(argc, argv, kmem_options,
692 kmem_subcommands, kmem_usage, 0); 689 kmem_subcommands, kmem_usage, 0);
693 690
694 if (!argc) 691 if (!argc)
695 usage_with_options(kmem_usage, kmem_options); 692 usage_with_options(kmem_usage, kmem_options);
696 693
697 symbol__init();
698
699 if (!strncmp(argv[0], "rec", 3)) { 694 if (!strncmp(argv[0], "rec", 3)) {
695 symbol__init(NULL);
700 return __cmd_record(argc, argv); 696 return __cmd_record(argc, argv);
701 } else if (!strcmp(argv[0], "stat")) { 697 }
698
699 session = perf_session__new(&file, false, &perf_kmem);
700 if (session == NULL)
701 return -ENOMEM;
702
703 symbol__init(&session->header.env);
704
705 if (!strcmp(argv[0], "stat")) {
702 if (cpu__setup_cpunode_map()) 706 if (cpu__setup_cpunode_map())
703 return -1; 707 goto out_delete;
704 708
705 if (list_empty(&caller_sort)) 709 if (list_empty(&caller_sort))
706 setup_sorting(&caller_sort, default_sort_order); 710 setup_sorting(&caller_sort, default_sort_order);
707 if (list_empty(&alloc_sort)) 711 if (list_empty(&alloc_sort))
708 setup_sorting(&alloc_sort, default_sort_order); 712 setup_sorting(&alloc_sort, default_sort_order);
709 713
710 return __cmd_kmem(); 714 ret = __cmd_kmem(session);
711 } else 715 } else
712 usage_with_options(kmem_usage, kmem_options); 716 usage_with_options(kmem_usage, kmem_options);
713 717
714 return 0; 718out_delete:
719 perf_session__delete(session);
720
721 return ret;
715} 722}
716 723
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 7ccceadcd9f8..14d03edc81c2 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -885,15 +885,11 @@ static int fd_set_nonblock(int fd)
885 return 0; 885 return 0;
886} 886}
887 887
888static 888static int perf_kvm__handle_stdin(void)
889int perf_kvm__handle_stdin(struct termios *tc_now, struct termios *tc_save)
890{ 889{
891 int c; 890 int c;
892 891
893 tcsetattr(0, TCSANOW, tc_now);
894 c = getc(stdin); 892 c = getc(stdin);
895 tcsetattr(0, TCSAFLUSH, tc_save);
896
897 if (c == 'q') 893 if (c == 'q')
898 return 1; 894 return 1;
899 895
@@ -904,7 +900,7 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm)
904{ 900{
905 struct pollfd *pollfds = NULL; 901 struct pollfd *pollfds = NULL;
906 int nr_fds, nr_stdin, ret, err = -EINVAL; 902 int nr_fds, nr_stdin, ret, err = -EINVAL;
907 struct termios tc, save; 903 struct termios save;
908 904
909 /* live flag must be set first */ 905 /* live flag must be set first */
910 kvm->live = true; 906 kvm->live = true;
@@ -919,14 +915,9 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm)
919 goto out; 915 goto out;
920 } 916 }
921 917
918 set_term_quiet_input(&save);
922 init_kvm_event_record(kvm); 919 init_kvm_event_record(kvm);
923 920
924 tcgetattr(0, &save);
925 tc = save;
926 tc.c_lflag &= ~(ICANON | ECHO);
927 tc.c_cc[VMIN] = 0;
928 tc.c_cc[VTIME] = 0;
929
930 signal(SIGINT, sig_handler); 921 signal(SIGINT, sig_handler);
931 signal(SIGTERM, sig_handler); 922 signal(SIGTERM, sig_handler);
932 923
@@ -972,7 +963,7 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm)
972 goto out; 963 goto out;
973 964
974 if (pollfds[nr_stdin].revents & POLLIN) 965 if (pollfds[nr_stdin].revents & POLLIN)
975 done = perf_kvm__handle_stdin(&tc, &save); 966 done = perf_kvm__handle_stdin();
976 967
977 if (!rc && !done) 968 if (!rc && !done)
978 err = poll(pollfds, nr_fds, 100); 969 err = poll(pollfds, nr_fds, 100);
@@ -989,6 +980,7 @@ out:
989 if (kvm->timerfd >= 0) 980 if (kvm->timerfd >= 0)
990 close(kvm->timerfd); 981 close(kvm->timerfd);
991 982
983 tcsetattr(0, TCSAFLUSH, &save);
992 free(pollfds); 984 free(pollfds);
993 return err; 985 return err;
994} 986}
@@ -1072,6 +1064,8 @@ static int read_events(struct perf_kvm_stat *kvm)
1072 return -EINVAL; 1064 return -EINVAL;
1073 } 1065 }
1074 1066
1067 symbol__init(&kvm->session->header.env);
1068
1075 if (!perf_session__has_traces(kvm->session, "kvm record")) 1069 if (!perf_session__has_traces(kvm->session, "kvm record"))
1076 return -EINVAL; 1070 return -EINVAL;
1077 1071
@@ -1201,8 +1195,6 @@ kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv)
1201 NULL 1195 NULL
1202 }; 1196 };
1203 1197
1204 symbol__init();
1205
1206 if (argc) { 1198 if (argc) {
1207 argc = parse_options(argc, argv, 1199 argc = parse_options(argc, argv,
1208 kvm_events_report_options, 1200 kvm_events_report_options,
@@ -1322,7 +1314,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
1322 kvm->opts.target.uid_str = NULL; 1314 kvm->opts.target.uid_str = NULL;
1323 kvm->opts.target.uid = UINT_MAX; 1315 kvm->opts.target.uid = UINT_MAX;
1324 1316
1325 symbol__init(); 1317 symbol__init(NULL);
1326 disable_buildid_cache(); 1318 disable_buildid_cache();
1327 1319
1328 use_browser = 0; 1320 use_browser = 0;
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index c8122d323621..92790ed7af45 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -865,6 +865,8 @@ static int __cmd_report(bool display_info)
865 return -ENOMEM; 865 return -ENOMEM;
866 } 866 }
867 867
868 symbol__init(&session->header.env);
869
868 if (!perf_session__has_traces(session, "lock record")) 870 if (!perf_session__has_traces(session, "lock record"))
869 goto out_delete; 871 goto out_delete;
870 872
@@ -974,7 +976,6 @@ int cmd_lock(int argc, const char **argv, const char *prefix __maybe_unused)
974 unsigned int i; 976 unsigned int i;
975 int rc = 0; 977 int rc = 0;
976 978
977 symbol__init();
978 for (i = 0; i < LOCKHASH_SIZE; i++) 979 for (i = 0; i < LOCKHASH_SIZE; i++)
979 INIT_LIST_HEAD(lockhash_table + i); 980 INIT_LIST_HEAD(lockhash_table + i);
980 981
diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c
index 80e57c84adef..8b4a87fe3858 100644
--- a/tools/perf/builtin-mem.c
+++ b/tools/perf/builtin-mem.c
@@ -133,7 +133,7 @@ static int report_raw_events(struct perf_mem *mem)
133 goto out_delete; 133 goto out_delete;
134 } 134 }
135 135
136 if (symbol__init() < 0) 136 if (symbol__init(&session->header.env) < 0)
137 return -1; 137 return -1;
138 138
139 printf("# PID, TID, IP, ADDR, LOCAL WEIGHT, DSRC, SYMBOL\n"); 139 printf("# PID, TID, IP, ADDR, LOCAL WEIGHT, DSRC, SYMBOL\n");
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index ca0251e8470d..4db670d4b8da 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -908,7 +908,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
908 usage_with_options(record_usage, record_options); 908 usage_with_options(record_usage, record_options);
909 } 909 }
910 910
911 symbol__init(); 911 symbol__init(NULL);
912 912
913 if (symbol_conf.kptr_restrict) 913 if (symbol_conf.kptr_restrict)
914 pr_warning( 914 pr_warning(
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 041e93da13e4..3da59a87ec7c 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -730,7 +730,7 @@ repeat:
730 has_br_stack = perf_header__has_feat(&session->header, 730 has_br_stack = perf_header__has_feat(&session->header,
731 HEADER_BRANCH_STACK); 731 HEADER_BRANCH_STACK);
732 732
733 if (branch_mode == -1 && has_br_stack) { 733 if ((branch_mode == -1 && has_br_stack) || branch_mode == 1) {
734 sort__mode = SORT_MODE__BRANCH; 734 sort__mode = SORT_MODE__BRANCH;
735 symbol_conf.cumulate_callchain = false; 735 symbol_conf.cumulate_callchain = false;
736 } 736 }
@@ -798,7 +798,7 @@ repeat:
798 } 798 }
799 } 799 }
800 800
801 if (symbol__init() < 0) 801 if (symbol__init(&session->header.env) < 0)
802 goto error; 802 goto error;
803 803
804 if (argc) { 804 if (argc) {
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 7c16aeb6b675..f5874a27b346 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1462,6 +1462,8 @@ static int perf_sched__read_events(struct perf_sched *sched,
1462 return -1; 1462 return -1;
1463 } 1463 }
1464 1464
1465 symbol__init(&session->header.env);
1466
1465 if (perf_session__set_tracepoints_handlers(session, handlers)) 1467 if (perf_session__set_tracepoints_handlers(session, handlers))
1466 goto out_delete; 1468 goto out_delete;
1467 1469
@@ -1747,7 +1749,6 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
1747 if (!strcmp(argv[0], "script")) 1749 if (!strcmp(argv[0], "script"))
1748 return cmd_script(argc, argv, prefix); 1750 return cmd_script(argc, argv, prefix);
1749 1751
1750 symbol__init();
1751 if (!strncmp(argv[0], "rec", 3)) { 1752 if (!strncmp(argv[0], "rec", 3)) {
1752 return __cmd_record(argc, argv); 1753 return __cmd_record(argc, argv);
1753 } else if (!strncmp(argv[0], "lat", 3)) { 1754 } else if (!strncmp(argv[0], "lat", 3)) {
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 868c17d09762..c1b7029884b1 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -184,10 +184,6 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
184 if (perf_evsel__check_stype(evsel, PERF_SAMPLE_IP, "IP", 184 if (perf_evsel__check_stype(evsel, PERF_SAMPLE_IP, "IP",
185 PERF_OUTPUT_IP)) 185 PERF_OUTPUT_IP))
186 return -EINVAL; 186 return -EINVAL;
187
188 if (!no_callchain &&
189 !(attr->sample_type & PERF_SAMPLE_CALLCHAIN))
190 symbol_conf.use_callchain = false;
191 } 187 }
192 188
193 if (PRINT_FIELD(ADDR) && 189 if (PRINT_FIELD(ADDR) &&
@@ -290,6 +286,19 @@ static int perf_session__check_output_opt(struct perf_session *session)
290 set_print_ip_opts(&evsel->attr); 286 set_print_ip_opts(&evsel->attr);
291 } 287 }
292 288
289 if (!no_callchain) {
290 bool use_callchain = false;
291
292 evlist__for_each(session->evlist, evsel) {
293 if (evsel->attr.sample_type & PERF_SAMPLE_CALLCHAIN) {
294 use_callchain = true;
295 break;
296 }
297 }
298 if (!use_callchain)
299 symbol_conf.use_callchain = false;
300 }
301
293 /* 302 /*
294 * set default for tracepoints to print symbols only 303 * set default for tracepoints to print symbols only
295 * if callchains are present 304 * if callchains are present
@@ -1471,12 +1480,13 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1471 bool show_full_info = false; 1480 bool show_full_info = false;
1472 bool header = false; 1481 bool header = false;
1473 bool header_only = false; 1482 bool header_only = false;
1483 bool script_started = false;
1474 char *rec_script_path = NULL; 1484 char *rec_script_path = NULL;
1475 char *rep_script_path = NULL; 1485 char *rep_script_path = NULL;
1476 struct perf_session *session; 1486 struct perf_session *session;
1477 char *script_path = NULL; 1487 char *script_path = NULL;
1478 const char **__argv; 1488 const char **__argv;
1479 int i, j, err; 1489 int i, j, err = 0;
1480 struct perf_script script = { 1490 struct perf_script script = {
1481 .tool = { 1491 .tool = {
1482 .sample = process_sample_event, 1492 .sample = process_sample_event,
@@ -1718,8 +1728,6 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1718 exit(-1); 1728 exit(-1);
1719 } 1729 }
1720 1730
1721 if (symbol__init() < 0)
1722 return -1;
1723 if (!script_name) 1731 if (!script_name)
1724 setup_pager(); 1732 setup_pager();
1725 1733
@@ -1730,14 +1738,18 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1730 if (header || header_only) { 1738 if (header || header_only) {
1731 perf_session__fprintf_info(session, stdout, show_full_info); 1739 perf_session__fprintf_info(session, stdout, show_full_info);
1732 if (header_only) 1740 if (header_only)
1733 return 0; 1741 goto out_delete;
1734 } 1742 }
1735 1743
1744 if (symbol__init(&session->header.env) < 0)
1745 goto out_delete;
1746
1736 script.session = session; 1747 script.session = session;
1737 1748
1738 if (cpu_list) { 1749 if (cpu_list) {
1739 if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap)) 1750 err = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap);
1740 return -1; 1751 if (err < 0)
1752 goto out_delete;
1741 } 1753 }
1742 1754
1743 if (!no_callchain) 1755 if (!no_callchain)
@@ -1752,53 +1764,60 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1752 if (output_set_by_user()) { 1764 if (output_set_by_user()) {
1753 fprintf(stderr, 1765 fprintf(stderr,
1754 "custom fields not supported for generated scripts"); 1766 "custom fields not supported for generated scripts");
1755 return -1; 1767 err = -EINVAL;
1768 goto out_delete;
1756 } 1769 }
1757 1770
1758 input = open(file.path, O_RDONLY); /* input_name */ 1771 input = open(file.path, O_RDONLY); /* input_name */
1759 if (input < 0) { 1772 if (input < 0) {
1773 err = -errno;
1760 perror("failed to open file"); 1774 perror("failed to open file");
1761 return -1; 1775 goto out_delete;
1762 } 1776 }
1763 1777
1764 err = fstat(input, &perf_stat); 1778 err = fstat(input, &perf_stat);
1765 if (err < 0) { 1779 if (err < 0) {
1766 perror("failed to stat file"); 1780 perror("failed to stat file");
1767 return -1; 1781 goto out_delete;
1768 } 1782 }
1769 1783
1770 if (!perf_stat.st_size) { 1784 if (!perf_stat.st_size) {
1771 fprintf(stderr, "zero-sized file, nothing to do!\n"); 1785 fprintf(stderr, "zero-sized file, nothing to do!\n");
1772 return 0; 1786 goto out_delete;
1773 } 1787 }
1774 1788
1775 scripting_ops = script_spec__lookup(generate_script_lang); 1789 scripting_ops = script_spec__lookup(generate_script_lang);
1776 if (!scripting_ops) { 1790 if (!scripting_ops) {
1777 fprintf(stderr, "invalid language specifier"); 1791 fprintf(stderr, "invalid language specifier");
1778 return -1; 1792 err = -ENOENT;
1793 goto out_delete;
1779 } 1794 }
1780 1795
1781 err = scripting_ops->generate_script(session->tevent.pevent, 1796 err = scripting_ops->generate_script(session->tevent.pevent,
1782 "perf-script"); 1797 "perf-script");
1783 goto out; 1798 goto out_delete;
1784 } 1799 }
1785 1800
1786 if (script_name) { 1801 if (script_name) {
1787 err = scripting_ops->start_script(script_name, argc, argv); 1802 err = scripting_ops->start_script(script_name, argc, argv);
1788 if (err) 1803 if (err)
1789 goto out; 1804 goto out_delete;
1790 pr_debug("perf script started with script %s\n\n", script_name); 1805 pr_debug("perf script started with script %s\n\n", script_name);
1806 script_started = true;
1791 } 1807 }
1792 1808
1793 1809
1794 err = perf_session__check_output_opt(session); 1810 err = perf_session__check_output_opt(session);
1795 if (err < 0) 1811 if (err < 0)
1796 goto out; 1812 goto out_delete;
1797 1813
1798 err = __cmd_script(&script); 1814 err = __cmd_script(&script);
1799 1815
1816out_delete:
1800 perf_session__delete(session); 1817 perf_session__delete(session);
1801 cleanup_scripting(); 1818
1819 if (script_started)
1820 cleanup_scripting();
1802out: 1821out:
1803 return err; 1822 return err;
1804} 1823}
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 912e3b5bb22b..48eea6cd2f5b 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -1607,6 +1607,8 @@ static int __cmd_timechart(struct timechart *tchart, const char *output_name)
1607 if (session == NULL) 1607 if (session == NULL)
1608 return -ENOMEM; 1608 return -ENOMEM;
1609 1609
1610 symbol__init(&session->header.env);
1611
1610 (void)perf_header__process_sections(&session->header, 1612 (void)perf_header__process_sections(&session->header,
1611 perf_data_file__fd(session->file), 1613 perf_data_file__fd(session->file),
1612 tchart, 1614 tchart,
@@ -1982,8 +1984,6 @@ int cmd_timechart(int argc, const char **argv,
1982 return -1; 1984 return -1;
1983 } 1985 }
1984 1986
1985 symbol__init();
1986
1987 if (argc && !strncmp(argv[0], "rec", 3)) { 1987 if (argc && !strncmp(argv[0], "rec", 3)) {
1988 argc = parse_options(argc, argv, record_options, record_usage, 1988 argc = parse_options(argc, argv, record_options, record_usage,
1989 PARSE_OPT_STOP_AT_NON_OPTION); 1989 PARSE_OPT_STOP_AT_NON_OPTION);
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index bde216b2071c..87a6615a40fa 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -276,11 +276,17 @@ static void perf_top__print_sym_table(struct perf_top *top)
276 return; 276 return;
277 } 277 }
278 278
279 if (top->zero) {
280 hists__delete_entries(&top->sym_evsel->hists);
281 } else {
282 hists__decay_entries(&top->sym_evsel->hists,
283 top->hide_user_symbols,
284 top->hide_kernel_symbols);
285 }
286
279 hists__collapse_resort(&top->sym_evsel->hists, NULL); 287 hists__collapse_resort(&top->sym_evsel->hists, NULL);
280 hists__output_resort(&top->sym_evsel->hists); 288 hists__output_resort(&top->sym_evsel->hists);
281 hists__decay_entries(&top->sym_evsel->hists, 289
282 top->hide_user_symbols,
283 top->hide_kernel_symbols);
284 hists__output_recalc_col_len(&top->sym_evsel->hists, 290 hists__output_recalc_col_len(&top->sym_evsel->hists,
285 top->print_entries - printed); 291 top->print_entries - printed);
286 putchar('\n'); 292 putchar('\n');
@@ -542,11 +548,16 @@ static void perf_top__sort_new_samples(void *arg)
542 if (t->evlist->selected != NULL) 548 if (t->evlist->selected != NULL)
543 t->sym_evsel = t->evlist->selected; 549 t->sym_evsel = t->evlist->selected;
544 550
551 if (t->zero) {
552 hists__delete_entries(&t->sym_evsel->hists);
553 } else {
554 hists__decay_entries(&t->sym_evsel->hists,
555 t->hide_user_symbols,
556 t->hide_kernel_symbols);
557 }
558
545 hists__collapse_resort(&t->sym_evsel->hists, NULL); 559 hists__collapse_resort(&t->sym_evsel->hists, NULL);
546 hists__output_resort(&t->sym_evsel->hists); 560 hists__output_resort(&t->sym_evsel->hists);
547 hists__decay_entries(&t->sym_evsel->hists,
548 t->hide_user_symbols,
549 t->hide_kernel_symbols);
550} 561}
551 562
552static void *display_thread_tui(void *arg) 563static void *display_thread_tui(void *arg)
@@ -577,23 +588,32 @@ static void *display_thread_tui(void *arg)
577 return NULL; 588 return NULL;
578} 589}
579 590
591static void display_sig(int sig __maybe_unused)
592{
593 done = 1;
594}
595
596static void display_setup_sig(void)
597{
598 signal(SIGSEGV, display_sig);
599 signal(SIGFPE, display_sig);
600 signal(SIGINT, display_sig);
601 signal(SIGQUIT, display_sig);
602 signal(SIGTERM, display_sig);
603}
604
580static void *display_thread(void *arg) 605static void *display_thread(void *arg)
581{ 606{
582 struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; 607 struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
583 struct termios tc, save; 608 struct termios save;
584 struct perf_top *top = arg; 609 struct perf_top *top = arg;
585 int delay_msecs, c; 610 int delay_msecs, c;
586 611
587 tcgetattr(0, &save); 612 display_setup_sig();
588 tc = save;
589 tc.c_lflag &= ~(ICANON | ECHO);
590 tc.c_cc[VMIN] = 0;
591 tc.c_cc[VTIME] = 0;
592
593 pthread__unblock_sigwinch(); 613 pthread__unblock_sigwinch();
594repeat: 614repeat:
595 delay_msecs = top->delay_secs * 1000; 615 delay_msecs = top->delay_secs * 1000;
596 tcsetattr(0, TCSANOW, &tc); 616 set_term_quiet_input(&save);
597 /* trash return*/ 617 /* trash return*/
598 getc(stdin); 618 getc(stdin);
599 619
@@ -620,13 +640,16 @@ repeat:
620 } 640 }
621 } 641 }
622 642
643 tcsetattr(0, TCSAFLUSH, &save);
623 return NULL; 644 return NULL;
624} 645}
625 646
626static int symbol_filter(struct map *map __maybe_unused, struct symbol *sym) 647static int symbol_filter(struct map *map, struct symbol *sym)
627{ 648{
628 const char *name = sym->name; 649 const char *name = sym->name;
629 650
651 if (!map->dso->kernel)
652 return 0;
630 /* 653 /*
631 * ppc64 uses function descriptors and appends a '.' to the 654 * ppc64 uses function descriptors and appends a '.' to the
632 * start of every instruction address. Remove it. 655 * start of every instruction address. Remove it.
@@ -963,7 +986,7 @@ static int __cmd_top(struct perf_top *top)
963 param.sched_priority = top->realtime_prio; 986 param.sched_priority = top->realtime_prio;
964 if (sched_setscheduler(0, SCHED_FIFO, &param)) { 987 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
965 ui__error("Could not set realtime priority.\n"); 988 ui__error("Could not set realtime priority.\n");
966 goto out_delete; 989 goto out_join;
967 } 990 }
968 } 991 }
969 992
@@ -977,6 +1000,8 @@ static int __cmd_top(struct perf_top *top)
977 } 1000 }
978 1001
979 ret = 0; 1002 ret = 0;
1003out_join:
1004 pthread_join(thread, NULL);
980out_delete: 1005out_delete:
981 perf_session__delete(top->session); 1006 perf_session__delete(top->session);
982 top->session = NULL; 1007 top->session = NULL;
@@ -1220,7 +1245,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
1220 symbol_conf.priv_size = sizeof(struct annotation); 1245 symbol_conf.priv_size = sizeof(struct annotation);
1221 1246
1222 symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL); 1247 symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
1223 if (symbol__init() < 0) 1248 if (symbol__init(NULL) < 0)
1224 return -1; 1249 return -1;
1225 1250
1226 sort__setup_elide(stdout); 1251 sort__setup_elide(stdout);
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 36ae51d61be2..d080b9cf0354 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -402,6 +402,31 @@ static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size,
402 402
403#define SCA_MMAP_FLAGS syscall_arg__scnprintf_mmap_flags 403#define SCA_MMAP_FLAGS syscall_arg__scnprintf_mmap_flags
404 404
405static size_t syscall_arg__scnprintf_mremap_flags(char *bf, size_t size,
406 struct syscall_arg *arg)
407{
408 int printed = 0, flags = arg->val;
409
410#define P_MREMAP_FLAG(n) \
411 if (flags & MREMAP_##n) { \
412 printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
413 flags &= ~MREMAP_##n; \
414 }
415
416 P_MREMAP_FLAG(MAYMOVE);
417#ifdef MREMAP_FIXED
418 P_MREMAP_FLAG(FIXED);
419#endif
420#undef P_MREMAP_FLAG
421
422 if (flags)
423 printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
424
425 return printed;
426}
427
428#define SCA_MREMAP_FLAGS syscall_arg__scnprintf_mremap_flags
429
405static size_t syscall_arg__scnprintf_madvise_behavior(char *bf, size_t size, 430static size_t syscall_arg__scnprintf_madvise_behavior(char *bf, size_t size,
406 struct syscall_arg *arg) 431 struct syscall_arg *arg)
407{ 432{
@@ -1004,6 +1029,7 @@ static struct syscall_fmt {
1004 [2] = SCA_MMAP_PROT, /* prot */ }, }, 1029 [2] = SCA_MMAP_PROT, /* prot */ }, },
1005 { .name = "mremap", .hexret = true, 1030 { .name = "mremap", .hexret = true,
1006 .arg_scnprintf = { [0] = SCA_HEX, /* addr */ 1031 .arg_scnprintf = { [0] = SCA_HEX, /* addr */
1032 [3] = SCA_MREMAP_FLAGS, /* flags */
1007 [4] = SCA_HEX, /* new_addr */ }, }, 1033 [4] = SCA_HEX, /* new_addr */ }, },
1008 { .name = "munlock", .errmsg = true, 1034 { .name = "munlock", .errmsg = true,
1009 .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, }, 1035 .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
@@ -1385,7 +1411,7 @@ static int trace__tool_process(struct perf_tool *tool,
1385 1411
1386static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist) 1412static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
1387{ 1413{
1388 int err = symbol__init(); 1414 int err = symbol__init(NULL);
1389 1415
1390 if (err) 1416 if (err)
1391 return err; 1417 return err;
@@ -2215,13 +2241,13 @@ static int trace__replay(struct trace *trace)
2215 /* add tid to output */ 2241 /* add tid to output */
2216 trace->multiple_threads = true; 2242 trace->multiple_threads = true;
2217 2243
2218 if (symbol__init() < 0)
2219 return -1;
2220
2221 session = perf_session__new(&file, false, &trace->tool); 2244 session = perf_session__new(&file, false, &trace->tool);
2222 if (session == NULL) 2245 if (session == NULL)
2223 return -ENOMEM; 2246 return -ENOMEM;
2224 2247
2248 if (symbol__init(&session->header.env) < 0)
2249 goto out;
2250
2225 trace->host = &session->machines.host; 2251 trace->host = &session->machines.host;
2226 2252
2227 err = perf_session__set_tracepoints_handlers(session, handlers); 2253 err = perf_session__set_tracepoints_handlers(session, handlers);
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 6f8b01bc6033..c6796d22423a 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -297,7 +297,7 @@ int cmd_test(int argc, const char **argv, const char *prefix __maybe_unused)
297 symbol_conf.sort_by_name = true; 297 symbol_conf.sort_by_name = true;
298 symbol_conf.try_vmlinux_path = true; 298 symbol_conf.try_vmlinux_path = true;
299 299
300 if (symbol__init() < 0) 300 if (symbol__init(NULL) < 0)
301 return -1; 301 return -1;
302 302
303 if (skip != NULL) 303 if (skip != NULL)
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 045c1e16ac59..4892480e8298 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -10,6 +10,7 @@
10#include "../../util/pstack.h" 10#include "../../util/pstack.h"
11#include "../../util/sort.h" 11#include "../../util/sort.h"
12#include "../../util/util.h" 12#include "../../util/util.h"
13#include "../../util/top.h"
13#include "../../arch/common.h" 14#include "../../arch/common.h"
14 15
15#include "../browser.h" 16#include "../browser.h"
@@ -228,8 +229,10 @@ static void callchain_node__init_have_children(struct callchain_node *node)
228{ 229{
229 struct callchain_list *chain; 230 struct callchain_list *chain;
230 231
231 list_for_each_entry(chain, &node->val, list) 232 if (!list_empty(&node->val)) {
233 chain = list_entry(node->val.prev, struct callchain_list, list);
232 chain->ms.has_children = !RB_EMPTY_ROOT(&node->rb_root); 234 chain->ms.has_children = !RB_EMPTY_ROOT(&node->rb_root);
235 }
233 236
234 callchain_node__init_have_children_rb_tree(node); 237 callchain_node__init_have_children_rb_tree(node);
235} 238}
@@ -1530,6 +1533,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
1530 "P Print histograms to perf.hist.N\n" 1533 "P Print histograms to perf.hist.N\n"
1531 "t Zoom into current Thread\n" 1534 "t Zoom into current Thread\n"
1532 "V Verbose (DSO names in callchains, etc)\n" 1535 "V Verbose (DSO names in callchains, etc)\n"
1536 "z Toggle zeroing of samples\n"
1533 "/ Filter symbol by name"; 1537 "/ Filter symbol by name";
1534 1538
1535 if (browser == NULL) 1539 if (browser == NULL)
@@ -1630,6 +1634,13 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
1630 case 'F': 1634 case 'F':
1631 symbol_conf.filter_relative ^= 1; 1635 symbol_conf.filter_relative ^= 1;
1632 continue; 1636 continue;
1637 case 'z':
1638 if (!is_report_browser(hbt)) {
1639 struct perf_top *top = hbt->arg;
1640
1641 top->zero = !top->zero;
1642 }
1643 continue;
1633 case K_F1: 1644 case K_F1:
1634 case 'h': 1645 case 'h':
1635 case '?': 1646 case '?':
diff --git a/tools/perf/util/cloexec.c b/tools/perf/util/cloexec.c
index 5073c01af618..4945aa56a017 100644
--- a/tools/perf/util/cloexec.c
+++ b/tools/perf/util/cloexec.c
@@ -1,3 +1,4 @@
1#include <sched.h>
1#include "util.h" 2#include "util.h"
2#include "../perf.h" 3#include "../perf.h"
3#include "cloexec.h" 4#include "cloexec.h"
@@ -11,13 +12,27 @@ static int perf_flag_probe(void)
11 struct perf_event_attr attr = { 12 struct perf_event_attr attr = {
12 .type = PERF_TYPE_SOFTWARE, 13 .type = PERF_TYPE_SOFTWARE,
13 .config = PERF_COUNT_SW_CPU_CLOCK, 14 .config = PERF_COUNT_SW_CPU_CLOCK,
15 .exclude_kernel = 1,
14 }; 16 };
15 int fd; 17 int fd;
16 int err; 18 int err;
19 int cpu;
20 pid_t pid = -1;
17 21
18 /* check cloexec flag */ 22 cpu = sched_getcpu();
19 fd = sys_perf_event_open(&attr, 0, -1, -1, 23 if (cpu < 0)
20 PERF_FLAG_FD_CLOEXEC); 24 cpu = 0;
25
26 while (1) {
27 /* check cloexec flag */
28 fd = sys_perf_event_open(&attr, pid, cpu, -1,
29 PERF_FLAG_FD_CLOEXEC);
30 if (fd < 0 && pid == -1 && errno == EACCES) {
31 pid = 0;
32 continue;
33 }
34 break;
35 }
21 err = errno; 36 err = errno;
22 37
23 if (fd >= 0) { 38 if (fd >= 0) {
@@ -30,7 +45,7 @@ static int perf_flag_probe(void)
30 err, strerror(err)); 45 err, strerror(err));
31 46
32 /* not supported, confirm error related to PERF_FLAG_FD_CLOEXEC */ 47 /* not supported, confirm error related to PERF_FLAG_FD_CLOEXEC */
33 fd = sys_perf_event_open(&attr, 0, -1, -1, 0); 48 fd = sys_perf_event_open(&attr, pid, cpu, -1, 0);
34 err = errno; 49 err = errno;
35 50
36 if (WARN_ONCE(fd < 0 && err != EBUSY, 51 if (WARN_ONCE(fd < 0 && err != EBUSY,
diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c
index f9e777629e21..b2bb59df65e1 100644
--- a/tools/perf/util/comm.c
+++ b/tools/perf/util/comm.c
@@ -74,7 +74,7 @@ static struct comm_str *comm_str__findnew(const char *str, struct rb_root *root)
74 return new; 74 return new;
75} 75}
76 76
77struct comm *comm__new(const char *str, u64 timestamp) 77struct comm *comm__new(const char *str, u64 timestamp, bool exec)
78{ 78{
79 struct comm *comm = zalloc(sizeof(*comm)); 79 struct comm *comm = zalloc(sizeof(*comm));
80 80
@@ -82,6 +82,7 @@ struct comm *comm__new(const char *str, u64 timestamp)
82 return NULL; 82 return NULL;
83 83
84 comm->start = timestamp; 84 comm->start = timestamp;
85 comm->exec = exec;
85 86
86 comm->comm_str = comm_str__findnew(str, &comm_str_root); 87 comm->comm_str = comm_str__findnew(str, &comm_str_root);
87 if (!comm->comm_str) { 88 if (!comm->comm_str) {
@@ -94,7 +95,7 @@ struct comm *comm__new(const char *str, u64 timestamp)
94 return comm; 95 return comm;
95} 96}
96 97
97int comm__override(struct comm *comm, const char *str, u64 timestamp) 98int comm__override(struct comm *comm, const char *str, u64 timestamp, bool exec)
98{ 99{
99 struct comm_str *new, *old = comm->comm_str; 100 struct comm_str *new, *old = comm->comm_str;
100 101
@@ -106,6 +107,8 @@ int comm__override(struct comm *comm, const char *str, u64 timestamp)
106 comm_str__put(old); 107 comm_str__put(old);
107 comm->comm_str = new; 108 comm->comm_str = new;
108 comm->start = timestamp; 109 comm->start = timestamp;
110 if (exec)
111 comm->exec = true;
109 112
110 return 0; 113 return 0;
111} 114}
diff --git a/tools/perf/util/comm.h b/tools/perf/util/comm.h
index fac5bd51befc..51c10ab257f8 100644
--- a/tools/perf/util/comm.h
+++ b/tools/perf/util/comm.h
@@ -11,11 +11,13 @@ struct comm {
11 struct comm_str *comm_str; 11 struct comm_str *comm_str;
12 u64 start; 12 u64 start;
13 struct list_head list; 13 struct list_head list;
14 bool exec;
14}; 15};
15 16
16void comm__free(struct comm *comm); 17void comm__free(struct comm *comm);
17struct comm *comm__new(const char *str, u64 timestamp); 18struct comm *comm__new(const char *str, u64 timestamp, bool exec);
18const char *comm__str(const struct comm *comm); 19const char *comm__str(const struct comm *comm);
19int comm__override(struct comm *comm, const char *str, u64 timestamp); 20int comm__override(struct comm *comm, const char *str, u64 timestamp,
21 bool exec);
20 22
21#endif /* __PERF_COMM_H */ 23#endif /* __PERF_COMM_H */
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 94d6976180da..7eb7107731ec 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -156,6 +156,8 @@ struct perf_sample {
156 u32 cpu; 156 u32 cpu;
157 u32 raw_size; 157 u32 raw_size;
158 u64 data_src; 158 u64 data_src;
159 u32 flags;
160 u16 insn_len;
159 void *raw_data; 161 void *raw_data;
160 struct ip_callchain *callchain; 162 struct ip_callchain *callchain;
161 struct branch_stack *branch_stack; 163 struct branch_stack *branch_stack;
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 3b366c085021..5dcd28c79c6e 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -122,6 +122,7 @@ void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry)
122{ 122{
123 list_add_tail(&entry->node, &evlist->entries); 123 list_add_tail(&entry->node, &evlist->entries);
124 entry->idx = evlist->nr_entries; 124 entry->idx = evlist->nr_entries;
125 entry->tracking = !entry->idx;
125 126
126 if (!evlist->nr_entries++) 127 if (!evlist->nr_entries++)
127 perf_evlist__set_id_pos(evlist); 128 perf_evlist__set_id_pos(evlist);
@@ -265,17 +266,27 @@ int perf_evlist__add_newtp(struct perf_evlist *evlist,
265 return 0; 266 return 0;
266} 267}
267 268
269static int perf_evlist__nr_threads(struct perf_evlist *evlist,
270 struct perf_evsel *evsel)
271{
272 if (evsel->system_wide)
273 return 1;
274 else
275 return thread_map__nr(evlist->threads);
276}
277
268void perf_evlist__disable(struct perf_evlist *evlist) 278void perf_evlist__disable(struct perf_evlist *evlist)
269{ 279{
270 int cpu, thread; 280 int cpu, thread;
271 struct perf_evsel *pos; 281 struct perf_evsel *pos;
272 int nr_cpus = cpu_map__nr(evlist->cpus); 282 int nr_cpus = cpu_map__nr(evlist->cpus);
273 int nr_threads = thread_map__nr(evlist->threads); 283 int nr_threads;
274 284
275 for (cpu = 0; cpu < nr_cpus; cpu++) { 285 for (cpu = 0; cpu < nr_cpus; cpu++) {
276 evlist__for_each(evlist, pos) { 286 evlist__for_each(evlist, pos) {
277 if (!perf_evsel__is_group_leader(pos) || !pos->fd) 287 if (!perf_evsel__is_group_leader(pos) || !pos->fd)
278 continue; 288 continue;
289 nr_threads = perf_evlist__nr_threads(evlist, pos);
279 for (thread = 0; thread < nr_threads; thread++) 290 for (thread = 0; thread < nr_threads; thread++)
280 ioctl(FD(pos, cpu, thread), 291 ioctl(FD(pos, cpu, thread),
281 PERF_EVENT_IOC_DISABLE, 0); 292 PERF_EVENT_IOC_DISABLE, 0);
@@ -288,12 +299,13 @@ void perf_evlist__enable(struct perf_evlist *evlist)
288 int cpu, thread; 299 int cpu, thread;
289 struct perf_evsel *pos; 300 struct perf_evsel *pos;
290 int nr_cpus = cpu_map__nr(evlist->cpus); 301 int nr_cpus = cpu_map__nr(evlist->cpus);
291 int nr_threads = thread_map__nr(evlist->threads); 302 int nr_threads;
292 303
293 for (cpu = 0; cpu < nr_cpus; cpu++) { 304 for (cpu = 0; cpu < nr_cpus; cpu++) {
294 evlist__for_each(evlist, pos) { 305 evlist__for_each(evlist, pos) {
295 if (!perf_evsel__is_group_leader(pos) || !pos->fd) 306 if (!perf_evsel__is_group_leader(pos) || !pos->fd)
296 continue; 307 continue;
308 nr_threads = perf_evlist__nr_threads(evlist, pos);
297 for (thread = 0; thread < nr_threads; thread++) 309 for (thread = 0; thread < nr_threads; thread++)
298 ioctl(FD(pos, cpu, thread), 310 ioctl(FD(pos, cpu, thread),
299 PERF_EVENT_IOC_ENABLE, 0); 311 PERF_EVENT_IOC_ENABLE, 0);
@@ -305,12 +317,14 @@ int perf_evlist__disable_event(struct perf_evlist *evlist,
305 struct perf_evsel *evsel) 317 struct perf_evsel *evsel)
306{ 318{
307 int cpu, thread, err; 319 int cpu, thread, err;
320 int nr_cpus = cpu_map__nr(evlist->cpus);
321 int nr_threads = perf_evlist__nr_threads(evlist, evsel);
308 322
309 if (!evsel->fd) 323 if (!evsel->fd)
310 return 0; 324 return 0;
311 325
312 for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { 326 for (cpu = 0; cpu < nr_cpus; cpu++) {
313 for (thread = 0; thread < evlist->threads->nr; thread++) { 327 for (thread = 0; thread < nr_threads; thread++) {
314 err = ioctl(FD(evsel, cpu, thread), 328 err = ioctl(FD(evsel, cpu, thread),
315 PERF_EVENT_IOC_DISABLE, 0); 329 PERF_EVENT_IOC_DISABLE, 0);
316 if (err) 330 if (err)
@@ -324,12 +338,14 @@ int perf_evlist__enable_event(struct perf_evlist *evlist,
324 struct perf_evsel *evsel) 338 struct perf_evsel *evsel)
325{ 339{
326 int cpu, thread, err; 340 int cpu, thread, err;
341 int nr_cpus = cpu_map__nr(evlist->cpus);
342 int nr_threads = perf_evlist__nr_threads(evlist, evsel);
327 343
328 if (!evsel->fd) 344 if (!evsel->fd)
329 return -EINVAL; 345 return -EINVAL;
330 346
331 for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { 347 for (cpu = 0; cpu < nr_cpus; cpu++) {
332 for (thread = 0; thread < evlist->threads->nr; thread++) { 348 for (thread = 0; thread < nr_threads; thread++) {
333 err = ioctl(FD(evsel, cpu, thread), 349 err = ioctl(FD(evsel, cpu, thread),
334 PERF_EVENT_IOC_ENABLE, 0); 350 PERF_EVENT_IOC_ENABLE, 0);
335 if (err) 351 if (err)
@@ -339,11 +355,67 @@ int perf_evlist__enable_event(struct perf_evlist *evlist,
339 return 0; 355 return 0;
340} 356}
341 357
358static int perf_evlist__enable_event_cpu(struct perf_evlist *evlist,
359 struct perf_evsel *evsel, int cpu)
360{
361 int thread, err;
362 int nr_threads = perf_evlist__nr_threads(evlist, evsel);
363
364 if (!evsel->fd)
365 return -EINVAL;
366
367 for (thread = 0; thread < nr_threads; thread++) {
368 err = ioctl(FD(evsel, cpu, thread),
369 PERF_EVENT_IOC_ENABLE, 0);
370 if (err)
371 return err;
372 }
373 return 0;
374}
375
376static int perf_evlist__enable_event_thread(struct perf_evlist *evlist,
377 struct perf_evsel *evsel,
378 int thread)
379{
380 int cpu, err;
381 int nr_cpus = cpu_map__nr(evlist->cpus);
382
383 if (!evsel->fd)
384 return -EINVAL;
385
386 for (cpu = 0; cpu < nr_cpus; cpu++) {
387 err = ioctl(FD(evsel, cpu, thread), PERF_EVENT_IOC_ENABLE, 0);
388 if (err)
389 return err;
390 }
391 return 0;
392}
393
394int perf_evlist__enable_event_idx(struct perf_evlist *evlist,
395 struct perf_evsel *evsel, int idx)
396{
397 bool per_cpu_mmaps = !cpu_map__empty(evlist->cpus);
398
399 if (per_cpu_mmaps)
400 return perf_evlist__enable_event_cpu(evlist, evsel, idx);
401 else
402 return perf_evlist__enable_event_thread(evlist, evsel, idx);
403}
404
342static int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) 405static int perf_evlist__alloc_pollfd(struct perf_evlist *evlist)
343{ 406{
344 int nr_cpus = cpu_map__nr(evlist->cpus); 407 int nr_cpus = cpu_map__nr(evlist->cpus);
345 int nr_threads = thread_map__nr(evlist->threads); 408 int nr_threads = thread_map__nr(evlist->threads);
346 int nfds = nr_cpus * nr_threads * evlist->nr_entries; 409 int nfds = 0;
410 struct perf_evsel *evsel;
411
412 list_for_each_entry(evsel, &evlist->entries, node) {
413 if (evsel->system_wide)
414 nfds += nr_cpus;
415 else
416 nfds += nr_cpus * nr_threads;
417 }
418
347 evlist->pollfd = malloc(sizeof(struct pollfd) * nfds); 419 evlist->pollfd = malloc(sizeof(struct pollfd) * nfds);
348 return evlist->pollfd != NULL ? 0 : -ENOMEM; 420 return evlist->pollfd != NULL ? 0 : -ENOMEM;
349} 421}
@@ -636,7 +708,12 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
636 struct perf_evsel *evsel; 708 struct perf_evsel *evsel;
637 709
638 evlist__for_each(evlist, evsel) { 710 evlist__for_each(evlist, evsel) {
639 int fd = FD(evsel, cpu, thread); 711 int fd;
712
713 if (evsel->system_wide && thread)
714 continue;
715
716 fd = FD(evsel, cpu, thread);
640 717
641 if (*output == -1) { 718 if (*output == -1) {
642 *output = fd; 719 *output = fd;
@@ -1266,3 +1343,19 @@ void perf_evlist__to_front(struct perf_evlist *evlist,
1266 1343
1267 list_splice(&move, &evlist->entries); 1344 list_splice(&move, &evlist->entries);
1268} 1345}
1346
1347void perf_evlist__set_tracking_event(struct perf_evlist *evlist,
1348 struct perf_evsel *tracking_evsel)
1349{
1350 struct perf_evsel *evsel;
1351
1352 if (tracking_evsel->tracking)
1353 return;
1354
1355 evlist__for_each(evlist, evsel) {
1356 if (evsel != tracking_evsel)
1357 evsel->tracking = false;
1358 }
1359
1360 tracking_evsel->tracking = true;
1361}
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index f5173cd63693..106de53a6a74 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -122,6 +122,8 @@ int perf_evlist__disable_event(struct perf_evlist *evlist,
122 struct perf_evsel *evsel); 122 struct perf_evsel *evsel);
123int perf_evlist__enable_event(struct perf_evlist *evlist, 123int perf_evlist__enable_event(struct perf_evlist *evlist,
124 struct perf_evsel *evsel); 124 struct perf_evsel *evsel);
125int perf_evlist__enable_event_idx(struct perf_evlist *evlist,
126 struct perf_evsel *evsel, int idx);
125 127
126void perf_evlist__set_selected(struct perf_evlist *evlist, 128void perf_evlist__set_selected(struct perf_evlist *evlist,
127 struct perf_evsel *evsel); 129 struct perf_evsel *evsel);
@@ -262,4 +264,7 @@ void perf_evlist__to_front(struct perf_evlist *evlist,
262#define evlist__for_each_safe(evlist, tmp, evsel) \ 264#define evlist__for_each_safe(evlist, tmp, evsel) \
263 __evlist__for_each_safe(&(evlist)->entries, tmp, evsel) 265 __evlist__for_each_safe(&(evlist)->entries, tmp, evsel)
264 266
267void perf_evlist__set_tracking_event(struct perf_evlist *evlist,
268 struct perf_evsel *tracking_evsel);
269
265#endif /* __PERF_EVLIST_H */ 270#endif /* __PERF_EVLIST_H */
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 0c8919decac8..01ce14c3575e 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -162,6 +162,7 @@ void perf_evsel__init(struct perf_evsel *evsel,
162 struct perf_event_attr *attr, int idx) 162 struct perf_event_attr *attr, int idx)
163{ 163{
164 evsel->idx = idx; 164 evsel->idx = idx;
165 evsel->tracking = !idx;
165 evsel->attr = *attr; 166 evsel->attr = *attr;
166 evsel->leader = evsel; 167 evsel->leader = evsel;
167 evsel->unit = ""; 168 evsel->unit = "";
@@ -561,7 +562,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
561{ 562{
562 struct perf_evsel *leader = evsel->leader; 563 struct perf_evsel *leader = evsel->leader;
563 struct perf_event_attr *attr = &evsel->attr; 564 struct perf_event_attr *attr = &evsel->attr;
564 int track = !evsel->idx; /* only the first counter needs these */ 565 int track = evsel->tracking;
565 bool per_cpu = opts->target.default_per_cpu && !opts->target.per_thread; 566 bool per_cpu = opts->target.default_per_cpu && !opts->target.per_thread;
566 567
567 attr->sample_id_all = perf_missing_features.sample_id_all ? 0 : 1; 568 attr->sample_id_all = perf_missing_features.sample_id_all ? 0 : 1;
@@ -695,6 +696,10 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
695int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) 696int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
696{ 697{
697 int cpu, thread; 698 int cpu, thread;
699
700 if (evsel->system_wide)
701 nthreads = 1;
702
698 evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int)); 703 evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int));
699 704
700 if (evsel->fd) { 705 if (evsel->fd) {
@@ -713,6 +718,9 @@ static int perf_evsel__run_ioctl(struct perf_evsel *evsel, int ncpus, int nthrea
713{ 718{
714 int cpu, thread; 719 int cpu, thread;
715 720
721 if (evsel->system_wide)
722 nthreads = 1;
723
716 for (cpu = 0; cpu < ncpus; cpu++) { 724 for (cpu = 0; cpu < ncpus; cpu++) {
717 for (thread = 0; thread < nthreads; thread++) { 725 for (thread = 0; thread < nthreads; thread++) {
718 int fd = FD(evsel, cpu, thread), 726 int fd = FD(evsel, cpu, thread),
@@ -743,6 +751,9 @@ int perf_evsel__enable(struct perf_evsel *evsel, int ncpus, int nthreads)
743 751
744int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads) 752int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads)
745{ 753{
754 if (evsel->system_wide)
755 nthreads = 1;
756
746 evsel->sample_id = xyarray__new(ncpus, nthreads, sizeof(struct perf_sample_id)); 757 evsel->sample_id = xyarray__new(ncpus, nthreads, sizeof(struct perf_sample_id));
747 if (evsel->sample_id == NULL) 758 if (evsel->sample_id == NULL)
748 return -ENOMEM; 759 return -ENOMEM;
@@ -787,6 +798,9 @@ void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
787{ 798{
788 int cpu, thread; 799 int cpu, thread;
789 800
801 if (evsel->system_wide)
802 nthreads = 1;
803
790 for (cpu = 0; cpu < ncpus; cpu++) 804 for (cpu = 0; cpu < ncpus; cpu++)
791 for (thread = 0; thread < nthreads; ++thread) { 805 for (thread = 0; thread < nthreads; ++thread) {
792 close(FD(evsel, cpu, thread)); 806 close(FD(evsel, cpu, thread));
@@ -875,6 +889,9 @@ int __perf_evsel__read(struct perf_evsel *evsel,
875 int cpu, thread; 889 int cpu, thread;
876 struct perf_counts_values *aggr = &evsel->counts->aggr, count; 890 struct perf_counts_values *aggr = &evsel->counts->aggr, count;
877 891
892 if (evsel->system_wide)
893 nthreads = 1;
894
878 aggr->val = aggr->ena = aggr->run = 0; 895 aggr->val = aggr->ena = aggr->run = 0;
879 896
880 for (cpu = 0; cpu < ncpus; cpu++) { 897 for (cpu = 0; cpu < ncpus; cpu++) {
@@ -997,13 +1014,18 @@ static size_t perf_event_attr__fprintf(struct perf_event_attr *attr, FILE *fp)
997static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, 1014static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
998 struct thread_map *threads) 1015 struct thread_map *threads)
999{ 1016{
1000 int cpu, thread; 1017 int cpu, thread, nthreads;
1001 unsigned long flags = PERF_FLAG_FD_CLOEXEC; 1018 unsigned long flags = PERF_FLAG_FD_CLOEXEC;
1002 int pid = -1, err; 1019 int pid = -1, err;
1003 enum { NO_CHANGE, SET_TO_MAX, INCREASED_MAX } set_rlimit = NO_CHANGE; 1020 enum { NO_CHANGE, SET_TO_MAX, INCREASED_MAX } set_rlimit = NO_CHANGE;
1004 1021
1022 if (evsel->system_wide)
1023 nthreads = 1;
1024 else
1025 nthreads = threads->nr;
1026
1005 if (evsel->fd == NULL && 1027 if (evsel->fd == NULL &&
1006 perf_evsel__alloc_fd(evsel, cpus->nr, threads->nr) < 0) 1028 perf_evsel__alloc_fd(evsel, cpus->nr, nthreads) < 0)
1007 return -ENOMEM; 1029 return -ENOMEM;
1008 1030
1009 if (evsel->cgrp) { 1031 if (evsel->cgrp) {
@@ -1027,10 +1049,10 @@ retry_sample_id:
1027 1049
1028 for (cpu = 0; cpu < cpus->nr; cpu++) { 1050 for (cpu = 0; cpu < cpus->nr; cpu++) {
1029 1051
1030 for (thread = 0; thread < threads->nr; thread++) { 1052 for (thread = 0; thread < nthreads; thread++) {
1031 int group_fd; 1053 int group_fd;
1032 1054
1033 if (!evsel->cgrp) 1055 if (!evsel->cgrp && !evsel->system_wide)
1034 pid = threads->map[thread]; 1056 pid = threads->map[thread];
1035 1057
1036 group_fd = get_group_fd(evsel, cpu, thread); 1058 group_fd = get_group_fd(evsel, cpu, thread);
@@ -1103,7 +1125,7 @@ out_close:
1103 close(FD(evsel, cpu, thread)); 1125 close(FD(evsel, cpu, thread));
1104 FD(evsel, cpu, thread) = -1; 1126 FD(evsel, cpu, thread) = -1;
1105 } 1127 }
1106 thread = threads->nr; 1128 thread = nthreads;
1107 } while (--cpu >= 0); 1129 } while (--cpu >= 0);
1108 return err; 1130 return err;
1109} 1131}
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index d7f93ce0ebc1..7bc314be6a7b 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -85,6 +85,8 @@ struct perf_evsel {
85 bool needs_swap; 85 bool needs_swap;
86 bool no_aux_samples; 86 bool no_aux_samples;
87 bool immediate; 87 bool immediate;
88 bool system_wide;
89 bool tracking;
88 /* parse modifier helper */ 90 /* parse modifier helper */
89 int exclude_GH; 91 int exclude_GH;
90 int nr_members; 92 int nr_members;
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 30df6187ee02..86569fa3651d 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -277,6 +277,28 @@ void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel)
277 } 277 }
278} 278}
279 279
280void hists__delete_entries(struct hists *hists)
281{
282 struct rb_node *next = rb_first(&hists->entries);
283 struct hist_entry *n;
284
285 while (next) {
286 n = rb_entry(next, struct hist_entry, rb_node);
287 next = rb_next(&n->rb_node);
288
289 rb_erase(&n->rb_node, &hists->entries);
290
291 if (sort__need_collapse)
292 rb_erase(&n->rb_node_in, &hists->entries_collapsed);
293
294 --hists->nr_entries;
295 if (!n->filtered)
296 --hists->nr_non_filtered_entries;
297
298 hist_entry__free(n);
299 }
300}
301
280/* 302/*
281 * histogram, sorted on item, collects periods 303 * histogram, sorted on item, collects periods
282 */ 304 */
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 95405a8fbd95..8c9c70e18cbb 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -152,6 +152,7 @@ void hists__output_resort(struct hists *hists);
152void hists__collapse_resort(struct hists *hists, struct ui_progress *prog); 152void hists__collapse_resort(struct hists *hists, struct ui_progress *prog);
153 153
154void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel); 154void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel);
155void hists__delete_entries(struct hists *hists);
155void hists__output_recalc_col_len(struct hists *hists, int max_rows); 156void hists__output_recalc_col_len(struct hists *hists, int max_rows);
156 157
157u64 hists__total_period(struct hists *hists); 158u64 hists__total_period(struct hists *hists);
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 16bba9fff2c8..b093b93607fb 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -31,6 +31,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
31 31
32 machine->symbol_filter = NULL; 32 machine->symbol_filter = NULL;
33 machine->id_hdr_size = 0; 33 machine->id_hdr_size = 0;
34 machine->comm_exec = false;
34 35
35 machine->root_dir = strdup(root_dir); 36 machine->root_dir = strdup(root_dir);
36 if (machine->root_dir == NULL) 37 if (machine->root_dir == NULL)
@@ -179,6 +180,19 @@ void machines__set_symbol_filter(struct machines *machines,
179 } 180 }
180} 181}
181 182
183void machines__set_comm_exec(struct machines *machines, bool comm_exec)
184{
185 struct rb_node *nd;
186
187 machines->host.comm_exec = comm_exec;
188
189 for (nd = rb_first(&machines->guests); nd; nd = rb_next(nd)) {
190 struct machine *machine = rb_entry(nd, struct machine, rb_node);
191
192 machine->comm_exec = comm_exec;
193 }
194}
195
182struct machine *machines__find(struct machines *machines, pid_t pid) 196struct machine *machines__find(struct machines *machines, pid_t pid)
183{ 197{
184 struct rb_node **p = &machines->guests.rb_node; 198 struct rb_node **p = &machines->guests.rb_node;
@@ -398,17 +412,31 @@ struct thread *machine__find_thread(struct machine *machine, pid_t pid,
398 return __machine__findnew_thread(machine, pid, tid, false); 412 return __machine__findnew_thread(machine, pid, tid, false);
399} 413}
400 414
415struct comm *machine__thread_exec_comm(struct machine *machine,
416 struct thread *thread)
417{
418 if (machine->comm_exec)
419 return thread__exec_comm(thread);
420 else
421 return thread__comm(thread);
422}
423
401int machine__process_comm_event(struct machine *machine, union perf_event *event, 424int machine__process_comm_event(struct machine *machine, union perf_event *event,
402 struct perf_sample *sample) 425 struct perf_sample *sample)
403{ 426{
404 struct thread *thread = machine__findnew_thread(machine, 427 struct thread *thread = machine__findnew_thread(machine,
405 event->comm.pid, 428 event->comm.pid,
406 event->comm.tid); 429 event->comm.tid);
430 bool exec = event->header.misc & PERF_RECORD_MISC_COMM_EXEC;
431
432 if (exec)
433 machine->comm_exec = true;
407 434
408 if (dump_trace) 435 if (dump_trace)
409 perf_event__fprintf_comm(event, stdout); 436 perf_event__fprintf_comm(event, stdout);
410 437
411 if (thread == NULL || thread__set_comm(thread, event->comm.comm, sample->time)) { 438 if (thread == NULL ||
439 __thread__set_comm(thread, event->comm.comm, sample->time, exec)) {
412 dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n"); 440 dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
413 return -1; 441 return -1;
414 } 442 }
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index b972824e6294..61216e028319 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -26,6 +26,7 @@ struct machine {
26 struct rb_node rb_node; 26 struct rb_node rb_node;
27 pid_t pid; 27 pid_t pid;
28 u16 id_hdr_size; 28 u16 id_hdr_size;
29 bool comm_exec;
29 char *root_dir; 30 char *root_dir;
30 struct rb_root threads; 31 struct rb_root threads;
31 struct list_head dead_threads; 32 struct list_head dead_threads;
@@ -47,6 +48,8 @@ struct map *machine__kernel_map(struct machine *machine, enum map_type type)
47 48
48struct thread *machine__find_thread(struct machine *machine, pid_t pid, 49struct thread *machine__find_thread(struct machine *machine, pid_t pid,
49 pid_t tid); 50 pid_t tid);
51struct comm *machine__thread_exec_comm(struct machine *machine,
52 struct thread *thread);
50 53
51int machine__process_comm_event(struct machine *machine, union perf_event *event, 54int machine__process_comm_event(struct machine *machine, union perf_event *event,
52 struct perf_sample *sample); 55 struct perf_sample *sample);
@@ -88,6 +91,7 @@ char *machine__mmap_name(struct machine *machine, char *bf, size_t size);
88 91
89void machines__set_symbol_filter(struct machines *machines, 92void machines__set_symbol_filter(struct machines *machines,
90 symbol_filter_t symbol_filter); 93 symbol_filter_t symbol_filter);
94void machines__set_comm_exec(struct machines *machines, bool comm_exec);
91 95
92struct machine *machine__new_host(void); 96struct machine *machine__new_host(void);
93int machine__init(struct machine *machine, const char *root_dir, pid_t pid); 97int machine__init(struct machine *machine, const char *root_dir, pid_t pid);
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 9a0a1839a377..784ea42ad8cb 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -79,7 +79,7 @@ static int init_symbol_maps(bool user_only)
79 int ret; 79 int ret;
80 80
81 symbol_conf.sort_by_name = true; 81 symbol_conf.sort_by_name = true;
82 ret = symbol__init(); 82 ret = symbol__init(NULL);
83 if (ret < 0) { 83 if (ret < 0) {
84 pr_debug("Failed to init symbol map.\n"); 84 pr_debug("Failed to init symbol map.\n");
85 goto out; 85 goto out;
@@ -1780,10 +1780,11 @@ static void clear_probe_trace_event(struct probe_trace_event *tev)
1780 memset(tev, 0, sizeof(*tev)); 1780 memset(tev, 0, sizeof(*tev));
1781} 1781}
1782 1782
1783static void print_warn_msg(const char *file, bool is_kprobe) 1783static void print_open_warning(int err, bool is_kprobe)
1784{ 1784{
1785 char sbuf[128];
1785 1786
1786 if (errno == ENOENT) { 1787 if (err == -ENOENT) {
1787 const char *config; 1788 const char *config;
1788 1789
1789 if (!is_kprobe) 1790 if (!is_kprobe)
@@ -1791,25 +1792,43 @@ static void print_warn_msg(const char *file, bool is_kprobe)
1791 else 1792 else
1792 config = "CONFIG_KPROBE_EVENTS"; 1793 config = "CONFIG_KPROBE_EVENTS";
1793 1794
1794 pr_warning("%s file does not exist - please rebuild kernel" 1795 pr_warning("%cprobe_events file does not exist"
1795 " with %s.\n", file, config); 1796 " - please rebuild kernel with %s.\n",
1796 } else 1797 is_kprobe ? 'k' : 'u', config);
1797 pr_warning("Failed to open %s file: %s\n", file, 1798 } else if (err == -ENOTSUP)
1798 strerror(errno)); 1799 pr_warning("Debugfs is not mounted.\n");
1800 else
1801 pr_warning("Failed to open %cprobe_events: %s\n",
1802 is_kprobe ? 'k' : 'u',
1803 strerror_r(-err, sbuf, sizeof(sbuf)));
1799} 1804}
1800 1805
1801static int open_probe_events(const char *trace_file, bool readwrite, 1806static void print_both_open_warning(int kerr, int uerr)
1802 bool is_kprobe) 1807{
1808 /* Both kprobes and uprobes are disabled, warn it. */
1809 if (kerr == -ENOTSUP && uerr == -ENOTSUP)
1810 pr_warning("Debugfs is not mounted.\n");
1811 else if (kerr == -ENOENT && uerr == -ENOENT)
1812 pr_warning("Please rebuild kernel with CONFIG_KPROBE_EVENTS "
1813 "or/and CONFIG_UPROBE_EVENTS.\n");
1814 else {
1815 char sbuf[128];
1816 pr_warning("Failed to open kprobe events: %s.\n",
1817 strerror_r(-kerr, sbuf, sizeof(sbuf)));
1818 pr_warning("Failed to open uprobe events: %s.\n",
1819 strerror_r(-uerr, sbuf, sizeof(sbuf)));
1820 }
1821}
1822
1823static int open_probe_events(const char *trace_file, bool readwrite)
1803{ 1824{
1804 char buf[PATH_MAX]; 1825 char buf[PATH_MAX];
1805 const char *__debugfs; 1826 const char *__debugfs;
1806 int ret; 1827 int ret;
1807 1828
1808 __debugfs = debugfs_find_mountpoint(); 1829 __debugfs = debugfs_find_mountpoint();
1809 if (__debugfs == NULL) { 1830 if (__debugfs == NULL)
1810 pr_warning("Debugfs is not mounted.\n"); 1831 return -ENOTSUP;
1811 return -ENOENT;
1812 }
1813 1832
1814 ret = e_snprintf(buf, PATH_MAX, "%s/%s", __debugfs, trace_file); 1833 ret = e_snprintf(buf, PATH_MAX, "%s/%s", __debugfs, trace_file);
1815 if (ret >= 0) { 1834 if (ret >= 0) {
@@ -1820,19 +1839,19 @@ static int open_probe_events(const char *trace_file, bool readwrite,
1820 ret = open(buf, O_RDONLY, 0); 1839 ret = open(buf, O_RDONLY, 0);
1821 1840
1822 if (ret < 0) 1841 if (ret < 0)
1823 print_warn_msg(buf, is_kprobe); 1842 ret = -errno;
1824 } 1843 }
1825 return ret; 1844 return ret;
1826} 1845}
1827 1846
1828static int open_kprobe_events(bool readwrite) 1847static int open_kprobe_events(bool readwrite)
1829{ 1848{
1830 return open_probe_events("tracing/kprobe_events", readwrite, true); 1849 return open_probe_events("tracing/kprobe_events", readwrite);
1831} 1850}
1832 1851
1833static int open_uprobe_events(bool readwrite) 1852static int open_uprobe_events(bool readwrite)
1834{ 1853{
1835 return open_probe_events("tracing/uprobe_events", readwrite, false); 1854 return open_probe_events("tracing/uprobe_events", readwrite);
1836} 1855}
1837 1856
1838/* Get raw string list of current kprobe_events or uprobe_events */ 1857/* Get raw string list of current kprobe_events or uprobe_events */
@@ -1940,27 +1959,34 @@ static int __show_perf_probe_events(int fd, bool is_kprobe)
1940/* List up current perf-probe events */ 1959/* List up current perf-probe events */
1941int show_perf_probe_events(void) 1960int show_perf_probe_events(void)
1942{ 1961{
1943 int fd, ret; 1962 int kp_fd, up_fd, ret;
1944 1963
1945 setup_pager(); 1964 setup_pager();
1946 fd = open_kprobe_events(false);
1947
1948 if (fd < 0)
1949 return fd;
1950 1965
1951 ret = init_symbol_maps(false); 1966 ret = init_symbol_maps(false);
1952 if (ret < 0) 1967 if (ret < 0)
1953 return ret; 1968 return ret;
1954 1969
1955 ret = __show_perf_probe_events(fd, true); 1970 kp_fd = open_kprobe_events(false);
1956 close(fd); 1971 if (kp_fd >= 0) {
1972 ret = __show_perf_probe_events(kp_fd, true);
1973 close(kp_fd);
1974 if (ret < 0)
1975 goto out;
1976 }
1957 1977
1958 fd = open_uprobe_events(false); 1978 up_fd = open_uprobe_events(false);
1959 if (fd >= 0) { 1979 if (kp_fd < 0 && up_fd < 0) {
1960 ret = __show_perf_probe_events(fd, false); 1980 print_both_open_warning(kp_fd, up_fd);
1961 close(fd); 1981 ret = kp_fd;
1982 goto out;
1962 } 1983 }
1963 1984
1985 if (up_fd >= 0) {
1986 ret = __show_perf_probe_events(up_fd, false);
1987 close(up_fd);
1988 }
1989out:
1964 exit_symbol_maps(); 1990 exit_symbol_maps();
1965 return ret; 1991 return ret;
1966} 1992}
@@ -2075,8 +2101,11 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
2075 else 2101 else
2076 fd = open_kprobe_events(true); 2102 fd = open_kprobe_events(true);
2077 2103
2078 if (fd < 0) 2104 if (fd < 0) {
2105 print_open_warning(fd, !pev->uprobes);
2079 return fd; 2106 return fd;
2107 }
2108
2080 /* Get current event names */ 2109 /* Get current event names */
2081 namelist = get_probe_trace_event_names(fd, false); 2110 namelist = get_probe_trace_event_names(fd, false);
2082 if (!namelist) { 2111 if (!namelist) {
@@ -2449,15 +2478,18 @@ int del_perf_probe_events(struct strlist *dellist)
2449 2478
2450 /* Get current event names */ 2479 /* Get current event names */
2451 kfd = open_kprobe_events(true); 2480 kfd = open_kprobe_events(true);
2452 if (kfd < 0) 2481 if (kfd >= 0)
2453 return kfd; 2482 namelist = get_probe_trace_event_names(kfd, true);
2454 2483
2455 namelist = get_probe_trace_event_names(kfd, true);
2456 ufd = open_uprobe_events(true); 2484 ufd = open_uprobe_events(true);
2457
2458 if (ufd >= 0) 2485 if (ufd >= 0)
2459 unamelist = get_probe_trace_event_names(ufd, true); 2486 unamelist = get_probe_trace_event_names(ufd, true);
2460 2487
2488 if (kfd < 0 && ufd < 0) {
2489 print_both_open_warning(kfd, ufd);
2490 goto error;
2491 }
2492
2461 if (namelist == NULL && unamelist == NULL) 2493 if (namelist == NULL && unamelist == NULL)
2462 goto error; 2494 goto error;
2463 2495
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
index fe8079edbdc1..cf69325b985f 100644
--- a/tools/perf/util/record.c
+++ b/tools/perf/util/record.c
@@ -14,6 +14,7 @@ static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str)
14 struct perf_evsel *evsel; 14 struct perf_evsel *evsel;
15 unsigned long flags = perf_event_open_cloexec_flag(); 15 unsigned long flags = perf_event_open_cloexec_flag();
16 int err = -EAGAIN, fd; 16 int err = -EAGAIN, fd;
17 static pid_t pid = -1;
17 18
18 evlist = perf_evlist__new(); 19 evlist = perf_evlist__new();
19 if (!evlist) 20 if (!evlist)
@@ -24,14 +25,22 @@ static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str)
24 25
25 evsel = perf_evlist__first(evlist); 26 evsel = perf_evlist__first(evlist);
26 27
27 fd = sys_perf_event_open(&evsel->attr, -1, cpu, -1, flags); 28 while (1) {
28 if (fd < 0) 29 fd = sys_perf_event_open(&evsel->attr, pid, cpu, -1, flags);
29 goto out_delete; 30 if (fd < 0) {
31 if (pid == -1 && errno == EACCES) {
32 pid = 0;
33 continue;
34 }
35 goto out_delete;
36 }
37 break;
38 }
30 close(fd); 39 close(fd);
31 40
32 fn(evsel); 41 fn(evsel);
33 42
34 fd = sys_perf_event_open(&evsel->attr, -1, cpu, -1, flags); 43 fd = sys_perf_event_open(&evsel->attr, pid, cpu, -1, flags);
35 if (fd < 0) { 44 if (fd < 0) {
36 if (errno == EINVAL) 45 if (errno == EINVAL)
37 err = -EINVAL; 46 err = -EINVAL;
@@ -47,7 +56,7 @@ out_delete:
47 56
48static bool perf_probe_api(setup_probe_fn_t fn) 57static bool perf_probe_api(setup_probe_fn_t fn)
49{ 58{
50 const char *try[] = {"cycles:u", "instructions:u", "cpu-clock", NULL}; 59 const char *try[] = {"cycles:u", "instructions:u", "cpu-clock:u", NULL};
51 struct cpu_map *cpus; 60 struct cpu_map *cpus;
52 int cpu, ret, i = 0; 61 int cpu, ret, i = 0;
53 62
@@ -106,7 +115,7 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts)
106 115
107 evlist__for_each(evlist, evsel) { 116 evlist__for_each(evlist, evsel) {
108 perf_evsel__config(evsel, opts); 117 perf_evsel__config(evsel, opts);
109 if (!evsel->idx && use_comm_exec) 118 if (evsel->tracking && use_comm_exec)
110 evsel->attr.comm_exec = 1; 119 evsel->attr.comm_exec = 1;
111 } 120 }
112 121
@@ -201,6 +210,7 @@ bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str)
201 struct perf_evsel *evsel; 210 struct perf_evsel *evsel;
202 int err, fd, cpu; 211 int err, fd, cpu;
203 bool ret = false; 212 bool ret = false;
213 pid_t pid = -1;
204 214
205 temp_evlist = perf_evlist__new(); 215 temp_evlist = perf_evlist__new();
206 if (!temp_evlist) 216 if (!temp_evlist)
@@ -221,12 +231,20 @@ bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str)
221 cpu = evlist->cpus->map[0]; 231 cpu = evlist->cpus->map[0];
222 } 232 }
223 233
224 fd = sys_perf_event_open(&evsel->attr, -1, cpu, -1, 234 while (1) {
225 perf_event_open_cloexec_flag()); 235 fd = sys_perf_event_open(&evsel->attr, pid, cpu, -1,
226 if (fd >= 0) { 236 perf_event_open_cloexec_flag());
227 close(fd); 237 if (fd < 0) {
228 ret = true; 238 if (pid == -1 && errno == EACCES) {
239 pid = 0;
240 continue;
241 }
242 goto out_delete;
243 }
244 break;
229 } 245 }
246 close(fd);
247 ret = true;
230 248
231out_delete: 249out_delete:
232 perf_evlist__delete(temp_evlist); 250 perf_evlist__delete(temp_evlist);
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index cbce2545da45..26e5f14239ed 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -73,6 +73,35 @@ static void pydict_set_item_string_decref(PyObject *dict, const char *key, PyObj
73 Py_DECREF(val); 73 Py_DECREF(val);
74} 74}
75 75
76static PyObject *get_handler(const char *handler_name)
77{
78 PyObject *handler;
79
80 handler = PyDict_GetItemString(main_dict, handler_name);
81 if (handler && !PyCallable_Check(handler))
82 return NULL;
83 return handler;
84}
85
86static void call_object(PyObject *handler, PyObject *args, const char *die_msg)
87{
88 PyObject *retval;
89
90 retval = PyObject_CallObject(handler, args);
91 if (retval == NULL)
92 handler_call_die(die_msg);
93 Py_DECREF(retval);
94}
95
96static void try_call_object(const char *handler_name, PyObject *args)
97{
98 PyObject *handler;
99
100 handler = get_handler(handler_name);
101 if (handler)
102 call_object(handler, args, handler_name);
103}
104
76static void define_value(enum print_arg_type field_type, 105static void define_value(enum print_arg_type field_type,
77 const char *ev_name, 106 const char *ev_name,
78 const char *field_name, 107 const char *field_name,
@@ -80,7 +109,7 @@ static void define_value(enum print_arg_type field_type,
80 const char *field_str) 109 const char *field_str)
81{ 110{
82 const char *handler_name = "define_flag_value"; 111 const char *handler_name = "define_flag_value";
83 PyObject *handler, *t, *retval; 112 PyObject *t;
84 unsigned long long value; 113 unsigned long long value;
85 unsigned n = 0; 114 unsigned n = 0;
86 115
@@ -98,13 +127,7 @@ static void define_value(enum print_arg_type field_type,
98 PyTuple_SetItem(t, n++, PyInt_FromLong(value)); 127 PyTuple_SetItem(t, n++, PyInt_FromLong(value));
99 PyTuple_SetItem(t, n++, PyString_FromString(field_str)); 128 PyTuple_SetItem(t, n++, PyString_FromString(field_str));
100 129
101 handler = PyDict_GetItemString(main_dict, handler_name); 130 try_call_object(handler_name, t);
102 if (handler && PyCallable_Check(handler)) {
103 retval = PyObject_CallObject(handler, t);
104 if (retval == NULL)
105 handler_call_die(handler_name);
106 Py_DECREF(retval);
107 }
108 131
109 Py_DECREF(t); 132 Py_DECREF(t);
110} 133}
@@ -127,7 +150,7 @@ static void define_field(enum print_arg_type field_type,
127 const char *delim) 150 const char *delim)
128{ 151{
129 const char *handler_name = "define_flag_field"; 152 const char *handler_name = "define_flag_field";
130 PyObject *handler, *t, *retval; 153 PyObject *t;
131 unsigned n = 0; 154 unsigned n = 0;
132 155
133 if (field_type == PRINT_SYMBOL) 156 if (field_type == PRINT_SYMBOL)
@@ -145,13 +168,7 @@ static void define_field(enum print_arg_type field_type,
145 if (field_type == PRINT_FLAGS) 168 if (field_type == PRINT_FLAGS)
146 PyTuple_SetItem(t, n++, PyString_FromString(delim)); 169 PyTuple_SetItem(t, n++, PyString_FromString(delim));
147 170
148 handler = PyDict_GetItemString(main_dict, handler_name); 171 try_call_object(handler_name, t);
149 if (handler && PyCallable_Check(handler)) {
150 retval = PyObject_CallObject(handler, t);
151 if (retval == NULL)
152 handler_call_die(handler_name);
153 Py_DECREF(retval);
154 }
155 172
156 Py_DECREF(t); 173 Py_DECREF(t);
157} 174}
@@ -362,7 +379,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
362 struct thread *thread, 379 struct thread *thread,
363 struct addr_location *al) 380 struct addr_location *al)
364{ 381{
365 PyObject *handler, *retval, *context, *t, *obj, *callchain; 382 PyObject *handler, *context, *t, *obj, *callchain;
366 PyObject *dict = NULL; 383 PyObject *dict = NULL;
367 static char handler_name[256]; 384 static char handler_name[256];
368 struct format_field *field; 385 struct format_field *field;
@@ -387,9 +404,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
387 404
388 sprintf(handler_name, "%s__%s", event->system, event->name); 405 sprintf(handler_name, "%s__%s", event->system, event->name);
389 406
390 handler = PyDict_GetItemString(main_dict, handler_name); 407 handler = get_handler(handler_name);
391 if (handler && !PyCallable_Check(handler))
392 handler = NULL;
393 if (!handler) { 408 if (!handler) {
394 dict = PyDict_New(); 409 dict = PyDict_New();
395 if (!dict) 410 if (!dict)
@@ -450,19 +465,9 @@ static void python_process_tracepoint(struct perf_sample *sample,
450 Py_FatalError("error resizing Python tuple"); 465 Py_FatalError("error resizing Python tuple");
451 466
452 if (handler) { 467 if (handler) {
453 retval = PyObject_CallObject(handler, t); 468 call_object(handler, t, handler_name);
454 if (retval == NULL)
455 handler_call_die(handler_name);
456 Py_DECREF(retval);
457 } else { 469 } else {
458 handler = PyDict_GetItemString(main_dict, "trace_unhandled"); 470 try_call_object("trace_unhandled", t);
459 if (handler && PyCallable_Check(handler)) {
460
461 retval = PyObject_CallObject(handler, t);
462 if (retval == NULL)
463 handler_call_die("trace_unhandled");
464 Py_DECREF(retval);
465 }
466 Py_DECREF(dict); 471 Py_DECREF(dict);
467 } 472 }
468 473
@@ -474,7 +479,7 @@ static void python_process_general_event(struct perf_sample *sample,
474 struct thread *thread, 479 struct thread *thread,
475 struct addr_location *al) 480 struct addr_location *al)
476{ 481{
477 PyObject *handler, *retval, *t, *dict, *callchain, *dict_sample; 482 PyObject *handler, *t, *dict, *callchain, *dict_sample;
478 static char handler_name[64]; 483 static char handler_name[64];
479 unsigned n = 0; 484 unsigned n = 0;
480 485
@@ -496,8 +501,8 @@ static void python_process_general_event(struct perf_sample *sample,
496 501
497 snprintf(handler_name, sizeof(handler_name), "%s", "process_event"); 502 snprintf(handler_name, sizeof(handler_name), "%s", "process_event");
498 503
499 handler = PyDict_GetItemString(main_dict, handler_name); 504 handler = get_handler(handler_name);
500 if (!handler || !PyCallable_Check(handler)) 505 if (!handler)
501 goto exit; 506 goto exit;
502 507
503 pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel))); 508 pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel)));
@@ -539,10 +544,7 @@ static void python_process_general_event(struct perf_sample *sample,
539 if (_PyTuple_Resize(&t, n) == -1) 544 if (_PyTuple_Resize(&t, n) == -1)
540 Py_FatalError("error resizing Python tuple"); 545 Py_FatalError("error resizing Python tuple");
541 546
542 retval = PyObject_CallObject(handler, t); 547 call_object(handler, t, handler_name);
543 if (retval == NULL)
544 handler_call_die(handler_name);
545 Py_DECREF(retval);
546exit: 548exit:
547 Py_DECREF(dict); 549 Py_DECREF(dict);
548 Py_DECREF(t); 550 Py_DECREF(t);
@@ -566,36 +568,24 @@ static void python_process_event(union perf_event *event __maybe_unused,
566 568
567static int run_start_sub(void) 569static int run_start_sub(void)
568{ 570{
569 PyObject *handler, *retval;
570 int err = 0;
571
572 main_module = PyImport_AddModule("__main__"); 571 main_module = PyImport_AddModule("__main__");
573 if (main_module == NULL) 572 if (main_module == NULL)
574 return -1; 573 return -1;
575 Py_INCREF(main_module); 574 Py_INCREF(main_module);
576 575
577 main_dict = PyModule_GetDict(main_module); 576 main_dict = PyModule_GetDict(main_module);
578 if (main_dict == NULL) { 577 if (main_dict == NULL)
579 err = -1;
580 goto error; 578 goto error;
581 }
582 Py_INCREF(main_dict); 579 Py_INCREF(main_dict);
583 580
584 handler = PyDict_GetItemString(main_dict, "trace_begin"); 581 try_call_object("trace_begin", NULL);
585 if (handler == NULL || !PyCallable_Check(handler))
586 goto out;
587 582
588 retval = PyObject_CallObject(handler, NULL); 583 return 0;
589 if (retval == NULL)
590 handler_call_die("trace_begin");
591 584
592 Py_DECREF(retval);
593 return err;
594error: 585error:
595 Py_XDECREF(main_dict); 586 Py_XDECREF(main_dict);
596 Py_XDECREF(main_module); 587 Py_XDECREF(main_module);
597out: 588 return -1;
598 return err;
599} 589}
600 590
601/* 591/*
@@ -654,23 +644,13 @@ error:
654 */ 644 */
655static int python_stop_script(void) 645static int python_stop_script(void)
656{ 646{
657 PyObject *handler, *retval; 647 try_call_object("trace_end", NULL);
658 int err = 0;
659 648
660 handler = PyDict_GetItemString(main_dict, "trace_end");
661 if (handler == NULL || !PyCallable_Check(handler))
662 goto out;
663
664 retval = PyObject_CallObject(handler, NULL);
665 if (retval == NULL)
666 handler_call_die("trace_end");
667 Py_DECREF(retval);
668out:
669 Py_XDECREF(main_dict); 649 Py_XDECREF(main_dict);
670 Py_XDECREF(main_module); 650 Py_XDECREF(main_module);
671 Py_Finalize(); 651 Py_Finalize();
672 652
673 return err; 653 return 0;
674} 654}
675 655
676static int python_generate_script(struct pevent *pevent, const char *outfile) 656static int python_generate_script(struct pevent *pevent, const char *outfile)
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 7e27f1eb260c..6d2d50dea1d8 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -67,6 +67,25 @@ static void perf_session__destroy_kernel_maps(struct perf_session *session)
67 machines__destroy_kernel_maps(&session->machines); 67 machines__destroy_kernel_maps(&session->machines);
68} 68}
69 69
70static bool perf_session__has_comm_exec(struct perf_session *session)
71{
72 struct perf_evsel *evsel;
73
74 evlist__for_each(session->evlist, evsel) {
75 if (evsel->attr.comm_exec)
76 return true;
77 }
78
79 return false;
80}
81
82static void perf_session__set_comm_exec(struct perf_session *session)
83{
84 bool comm_exec = perf_session__has_comm_exec(session);
85
86 machines__set_comm_exec(&session->machines, comm_exec);
87}
88
70struct perf_session *perf_session__new(struct perf_data_file *file, 89struct perf_session *perf_session__new(struct perf_data_file *file,
71 bool repipe, struct perf_tool *tool) 90 bool repipe, struct perf_tool *tool)
72{ 91{
@@ -90,6 +109,7 @@ struct perf_session *perf_session__new(struct perf_data_file *file,
90 goto out_close; 109 goto out_close;
91 110
92 perf_session__set_id_hdr_size(session); 111 perf_session__set_id_hdr_size(session);
112 perf_session__set_comm_exec(session);
93 } 113 }
94 } 114 }
95 115
@@ -866,8 +886,10 @@ static s64 perf_session__process_user_event(struct perf_session *session,
866 switch (event->header.type) { 886 switch (event->header.type) {
867 case PERF_RECORD_HEADER_ATTR: 887 case PERF_RECORD_HEADER_ATTR:
868 err = tool->attr(tool, event, &session->evlist); 888 err = tool->attr(tool, event, &session->evlist);
869 if (err == 0) 889 if (err == 0) {
870 perf_session__set_id_hdr_size(session); 890 perf_session__set_id_hdr_size(session);
891 perf_session__set_comm_exec(session);
892 }
871 return err; 893 return err;
872 case PERF_RECORD_HEADER_EVENT_TYPE: 894 case PERF_RECORD_HEADER_EVENT_TYPE:
873 /* 895 /*
@@ -897,6 +919,61 @@ static void event_swap(union perf_event *event, bool sample_id_all)
897 swap(event, sample_id_all); 919 swap(event, sample_id_all);
898} 920}
899 921
922int perf_session__peek_event(struct perf_session *session, off_t file_offset,
923 void *buf, size_t buf_sz,
924 union perf_event **event_ptr,
925 struct perf_sample *sample)
926{
927 union perf_event *event;
928 size_t hdr_sz, rest;
929 int fd;
930
931 if (session->one_mmap && !session->header.needs_swap) {
932 event = file_offset - session->one_mmap_offset +
933 session->one_mmap_addr;
934 goto out_parse_sample;
935 }
936
937 if (perf_data_file__is_pipe(session->file))
938 return -1;
939
940 fd = perf_data_file__fd(session->file);
941 hdr_sz = sizeof(struct perf_event_header);
942
943 if (buf_sz < hdr_sz)
944 return -1;
945
946 if (lseek(fd, file_offset, SEEK_SET) == (off_t)-1 ||
947 readn(fd, &buf, hdr_sz) != (ssize_t)hdr_sz)
948 return -1;
949
950 event = (union perf_event *)buf;
951
952 if (session->header.needs_swap)
953 perf_event_header__bswap(&event->header);
954
955 if (event->header.size < hdr_sz)
956 return -1;
957
958 rest = event->header.size - hdr_sz;
959
960 if (readn(fd, &buf, rest) != (ssize_t)rest)
961 return -1;
962
963 if (session->header.needs_swap)
964 event_swap(event, perf_evlist__sample_id_all(session->evlist));
965
966out_parse_sample:
967
968 if (sample && event->header.type < PERF_RECORD_USER_TYPE_START &&
969 perf_evlist__parse_sample(session->evlist, event, sample))
970 return -1;
971
972 *event_ptr = event;
973
974 return 0;
975}
976
900static s64 perf_session__process_event(struct perf_session *session, 977static s64 perf_session__process_event(struct perf_session *session,
901 union perf_event *event, 978 union perf_event *event,
902 struct perf_tool *tool, 979 struct perf_tool *tool,
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 0630e658f8be..8dd41cad2d59 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -45,6 +45,11 @@ void perf_session__delete(struct perf_session *session);
45 45
46void perf_event_header__bswap(struct perf_event_header *hdr); 46void perf_event_header__bswap(struct perf_event_header *hdr);
47 47
48int perf_session__peek_event(struct perf_session *session, off_t file_offset,
49 void *buf, size_t buf_sz,
50 union perf_event **event_ptr,
51 struct perf_sample *sample);
52
48int __perf_session__process_events(struct perf_session *session, 53int __perf_session__process_events(struct perf_session *session,
49 u64 data_offset, u64 data_size, u64 size, 54 u64 data_offset, u64 data_size, u64 size,
50 struct perf_tool *tool); 55 struct perf_tool *tool);
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index d75349979e65..9fb5e9e9f161 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -736,7 +736,7 @@ int dso__load_sym(struct dso *dso, struct map *map,
736 if (symstrs == NULL) 736 if (symstrs == NULL)
737 goto out_elf_end; 737 goto out_elf_end;
738 738
739 sec_strndx = elf_getscn(elf, ehdr.e_shstrndx); 739 sec_strndx = elf_getscn(runtime_ss->elf, runtime_ss->ehdr.e_shstrndx);
740 if (sec_strndx == NULL) 740 if (sec_strndx == NULL)
741 goto out_elf_end; 741 goto out_elf_end;
742 742
@@ -939,8 +939,11 @@ new_symbol:
939 * to it... 939 * to it...
940 */ 940 */
941 if (symbol_conf.demangle) { 941 if (symbol_conf.demangle) {
942 demangled = bfd_demangle(NULL, elf_name, 942 int demangle_flags = DMGL_NO_OPTS;
943 DMGL_PARAMS | DMGL_ANSI); 943 if (verbose)
944 demangle_flags = DMGL_PARAMS | DMGL_ANSI;
945
946 demangled = bfd_demangle(NULL, elf_name, demangle_flags);
944 if (demangled != NULL) 947 if (demangled != NULL)
945 elf_name = demangled; 948 elf_name = demangled;
946 } 949 }
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index f134ec138934..ac098a3c2a31 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -15,6 +15,7 @@
15#include "machine.h" 15#include "machine.h"
16#include "symbol.h" 16#include "symbol.h"
17#include "strlist.h" 17#include "strlist.h"
18#include "header.h"
18 19
19#include <elf.h> 20#include <elf.h>
20#include <limits.h> 21#include <limits.h>
@@ -523,10 +524,15 @@ struct process_kallsyms_args {
523 struct dso *dso; 524 struct dso *dso;
524}; 525};
525 526
527/*
528 * These are symbols in the kernel image, so make sure that
529 * sym is from a kernel DSO.
530 */
526bool symbol__is_idle(struct symbol *sym) 531bool symbol__is_idle(struct symbol *sym)
527{ 532{
528 const char * const idle_symbols[] = { 533 const char * const idle_symbols[] = {
529 "cpu_idle", 534 "cpu_idle",
535 "cpu_startup_entry",
530 "intel_idle", 536 "intel_idle",
531 "default_idle", 537 "default_idle",
532 "native_safe_halt", 538 "native_safe_halt",
@@ -1744,10 +1750,11 @@ static void vmlinux_path__exit(void)
1744 zfree(&vmlinux_path); 1750 zfree(&vmlinux_path);
1745} 1751}
1746 1752
1747static int vmlinux_path__init(void) 1753static int vmlinux_path__init(struct perf_session_env *env)
1748{ 1754{
1749 struct utsname uts; 1755 struct utsname uts;
1750 char bf[PATH_MAX]; 1756 char bf[PATH_MAX];
1757 char *kernel_version;
1751 1758
1752 vmlinux_path = malloc(sizeof(char *) * 5); 1759 vmlinux_path = malloc(sizeof(char *) * 5);
1753 if (vmlinux_path == NULL) 1760 if (vmlinux_path == NULL)
@@ -1762,25 +1769,31 @@ static int vmlinux_path__init(void)
1762 goto out_fail; 1769 goto out_fail;
1763 ++vmlinux_path__nr_entries; 1770 ++vmlinux_path__nr_entries;
1764 1771
1765 /* only try running kernel version if no symfs was given */ 1772 /* only try kernel version if no symfs was given */
1766 if (symbol_conf.symfs[0] != 0) 1773 if (symbol_conf.symfs[0] != 0)
1767 return 0; 1774 return 0;
1768 1775
1769 if (uname(&uts) < 0) 1776 if (env) {
1770 return -1; 1777 kernel_version = env->os_release;
1778 } else {
1779 if (uname(&uts) < 0)
1780 goto out_fail;
1781
1782 kernel_version = uts.release;
1783 }
1771 1784
1772 snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release); 1785 snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", kernel_version);
1773 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); 1786 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1774 if (vmlinux_path[vmlinux_path__nr_entries] == NULL) 1787 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1775 goto out_fail; 1788 goto out_fail;
1776 ++vmlinux_path__nr_entries; 1789 ++vmlinux_path__nr_entries;
1777 snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", uts.release); 1790 snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", kernel_version);
1778 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); 1791 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1779 if (vmlinux_path[vmlinux_path__nr_entries] == NULL) 1792 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1780 goto out_fail; 1793 goto out_fail;
1781 ++vmlinux_path__nr_entries; 1794 ++vmlinux_path__nr_entries;
1782 snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux", 1795 snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux",
1783 uts.release); 1796 kernel_version);
1784 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); 1797 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1785 if (vmlinux_path[vmlinux_path__nr_entries] == NULL) 1798 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1786 goto out_fail; 1799 goto out_fail;
@@ -1826,7 +1839,7 @@ static bool symbol__read_kptr_restrict(void)
1826 return value; 1839 return value;
1827} 1840}
1828 1841
1829int symbol__init(void) 1842int symbol__init(struct perf_session_env *env)
1830{ 1843{
1831 const char *symfs; 1844 const char *symfs;
1832 1845
@@ -1841,7 +1854,7 @@ int symbol__init(void)
1841 symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) - 1854 symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) -
1842 sizeof(struct symbol)); 1855 sizeof(struct symbol));
1843 1856
1844 if (symbol_conf.try_vmlinux_path && vmlinux_path__init() < 0) 1857 if (symbol_conf.try_vmlinux_path && vmlinux_path__init(env) < 0)
1845 return -1; 1858 return -1;
1846 1859
1847 if (symbol_conf.field_sep && *symbol_conf.field_sep == '.') { 1860 if (symbol_conf.field_sep && *symbol_conf.field_sep == '.') {
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 196b29104276..3f95ea0357e3 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -60,6 +60,7 @@ extern Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
60#endif 60#endif
61 61
62#ifndef DMGL_PARAMS 62#ifndef DMGL_PARAMS
63#define DMGL_NO_OPTS 0 /* For readability... */
63#define DMGL_PARAMS (1 << 0) /* Include function args */ 64#define DMGL_PARAMS (1 << 0) /* Include function args */
64#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ 65#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
65#endif 66#endif
@@ -262,7 +263,8 @@ int modules__parse(const char *filename, void *arg,
262int filename__read_debuglink(const char *filename, char *debuglink, 263int filename__read_debuglink(const char *filename, char *debuglink,
263 size_t size); 264 size_t size);
264 265
265int symbol__init(void); 266struct perf_session_env;
267int symbol__init(struct perf_session_env *env);
266void symbol__exit(void); 268void symbol__exit(void);
267void symbol__elf_init(void); 269void symbol__elf_init(void);
268struct symbol *symbol__new(u64 start, u64 len, u8 binding, const char *name); 270struct symbol *symbol__new(u64 start, u64 len, u8 binding, const char *name);
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 12c7a253a63c..a9df7f2c6dc9 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -42,7 +42,7 @@ struct thread *thread__new(pid_t pid, pid_t tid)
42 goto err_thread; 42 goto err_thread;
43 43
44 snprintf(comm_str, 32, ":%d", tid); 44 snprintf(comm_str, 32, ":%d", tid);
45 comm = comm__new(comm_str, 0); 45 comm = comm__new(comm_str, 0, false);
46 free(comm_str); 46 free(comm_str);
47 if (!comm) 47 if (!comm)
48 goto err_thread; 48 goto err_thread;
@@ -81,19 +81,33 @@ struct comm *thread__comm(const struct thread *thread)
81 return list_first_entry(&thread->comm_list, struct comm, list); 81 return list_first_entry(&thread->comm_list, struct comm, list);
82} 82}
83 83
84struct comm *thread__exec_comm(const struct thread *thread)
85{
86 struct comm *comm, *last = NULL;
87
88 list_for_each_entry(comm, &thread->comm_list, list) {
89 if (comm->exec)
90 return comm;
91 last = comm;
92 }
93
94 return last;
95}
96
84/* CHECKME: time should always be 0 if event aren't ordered */ 97/* CHECKME: time should always be 0 if event aren't ordered */
85int thread__set_comm(struct thread *thread, const char *str, u64 timestamp) 98int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp,
99 bool exec)
86{ 100{
87 struct comm *new, *curr = thread__comm(thread); 101 struct comm *new, *curr = thread__comm(thread);
88 int err; 102 int err;
89 103
90 /* Override latest entry if it had no specific time coverage */ 104 /* Override latest entry if it had no specific time coverage */
91 if (!curr->start) { 105 if (!curr->start && !curr->exec) {
92 err = comm__override(curr, str, timestamp); 106 err = comm__override(curr, str, timestamp, exec);
93 if (err) 107 if (err)
94 return err; 108 return err;
95 } else { 109 } else {
96 new = comm__new(str, timestamp); 110 new = comm__new(str, timestamp, exec);
97 if (!new) 111 if (!new)
98 return -ENOMEM; 112 return -ENOMEM;
99 list_add(&new->list, &thread->comm_list); 113 list_add(&new->list, &thread->comm_list);
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 716b7723cce2..8c75fa774706 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -38,9 +38,17 @@ static inline void thread__exited(struct thread *thread)
38 thread->dead = true; 38 thread->dead = true;
39} 39}
40 40
41int thread__set_comm(struct thread *thread, const char *comm, u64 timestamp); 41int __thread__set_comm(struct thread *thread, const char *comm, u64 timestamp,
42 bool exec);
43static inline int thread__set_comm(struct thread *thread, const char *comm,
44 u64 timestamp)
45{
46 return __thread__set_comm(thread, comm, timestamp, false);
47}
48
42int thread__comm_len(struct thread *thread); 49int thread__comm_len(struct thread *thread);
43struct comm *thread__comm(const struct thread *thread); 50struct comm *thread__comm(const struct thread *thread);
51struct comm *thread__exec_comm(const struct thread *thread);
44const char *thread__comm_str(const struct thread *thread); 52const char *thread__comm_str(const struct thread *thread);
45void thread__insert_map(struct thread *thread, struct map *map); 53void thread__insert_map(struct thread *thread, struct map *map);
46int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp); 54int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp);
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index b82a93cb1694..25822bdf7bbf 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -13,6 +13,7 @@
13#include <limits.h> 13#include <limits.h>
14#include <byteswap.h> 14#include <byteswap.h>
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <unistd.h>
16 17
17/* 18/*
18 * XXX We need to find a better place for these things... 19 * XXX We need to find a better place for these things...
@@ -282,6 +283,18 @@ void get_term_dimensions(struct winsize *ws)
282 ws->ws_col = 80; 283 ws->ws_col = 80;
283} 284}
284 285
286void set_term_quiet_input(struct termios *old)
287{
288 struct termios tc;
289
290 tcgetattr(0, old);
291 tc = *old;
292 tc.c_lflag &= ~(ICANON | ECHO);
293 tc.c_cc[VMIN] = 0;
294 tc.c_cc[VTIME] = 0;
295 tcsetattr(0, TCSANOW, &tc);
296}
297
285static void set_tracing_events_path(const char *mountpoint) 298static void set_tracing_events_path(const char *mountpoint)
286{ 299{
287 snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s", 300 snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s",
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 03a1ea2266b8..d6a79b1fb28c 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -75,6 +75,7 @@
75#include <api/fs/debugfs.h> 75#include <api/fs/debugfs.h>
76#include <termios.h> 76#include <termios.h>
77#include <linux/bitops.h> 77#include <linux/bitops.h>
78#include <termios.h>
78 79
79extern const char *graph_line; 80extern const char *graph_line;
80extern const char *graph_dotted_line; 81extern const char *graph_dotted_line;
@@ -308,6 +309,7 @@ extern unsigned int page_size;
308extern int cacheline_size; 309extern int cacheline_size;
309 310
310void get_term_dimensions(struct winsize *ws); 311void get_term_dimensions(struct winsize *ws);
312void set_term_quiet_input(struct termios *old);
311 313
312struct parse_tag { 314struct parse_tag {
313 char tag; 315 char tag;