perf/core refactorings and fixes:

Infrastructure:
 
 - 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>
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJWadUsAAoJENZQFvNTUqpAPkUP/A1JdGbSzgXAUhVO9uGxR8tP
 fnJlvun8J/qjCzLNfzFBH/UkbHyBjNoXj+dt846HH9chJuzO9zI3Nn5bshcHIpHj
 30Qu+K9eMtYchDRZc4wfLgT/ciatfn4bp6RTPZZzVJGKQyY7cxYydeEQnMqCYdJ5
 LPkA76qAvESMOj47RrJEFO/L3VJb2cUcaG7WrDiKVLjSw6yWOCTX+ESVHnQX6QPx
 LeUYNvmUht6ZtVMVG3xVnIMBYmNJDVjPimPtmqNCbn4J+gaAeSInYdVWRGn6BMCY
 qm9OEZAOcDqRA2uKRQF/ytHalHQngJgoIfo6vI2KkyPcRptqS1LHy03qckYac3FV
 Rsk+tHWa+tZmDlmnxILl7QSp2rDfc9npD+c9bYRfuScyGwdIaTfWhHCOIoqx6IdO
 UB8Tlfmhx0m+2ffItKfx+U9UlMBDdkJfN7HMfqNObkSZ/oIRFcktyTOQAwxNkyoG
 4iDBGJi4sUb2pKNnSZLytqB/75oQ5b5UiXyBuyaARO9eVIzZcZiK/E9nmZ5K6Evu
 b2sc1XYZkthaAVxUu7yzI1y12rARQqefZJQJwJrzKRnBrAEYHLQ4H1bO4feh1BgM
 7T3+4UZYAFBjio1WLgAlwc3SOYfqjNqAqQjct2RyLSamWJuRS2n9JY8y60Uns68h
 OqTqhyO9XEMVMGed06Iv
 =nr7K
 -----END PGP SIGNATURE-----

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>
This commit is contained in:
Ingo Molnar 2015-12-11 08:47:25 +01:00
commit 54c9238cfd
12 changed files with 73 additions and 66 deletions

View File

@ -343,18 +343,19 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
return ret; return ret;
argc = parse_options(argc, argv, options, annotate_usage, 0); argc = parse_options(argc, argv, options, annotate_usage, 0);
if (argc) {
/*
* Special case: if there's an argument left then assume that
* it's a symbol filter:
*/
if (argc > 1)
usage_with_options(annotate_usage, options);
if (annotate.use_stdio) annotate.sym_hist_filter = argv[0];
use_browser = 0; }
else if (annotate.use_tui)
use_browser = 1;
else if (annotate.use_gtk)
use_browser = 2;
file.path = input_name; file.path = input_name;
setup_browser(true);
annotate.session = perf_session__new(&file, false, &annotate.tool); annotate.session = perf_session__new(&file, false, &annotate.tool);
if (annotate.session == NULL) if (annotate.session == NULL)
return -1; return -1;
@ -369,16 +370,14 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
if (setup_sorting() < 0) if (setup_sorting() < 0)
usage_with_options(annotate_usage, options); usage_with_options(annotate_usage, options);
if (argc) { if (annotate.use_stdio)
/* use_browser = 0;
* Special case: if there's an argument left then assume that else if (annotate.use_tui)
* it's a symbol filter: use_browser = 1;
*/ else if (annotate.use_gtk)
if (argc > 1) use_browser = 2;
usage_with_options(annotate_usage, options);
annotate.sym_hist_filter = argv[0]; setup_browser(true);
}
ret = __cmd_annotate(&annotate); ret = __cmd_annotate(&annotate);

View File

