Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core

Pull perf/core refactorings and fixes from Arnaldo Carvalho de Melo:

Infrastructure changes:

- Revert "perf tools: Improve setting of gcc debug option", -Og is broken,
GCC PR created (Jiri Olsa)

- More reference count fixes (Masami Hiramatsu)

- Untangle browser setup (--stdio, --tui, etc) from argument checking,
prep work to move the usage() code out of tools/perf for use by
other tools/ living utilities (Namhyung Kim)

- Delete half-processed hist entries when exiting 'perf top' (Namhyung Kim)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>

+73 -66
+16 -17
tools/perf/builtin-annotate.c
··· 343 343 return ret; 344 344 345 345 argc = parse_options(argc, argv, options, annotate_usage, 0); 346 + if (argc) { 347 + /* 348 + * Special case: if there's an argument left then assume that 349 + * it's a symbol filter: 350 + */ 351 + if (argc > 1) 352 + usage_with_options(annotate_usage, options); 346 353 347 - if (annotate.use_stdio) 348 - use_browser = 0; 349 - else if (annotate.use_tui) 350 - use_browser = 1; 351 - else if (annotate.use_gtk) 352 - use_browser = 2; 354 + annotate.sym_hist_filter = argv[0]; 355 + } 353 356 354 357 file.path = input_name; 355 - 356 - setup_browser(true); 357 358 358 359 annotate.session = perf_session__new(&file, false, &annotate.tool); 359 360 if (annotate.session == NULL) ··· 370 369 if (setup_sorting() < 0) 371 370 usage_with_options(annotate_usage, options); 372 371 373 - if (argc) { 374 - /* 375 - * Special case: if there's an argument left then assume that 376 - * it's a symbol filter: 377 - */ 378 - if (argc > 1) 379 - usage_with_options(annotate_usage, options); 372 + if (annotate.use_stdio) 373 + use_browser = 0; 374 + else if (annotate.use_tui) 375 + use_browser = 1; 376 + else if (annotate.use_gtk) 377 + use_browser = 2; 380 378 381 - annotate.sym_hist_filter = argv[0]; 382 - } 379 + setup_browser(true); 383 380 384 381 ret = __cmd_annotate(&annotate); 385 382
-3
tools/perf/builtin-kvm.c
··· 1351 1351 disable_buildid_cache(); 1352 1352 1353 1353 use_browser = 0; 1354 - setup_browser(false); 1355 1354 1356 1355 if (argc) { 1357 1356 argc = parse_options(argc, argv, live_options, ··· 1408 1409 err = kvm_events_live_report(kvm); 1409 1410 1410 1411 out: 1411 - exit_browser(0); 1412 - 1413 1412 if (kvm->session) 1414 1413 perf_session__delete(kvm->session); 1415 1414 kvm->session = NULL;
+10 -11
tools/perf/builtin-report.c
··· 801 801 perf_config(report__config, &report); 802 802 803 803 argc = parse_options(argc, argv, options, report_usage, 0); 804 + if (argc) { 805 + /* 806 + * Special case: if there's an argument left then assume that 807 + * it's a symbol filter: 808 + */ 809 + if (argc > 1) 810 + usage_with_options(report_usage, options); 811 + 812 + report.symbol_filter_str = argv[0]; 813 + } 804 814 805 815 if (symbol_conf.vmlinux_name && 806 816 access(symbol_conf.vmlinux_name, R_OK)) { ··· 955 945 956 946 if (symbol__init(&session->header.env) < 0) 957 947 goto error; 958 - 959 - if (argc) { 960 - /* 961 - * Special case: if there's an argument left then assume that 962 - * it's a symbol filter: 963 - */ 964 - if (argc > 1) 965 - usage_with_options(report_usage, options); 966 - 967 - report.symbol_filter_str = argv[0]; 968 - } 969 948 970 949 sort__setup_elide(stdout); 971 950
+6 -3
tools/perf/builtin-top.c
··· 964 964 if (ret) 965 965 goto out_delete; 966 966 967 - if (perf_session__register_idle_thread(top->session) == NULL) 967 + if (perf_session__register_idle_thread(top->session) < 0) 968 968 goto out_delete; 969 969 970 970 machine__synthesize_threads(&top->session->machines.host, &opts->target, ··· 1279 1279 if (target__none(target)) 1280 1280 target->system_wide = true; 1281 1281 1282 - if (perf_evlist__create_maps(top.evlist, target) < 0) 1283 - usage_with_options(top_usage, options); 1282 + if (perf_evlist__create_maps(top.evlist, target) < 0) { 1283 + ui__error("Couldn't create thread/CPU maps: %s\n", 1284 + errno == ENOENT ? "No such process" : strerror_r(errno, errbuf, sizeof(errbuf))); 1285 + goto out_delete_evlist; 1286 + } 1284 1287 1285 1288 if (!top.evlist->nr_entries && 1286 1289 perf_evlist__add_default(top.evlist) < 0) {
-2
tools/perf/config/Makefile
··· 135 135 136 136 ifeq ($(DEBUG),0) 137 137 CFLAGS += -O6 138 - else 139 - CFLAGS += $(call cc-option,-Og,-O0) 140 138 endif 141 139 142 140 ifdef PARSER_DEBUG
-19
tools/perf/config/utilities.mak
··· 177 177 endef 178 178 _ge_attempt = $(if $(get-executable),$(get-executable),$(call _gea_err,$(2))) 179 179 _gea_err = $(if $(1),$(error Please set '$(1)' appropriately)) 180 - 181 - # try-run 182 - # Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise) 183 - # Exit code chooses option. "$$TMP" is can be used as temporary file and 184 - # is automatically cleaned up. 185 - try-run = $(shell set -e; \ 186 - TMP="$(TMPOUT).$$$$.tmp"; \ 187 - TMPO="$(TMPOUT).$$$$.o"; \ 188 - if ($(1)) >/dev/null 2>&1; \ 189 - then echo "$(2)"; \ 190 - else echo "$(3)"; \ 191 - fi; \ 192 - rm -f "$$TMP" "$$TMPO") 193 - 194 - # cc-option 195 - # Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586) 196 - 197 - cc-option = $(call try-run,\ 198 - $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2))
+25 -1
tools/perf/util/hist.c
··· 270 270 271 271 if (sort__need_collapse) 272 272 rb_erase(&he->rb_node_in, &hists->entries_collapsed); 273 + else 274 + rb_erase(&he->rb_node_in, hists->entries_in); 273 275 274 276 --hists->nr_entries; 275 277 if (!he->filtered) ··· 1569 1567 return 0; 1570 1568 } 1571 1569 1570 + static void hists__delete_remaining_entries(struct rb_root *root) 1571 + { 1572 + struct rb_node *node; 1573 + struct hist_entry *he; 1574 + 1575 + while (!RB_EMPTY_ROOT(root)) { 1576 + node = rb_first(root); 1577 + rb_erase(node, root); 1578 + 1579 + he = rb_entry(node, struct hist_entry, rb_node_in); 1580 + hist_entry__delete(he); 1581 + } 1582 + } 1583 + 1584 + static void hists__delete_all_entries(struct hists *hists) 1585 + { 1586 + hists__delete_entries(hists); 1587 + hists__delete_remaining_entries(&hists->entries_in_array[0]); 1588 + hists__delete_remaining_entries(&hists->entries_in_array[1]); 1589 + hists__delete_remaining_entries(&hists->entries_collapsed); 1590 + } 1591 + 1572 1592 static void hists_evsel__exit(struct perf_evsel *evsel) 1573 1593 { 1574 1594 struct hists *hists = evsel__hists(evsel); 1575 1595 1576 - hists__delete_entries(hists); 1596 + hists__delete_all_entries(hists); 1577 1597 } 1578 1598 1579 1599 /*
-3
tools/perf/util/parse-options.c
··· 766 766 void usage_with_options(const char * const *usagestr, 767 767 const struct option *opts) 768 768 { 769 - exit_browser(false); 770 769 usage_with_options_internal(usagestr, opts, 0, NULL); 771 770 exit(129); 772 771 } ··· 774 775 const struct option *opts, const char *fmt, ...) 775 776 { 776 777 va_list ap; 777 - 778 - exit_browser(false); 779 778 780 779 va_start(ap, fmt); 781 780 strbuf_addv(&error_buf, fmt, ap);
+7 -4
tools/perf/util/session.c
··· 1311 1311 return machine__findnew_thread(&session->machines.host, -1, pid); 1312 1312 } 1313 1313 1314 - struct thread *perf_session__register_idle_thread(struct perf_session *session) 1314 + int perf_session__register_idle_thread(struct perf_session *session) 1315 1315 { 1316 1316 struct thread *thread; 1317 + int err = 0; 1317 1318 1318 1319 thread = machine__findnew_thread(&session->machines.host, 0, 0); 1319 1320 if (thread == NULL || thread__set_comm(thread, "swapper", 0)) { 1320 1321 pr_err("problem inserting idle task.\n"); 1321 - thread = NULL; 1322 + err = -1; 1322 1323 } 1323 1324 1324 - return thread; 1325 + /* machine__findnew_thread() got the thread, so put it */ 1326 + thread__put(thread); 1327 + return err; 1325 1328 } 1326 1329 1327 1330 static void perf_session__warn_about_errors(const struct perf_session *session) ··· 1679 1676 u64 size = perf_data_file__size(session->file); 1680 1677 int err; 1681 1678 1682 - if (perf_session__register_idle_thread(session) == NULL) 1679 + if (perf_session__register_idle_thread(session) < 0) 1683 1680 return -ENOMEM; 1684 1681 1685 1682 if (!perf_data_file__is_pipe(session->file))
+1 -1
tools/perf/util/session.h
··· 89 89 } 90 90 91 91 struct thread *perf_session__findnew(struct perf_session *session, pid_t pid); 92 - struct thread *perf_session__register_idle_thread(struct perf_session *session); 92 + int perf_session__register_idle_thread(struct perf_session *session); 93 93 94 94 size_t perf_session__fprintf(struct perf_session *session, FILE *fp); 95 95
+7 -2
tools/perf/util/symbol-elf.c
··· 1026 1026 curr_dso->long_name_len = dso->long_name_len; 1027 1027 curr_map = map__new2(start, curr_dso, 1028 1028 map->type); 1029 + dso__put(curr_dso); 1029 1030 if (curr_map == NULL) { 1030 - dso__put(curr_dso); 1031 1031 goto out_elf_end; 1032 1032 } 1033 1033 if (adjust_kernel_syms) { ··· 1042 1042 } 1043 1043 curr_dso->symtab_type = dso->symtab_type; 1044 1044 map_groups__insert(kmaps, curr_map); 1045 + /* 1046 + * Add it before we drop the referece to curr_map, 1047 + * i.e. while we still are sure to have a reference 1048 + * to this DSO via curr_map->dso. 1049 + */ 1050 + dsos__add(&map->groups->machine->dsos, curr_dso); 1045 1051 /* kmaps already got it */ 1046 1052 map__put(curr_map); 1047 - dsos__add(&map->groups->machine->dsos, curr_dso); 1048 1053 dso__set_loaded(curr_dso, map->type); 1049 1054 } else 1050 1055 curr_dso = curr_map->dso;
+1
tools/perf/util/thread_map.c
··· 304 304 305 305 out_free_threads: 306 306 zfree(&threads); 307 + strlist__delete(slist); 307 308 goto out; 308 309 } 309 310