@ -1351,7 +1351,6 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
disable_buildid_cache(); disable_buildid_cache();
use_browser = 0; use_browser = 0;
setup_browser(false);
if (argc) { if (argc) {
argc = parse_options(argc, argv, live_options, argc = parse_options(argc, argv, live_options,
@ -1409,8 +1408,6 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
err = kvm_events_live_report(kvm); err = kvm_events_live_report(kvm);
out: out:
exit_browser(0);
if (kvm->session) if (kvm->session)
perf_session__delete(kvm->session); perf_session__delete(kvm->session);
kvm->session = NULL; kvm->session = NULL;

View File

@ -801,6 +801,16 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
perf_config(report__config, &report); perf_config(report__config, &report);
argc = parse_options(argc, argv, options, report_usage, 0); argc = parse_options(argc, argv, options, report_usage, 0);
if (argc) {
/*
* Special case: if there's an argument left then assume that
* it's a symbol filter:
*/
if (argc > 1)
usage_with_options(report_usage, options);
report.symbol_filter_str = argv[0];
}
if (symbol_conf.vmlinux_name && if (symbol_conf.vmlinux_name &&
access(symbol_conf.vmlinux_name, R_OK)) { access(symbol_conf.vmlinux_name, R_OK)) {
@ -946,17 +956,6 @@ repeat:
if (symbol__init(&session->header.env) < 0) if (symbol__init(&session->header.env) < 0)
goto error; goto error;
if (argc) {
/*
* Special case: if there's an argument left then assume that
* it's a symbol filter:
*/
if (argc > 1)
usage_with_options(report_usage, options);
report.symbol_filter_str = argv[0];
}
sort__setup_elide(stdout); sort__setup_elide(stdout);
ret = __cmd_report(&report); ret = __cmd_report(&report);

View File

@ -964,7 +964,7 @@ static int __cmd_top(struct perf_top *top)
if (ret) if (ret)
goto out_delete; goto out_delete;
if (perf_session__register_idle_thread(top->session) == NULL) if (perf_session__register_idle_thread(top->session) < 0)
goto out_delete; goto out_delete;
machine__synthesize_threads(&top->session->machines.host, &opts->target, machine__synthesize_threads(&top->session->machines.host, &opts->target,
@ -1279,8 +1279,11 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
if (target__none(target)) if (target__none(target))
target->system_wide = true; target->system_wide = true;
if (perf_evlist__create_maps(top.evlist, target) < 0) if (perf_evlist__create_maps(top.evlist, target) < 0) {
usage_with_options(top_usage, options); ui__error("Couldn't create thread/CPU maps: %s\n",
errno == ENOENT ? "No such process" : strerror_r(errno, errbuf, sizeof(errbuf)));
goto out_delete_evlist;
}
if (!top.evlist->nr_entries && if (!top.evlist->nr_entries &&
perf_evlist__add_default(top.evlist) < 0) { perf_evlist__add_default(top.evlist) < 0) {

View File

@ -135,8 +135,6 @@ endif
ifeq ($(DEBUG),0) ifeq ($(DEBUG),0)
CFLAGS += -O6 CFLAGS += -O6
else
CFLAGS += $(call cc-option,-Og,-O0)
endif endif
ifdef PARSER_DEBUG ifdef PARSER_DEBUG

View File

@ -177,22 +177,3 @@ $(if $($(1)),$(call _ge_attempt,$($(1)),$(1)),$(call _ge_attempt,$(2)))
endef endef
_ge_attempt = $(if $(get-executable),$(get-executable),$(call _gea_err,$(2))) _ge_attempt = $(if $(get-executable),$(get-executable),$(call _gea_err,$(2)))
_gea_err = $(if $(1),$(error Please set '$(1)' appropriately)) _gea_err = $(if $(1),$(error Please set '$(1)' appropriately))
# try-run
# Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise)
# Exit code chooses option. "$$TMP" is can be used as temporary file and
# is automatically cleaned up.
try-run = $(shell set -e; \
TMP="$(TMPOUT).$$$$.tmp"; \
TMPO="$(TMPOUT).$$$$.o"; \
if ($(1)) >/dev/null 2>&1; \
then echo "$(2)"; \
else echo "$(3)"; \
fi; \
rm -f "$$TMP" "$$TMPO")
# cc-option
# Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586)
cc-option = $(call try-run,\
$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2))

View File

@ -270,6 +270,8 @@ static void hists__delete_entry(struct hists *hists, struct hist_entry *he)
if (sort__need_collapse) if (sort__need_collapse)
rb_erase(&he->rb_node_in, &hists->entries_collapsed); rb_erase(&he->rb_node_in, &hists->entries_collapsed);
else
rb_erase(&he->rb_node_in, hists->entries_in);
--hists->nr_entries; --hists->nr_entries;
if (!he->filtered) if (!he->filtered)
@ -1567,11 +1569,33 @@ static int hists_evsel__init(struct perf_evsel *evsel)
return 0; return 0;
} }
static void hists__delete_remaining_entries(struct rb_root *root)
{
struct rb_node *node;
struct hist_entry *he;
while (!RB_EMPTY_ROOT(root)) {
node = rb_first(root);
rb_erase(node, root);
he = rb_entry(node, struct hist_entry, rb_node_in);
hist_entry__delete(he);
}
}
static void hists__delete_all_entries(struct hists *hists)
{
hists__delete_entries(hists);
hists__delete_remaining_entries(&hists->entries_in_array[0]);
hists__delete_remaining_entries(&hists->entries_in_array[1]);
hists__delete_remaining_entries(&hists->entries_collapsed);
}
static void hists_evsel__exit(struct perf_evsel *evsel) static void hists_evsel__exit(struct perf_evsel *evsel)
{ {
struct hists *hists = evsel__hists(evsel); struct hists *hists = evsel__hists(evsel);
hists__delete_entries(hists); hists__delete_all_entries(hists);
} }
/* /*

View File

@ -766,7 +766,6 @@ int usage_with_options_internal(const char * const *usagestr,
void usage_with_options(const char * const *usagestr, void usage_with_options(const char * const *usagestr,
const struct option *opts) const struct option *opts)
{ {
exit_browser(false);
usage_with_options_internal(usagestr, opts, 0, NULL); usage_with_options_internal(usagestr, opts, 0, NULL);
exit(129); exit(129);
} }
@ -776,8 +775,6 @@ void usage_with_options_msg(const char * const *usagestr,
{ {
va_list ap; va_list ap;
exit_browser(false);
va_start(ap, fmt); va_start(ap, fmt);
strbuf_addv(&error_buf, fmt, ap); strbuf_addv(&error_buf, fmt, ap);
va_end(ap); va_end(ap);

View File

@ -1311,17 +1311,20 @@ struct thread *perf_session__findnew(struct perf_session *session, pid_t pid)
return machine__findnew_thread(&session->machines.host, -1, pid); return machine__findnew_thread(&session->machines.host, -1, pid);
} }
struct thread *perf_session__register_idle_thread(struct perf_session *session) int perf_session__register_idle_thread(struct perf_session *session)
{ {
struct thread *thread; struct thread *thread;
int err = 0;
thread = machine__findnew_thread(&session->machines.host, 0, 0); thread = machine__findnew_thread(&session->machines.host, 0, 0);
if (thread == NULL || thread__set_comm(thread, "swapper", 0)) { if (thread == NULL || thread__set_comm(thread, "swapper", 0)) {
pr_err("problem inserting idle task.\n"); pr_err("problem inserting idle task.\n");
thread = NULL; err = -1;
} }
return thread; /* machine__findnew_thread() got the thread, so put it */
thread__put(thread);
return err;
} }
static void perf_session__warn_about_errors(const struct perf_session *session) static void perf_session__warn_about_errors(const struct perf_session *session)
@ -1676,7 +1679,7 @@ int perf_session__process_events(struct perf_session *session)
u64 size = perf_data_file__size(session->file); u64 size = perf_data_file__size(session->file);
int err; int err;
if (perf_session__register_idle_thread(session) == NULL) if (perf_session__register_idle_thread(session) < 0)
return -ENOMEM; return -ENOMEM;
if (!perf_data_file__is_pipe(session->file)) if (!perf_data_file__is_pipe(session->file))

View File

@ -89,7 +89,7 @@ struct machine *perf_session__findnew_machine(struct perf_session *session, pid_
} }
struct thread *perf_session__findnew(struct perf_session *session, pid_t pid); struct thread *perf_session__findnew(struct perf_session *session, pid_t pid);
struct thread *perf_session__register_idle_thread(struct perf_session *session); int perf_session__register_idle_thread(struct perf_session *session);
size_t perf_session__fprintf(struct perf_session *session, FILE *fp); size_t perf_session__fprintf(struct perf_session *session, FILE *fp);

View File

@ -1026,8 +1026,8 @@ int dso__load_sym(struct dso *dso, struct map *map,
curr_dso->long_name_len = dso->long_name_len; curr_dso->long_name_len = dso->long_name_len;
curr_map = map__new2(start, curr_dso, curr_map = map__new2(start, curr_dso,
map->type); map->type);
dso__put(curr_dso);
if (curr_map == NULL) { if (curr_map == NULL) {
dso__put(curr_dso);
goto out_elf_end; goto out_elf_end;
} }
if (adjust_kernel_syms) { if (adjust_kernel_syms) {
@ -1042,9 +1042,14 @@ int dso__load_sym(struct dso *dso, struct map *map,
} }
curr_dso->symtab_type = dso->symtab_type; curr_dso->symtab_type = dso->symtab_type;
map_groups__insert(kmaps, curr_map); map_groups__insert(kmaps, curr_map);
/*
* Add it before we drop the referece to curr_map,
* i.e. while we still are sure to have a reference
* to this DSO via curr_map->dso.
*/
dsos__add(&map->groups->machine->dsos, curr_dso);
/* kmaps already got it */ /* kmaps already got it */
map__put(curr_map); map__put(curr_map);
dsos__add(&map->groups->machine->dsos, curr_dso);
dso__set_loaded(curr_dso, map->type); dso__set_loaded(curr_dso, map->type);
} else } else
curr_dso = curr_map->dso; curr_dso = curr_map->dso;

View File

@ -304,6 +304,7 @@ out:
out_free_threads: out_free_threads:
zfree(&threads); zfree(&threads);
strlist__delete(slist);
goto out; goto out;
} }