diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-02-28 11:38:18 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-02-28 11:38:18 -0800 |
commit | 3f26b0c876bbfeed74325ada0329de53efbdf7a6 (patch) | |
tree | 10001aca5e2ff11e9d84514f8e4fcd050e944513 | |
parent | 74efe07bc38c538ba7ac40a895910f4f3bee3152 (diff) | |
parent | 1572e45a924f254d9570093abde46430c3172e3d (diff) |
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf fixes from Ingo Molnar:
"Misc fixes on the kernel and tooling side - nothing in particular
stands out"
* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (21 commits)
perf/core: Fix the perf_cpu_time_max_percent check
perf/core: Fix perf_event_enable_on_exec() timekeeping (again)
perf/core: Remove confusing comment and move put_ctx()
perf record: Honor --quiet option properly
perf annotate: Add -q/--quiet option
perf diff: Add -q/--quiet option
perf report: Add -q/--quiet option
perf utils: Check verbose flag properly
perf utils: Add perf_quiet_option()
perf record: Add -a as default target
perf stat: Add -a as default target
perf tools: Fail on using multiple bits long terms without value
perf tools: Move new_term arguments into struct parse_events_term template
perf build: Add special fixdep cleaning rule
perf tools: Replace _SC_NPROCESSORS_CONF with max_present_cpu in cpu_topology_map
perf header: Make build_cpu_topology skip offline/absent CPUs
perf cpumap: Add cpu__max_present_cpu()
perf session: Fix DEBUG=1 build with clang
tools lib traceevent: It's preempt not prempt
perf python: Filter out -specs=/a/b/c from the python binding cc options
...
55 files changed, 260 insertions, 137 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c index 5b4e0b98f4eb..1031bdf9f012 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -455,7 +455,7 @@ int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { - int ret = proc_dointvec(table, write, buffer, lenp, ppos); + int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); if (ret || !write) return ret; @@ -3522,6 +3522,8 @@ static void perf_event_enable_on_exec(int ctxn) if (enabled) { clone_ctx = unclone_ctx(ctx); ctx_resched(cpuctx, ctx, event_type); + } else { + ctx_sched_in(ctx, cpuctx, EVENT_TIME, current); } perf_ctx_unlock(cpuctx, ctx); @@ -9955,6 +9957,7 @@ SYSCALL_DEFINE5(perf_event_open, * of swizzling perf_event::ctx. */ perf_remove_from_context(group_leader, 0); + put_ctx(gctx); list_for_each_entry(sibling, &group_leader->sibling_list, group_entry) { @@ -9993,13 +9996,6 @@ SYSCALL_DEFINE5(perf_event_open, perf_event__state_init(group_leader); perf_install_in_context(ctx, group_leader, group_leader->cpu); get_ctx(ctx); - - /* - * Now that all events are installed in @ctx, nothing - * references @gctx anymore, so drop the last reference we have - * on it. - */ - put_ctx(gctx); } /* diff --git a/tools/build/Makefile b/tools/build/Makefile index aaf7ed329a45..477f00eda591 100644 --- a/tools/build/Makefile +++ b/tools/build/Makefile @@ -35,8 +35,8 @@ all: $(OUTPUT)fixdep clean: $(call QUIET_CLEAN, fixdep) - $(Q)find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete - $(Q)rm -f fixdep + $(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete + $(Q)rm -f $(OUTPUT)fixdep $(OUTPUT)fixdep-in.o: FORCE $(Q)$(MAKE) $(build)=fixdep diff --git a/tools/build/Makefile.include b/tools/build/Makefile.include index ad22e4e7bc59..d360f39a445b 100644 --- a/tools/build/Makefile.include +++ b/tools/build/Makefile.include @@ -3,4 +3,7 @@ build := -f $(srctree)/tools/build/Makefile.build dir=. obj fixdep: $(Q)$(MAKE) -C $(srctree)/tools/build CFLAGS= LDFLAGS= $(OUTPUT)fixdep +fixdep-clean: + $(Q)$(MAKE) -C $(srctree)/tools/build clean + .PHONY: fixdep diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index f2ea78021450..7ce724fc0544 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -5225,13 +5225,13 @@ int pevent_data_pid(struct pevent *pevent, struct pevent_record *rec) } /** - * pevent_data_prempt_count - parse the preempt count from the record + * pevent_data_preempt_count - parse the preempt count from the record * @pevent: a handle to the pevent * @rec: the record to parse * * This returns the preempt count from a record. */ -int pevent_data_prempt_count(struct pevent *pevent, struct pevent_record *rec) +int pevent_data_preempt_count(struct pevent *pevent, struct pevent_record *rec) { return parse_common_pc(pevent, rec->data); } diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h index 74cecba87daa..66342804161c 100644 --- a/tools/lib/traceevent/event-parse.h +++ b/tools/lib/traceevent/event-parse.h @@ -710,7 +710,7 @@ void pevent_data_lat_fmt(struct pevent *pevent, int pevent_data_type(struct pevent *pevent, struct pevent_record *rec); struct event_format *pevent_data_event_from_type(struct pevent *pevent, int type); int pevent_data_pid(struct pevent *pevent, struct pevent_record *rec); -int pevent_data_prempt_count(struct pevent *pevent, struct pevent_record *rec); +int pevent_data_preempt_count(struct pevent *pevent, struct pevent_record *rec); int pevent_data_flags(struct pevent *pevent, struct pevent_record *rec); const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid); struct cmdline; diff --git a/tools/perf/Documentation/perf-annotate.txt b/tools/perf/Documentation/perf-annotate.txt index 8ffbd272952d..a89273d8e744 100644 --- a/tools/perf/Documentation/perf-annotate.txt +++ b/tools/perf/Documentation/perf-annotate.txt @@ -39,6 +39,10 @@ OPTIONS --verbose:: Be more verbose. (Show symbol address, etc) +-q:: +--quiet:: + Do not show any message. (Suppress -v) + -D:: --dump-raw-trace:: Dump raw trace in ASCII. diff --git a/tools/perf/Documentation/perf-diff.txt b/tools/perf/Documentation/perf-diff.txt index 66dbe3dee74b..a79c84ae61aa 100644 --- a/tools/perf/Documentation/perf-diff.txt +++ b/tools/perf/Documentation/perf-diff.txt @@ -73,6 +73,10 @@ OPTIONS Be verbose, for instance, show the raw counts in addition to the diff. +-q:: +--quiet:: + Do not show any message. (Suppress -v) + -f:: --force:: Don't do ownership validation. diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index 27256bc68eda..b16003ec14a7 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -157,7 +157,7 @@ OPTIONS -a:: --all-cpus:: - System-wide collection from all CPUs. + System-wide collection from all CPUs (default if no target is specified). -p:: --pid=:: diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index f2914f03ae7b..c04cc0647c16 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -25,6 +25,10 @@ OPTIONS --verbose:: Be more verbose. (show symbol address, etc) +-q:: +--quiet:: + Do not show any message. (Suppress -v) + -n:: --show-nr-samples:: Show the number of samples for each symbol diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt index d96ccd4844df..aecf2a87e7d6 100644 --- a/tools/perf/Documentation/perf-stat.txt +++ b/tools/perf/Documentation/perf-stat.txt @@ -63,7 +63,7 @@ report:: -a:: --all-cpus:: - system-wide collection from all CPUs + system-wide collection from all CPUs (default if no target is specified) -c:: --scale:: diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index 2b941efadb04..27c9fbca7bd9 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -175,6 +175,10 @@ PYTHON_CONFIG_SQ := $(call shell-sq,$(PYTHON_CONFIG)) PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null) PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) +ifeq ($(CC), clang) + PYTHON_EMBED_CCOPTS := $(filter-out -specs=%,$(PYTHON_EMBED_CCOPTS)) +endif + FEATURE_CHECK_CFLAGS-libpython := $(PYTHON_EMBED_CCOPTS) FEATURE_CHECK_LDFLAGS-libpython := $(PYTHON_EMBED_LDOPTS) FEATURE_CHECK_CFLAGS-libpython-version := $(PYTHON_EMBED_CCOPTS) @@ -601,6 +605,9 @@ else PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS)) PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS)) -lutil PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) + ifeq ($(CC), clang) + PYTHON_EMBED_CCOPTS := $(filter-out -specs=%,$(PYTHON_EMBED_CCOPTS)) + endif FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) ifneq ($(feature-libpython), 1) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 4da19b6ba94a..79fe31f20a17 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -726,13 +726,13 @@ config-clean: $(call QUIET_CLEAN, config) $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ $(if $(OUTPUT),OUTPUT=$(OUTPUT)feature/,) clean >/dev/null -clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean config-clean +clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean config-clean fixdep-clean $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS) $(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete $(Q)$(RM) $(OUTPUT).config-detected $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32 $(OUTPUT)pmu-events/jevents $(OUTPUT)$(LIBJVMTI).so $(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)FEATURE-DUMP $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* \ - $(OUTPUT)util/intel-pt-decoder/inat-tables.c $(OUTPUT)fixdep \ + $(OUTPUT)util/intel-pt-decoder/inat-tables.c \ $(OUTPUT)tests/llvm-src-{base,kbuild,prologue,relocation}.c \ $(OUTPUT)pmu-events/pmu-events.c $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index ebb628332a6e..4f52d85f5ebc 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -410,6 +410,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"), OPT_INCR('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"), + OPT_BOOLEAN('q', "quiet", &quiet, "do now show any message"), OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, "dump raw trace in ASCII"), OPT_BOOLEAN(0, "gtk", &annotate.use_gtk, "Use the GTK interface"), @@ -463,6 +464,9 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) annotate.sym_hist_filter = argv[0]; } + if (quiet) + perf_quiet_option(); + file.path = input_name; annotate.session = perf_session__new(&file, false, &annotate.tool); diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 70a289347591..1b96a3122228 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -691,7 +691,7 @@ static void hists__process(struct hists *hists) hists__precompute(hists); hists__output_resort(hists, NULL); - hists__fprintf(hists, true, 0, 0, 0, stdout, + hists__fprintf(hists, !quiet, 0, 0, 0, stdout, symbol_conf.use_callchain); } @@ -739,12 +739,14 @@ static void data_process(void) hists__link(hists_base, hists); } - fprintf(stdout, "%s# Event '%s'\n#\n", first ? "" : "\n", - perf_evsel__name(evsel_base)); + if (!quiet) { + fprintf(stdout, "%s# Event '%s'\n#\n", first ? "" : "\n", + perf_evsel__name(evsel_base)); + } first = false; - if (verbose || data__files_cnt > 2) + if (verbose > 0 || ((data__files_cnt > 2) && !quiet)) data__fprintf(); /* Don't sort callchain for perf diff */ @@ -807,6 +809,7 @@ static const char * const diff_usage[] = { static const struct option options[] = { OPT_INCR('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"), + OPT_BOOLEAN('q', "quiet", &quiet, "Do not show any message"), OPT_BOOLEAN('b', "baseline-only", &show_baseline_only, "Show only items with match in baseline"), OPT_CALLBACK('c', "compute", &compute, @@ -1328,6 +1331,9 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused) argc = parse_options(argc, argv, options, diff_usage, 0); + if (quiet) + perf_quiet_option(); + if (symbol__init(NULL) < 0) return -1; diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index cd7bc4d104e2..6114e07ca613 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c @@ -42,8 +42,8 @@ static int parse_record_events(const struct option *opt, fprintf(stderr, "%-13s%-*s%s\n", e->tag, - verbose ? 25 : 0, - verbose ? perf_mem_events__name(j) : "", + verbose > 0 ? 25 : 0, + verbose > 0 ? perf_mem_events__name(j) : "", e->supported ? ": available" : ""); } exit(0); diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 6cd6776052e7..bc84a375295d 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -432,7 +432,7 @@ static int record__open(struct record *rec) try_again: if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) { if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) { - if (verbose) + if (verbose > 0) ui__warning("%s\n", msg); goto try_again; } @@ -1677,8 +1677,12 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) argc = parse_options(argc, argv, record_options, record_usage, PARSE_OPT_STOP_AT_NON_OPTION); + if (quiet) + perf_quiet_option(); + + /* Make system wide (-a) the default target. */ if (!argc && target__none(&rec->opts.target)) - usage_with_options(record_usage, record_options); + rec->opts.target.system_wide = true; if (nr_cgroups && !rec->opts.target.system_wide) { usage_with_options_msg(record_usage, record_options, diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index dbd7fa028861..0a88670e56f3 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -320,6 +320,9 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report size_t size = sizeof(buf); int socked_id = hists->socket_filter; + if (quiet) + return 0; + if (symbol_conf.filter_relative) { nr_samples = hists->stats.nr_non_filtered_samples; nr_events = hists->stats.total_non_filtered_period; @@ -372,7 +375,11 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, { struct perf_evsel *pos; - fprintf(stdout, "#\n# Total Lost Samples: %" PRIu64 "\n#\n", evlist->stats.total_lost_samples); + if (!quiet) { + fprintf(stdout, "#\n# Total Lost Samples: %" PRIu64 "\n#\n", + evlist->stats.total_lost_samples); + } + evlist__for_each_entry(evlist, pos) { struct hists *hists = evsel__hists(pos); const char *evname = perf_evsel__name(pos); @@ -382,7 +389,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, continue; hists__fprintf_nr_sample_events(hists, rep, evname, stdout); - hists__fprintf(hists, true, 0, 0, rep->min_percent, stdout, + hists__fprintf(hists, !quiet, 0, 0, rep->min_percent, stdout, symbol_conf.use_callchain); fprintf(stdout, "\n\n"); } @@ -716,6 +723,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) "input file name"), OPT_INCR('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"), + OPT_BOOLEAN('q', "quiet", &quiet, "Do not show any message"), OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, "dump raw trace in ASCII"), OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, @@ -863,6 +871,9 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) report.symbol_filter_str = argv[0]; } + if (quiet) + perf_quiet_option(); + if (symbol_conf.vmlinux_name && access(symbol_conf.vmlinux_name, R_OK)) { pr_err("Invalid file: %s\n", symbol_conf.vmlinux_name); @@ -983,14 +994,14 @@ repeat: goto error; } - if (report.header || report.header_only) { + if ((report.header || report.header_only) && !quiet) { perf_session__fprintf_info(session, stdout, report.show_full_info); if (report.header_only) { ret = 0; goto error; } - } else if (use_browser == 0) { + } else if (use_browser == 0 && !quiet) { fputs("# To display the perf.data header info, please use --header/--header-only options.\n#\n", stdout); } @@ -1009,7 +1020,7 @@ repeat: * providing it only in verbose mode not to bloat too * much struct symbol. */ - if (verbose) { + if (verbose > 0) { /* * XXX: Need to provide a less kludgy way to ask for * more space per symbol, the u32 is for the index on diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 270eb2d8ca6b..b94cf0de715a 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -460,7 +460,7 @@ static struct task_desc *register_pid(struct perf_sched *sched, BUG_ON(!sched->tasks); sched->tasks[task->nr] = task; - if (verbose) + if (verbose > 0) printf("registered task #%ld, PID %ld (%s)\n", sched->nr_tasks, pid, comm); return task; @@ -794,7 +794,7 @@ replay_wakeup_event(struct perf_sched *sched, const u32 pid = perf_evsel__intval(evsel, sample, "pid"); struct task_desc *waker, *wakee; - if (verbose) { + if (verbose > 0) { printf("sched_wakeup event %p\n", evsel); printf(" ... pid %d woke up %s/%d\n", sample->tid, comm, pid); @@ -822,7 +822,7 @@ static int replay_switch_event(struct perf_sched *sched, int cpu = sample->cpu; s64 delta; - if (verbose) + if (verbose > 0) printf("sched_switch event %p\n", evsel); if (cpu >= MAX_CPUS || cpu < 0) @@ -870,7 +870,7 @@ static int replay_fork_event(struct perf_sched *sched, goto out_put; } - if (verbose) { + if (verbose > 0) { printf("fork event\n"); printf("... parent: %s/%d\n", thread__comm_str(parent), parent->tid); printf("... child: %s/%d\n", thread__comm_str(child), child->tid); @@ -1573,7 +1573,7 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel, timestamp__scnprintf_usec(timestamp, stimestamp, sizeof(stimestamp)); color_fprintf(stdout, color, " %12s secs ", stimestamp); - if (new_shortname || (verbose && sched_in->tid)) { + if (new_shortname || (verbose > 0 && sched_in->tid)) { const char *pid_color = color; if (thread__has_color(sched_in)) @@ -2050,7 +2050,7 @@ static void save_task_callchain(struct perf_sched *sched, if (thread__resolve_callchain(thread, cursor, evsel, sample, NULL, NULL, sched->max_stack + 2) != 0) { - if (verbose) + if (verbose > 0) error("Failed to resolve callchain. Skipping\n"); return; diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index f28719178b51..13b54999ad79 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -573,7 +573,7 @@ try_again: if (errno == EINVAL || errno == ENOSYS || errno == ENOENT || errno == EOPNOTSUPP || errno == ENXIO) { - if (verbose) + if (verbose > 0) ui__warning("%s event is not supported by the kernel.\n", perf_evsel__name(counter)); counter->supported = false; @@ -582,7 +582,7 @@ try_again: !(counter->leader->nr_members > 1)) continue; } else if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) { - if (verbose) + if (verbose > 0) ui__warning("%s\n", msg); goto try_again; } @@ -1765,7 +1765,7 @@ static inline int perf_env__get_cpu(struct perf_env *env, struct cpu_map *map, i cpu = map->map[idx]; - if (cpu >= env->nr_cpus_online) + if (cpu >= env->nr_cpus_avail) return -1; return cpu; @@ -2445,8 +2445,9 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) } else if (big_num_opt == 0) /* User passed --no-big-num */ big_num = false; + /* Make system wide (-a) the default target. */ if (!argc && target__none(&target)) - usage_with_options(stat_usage, stat_options); + target.system_wide = true; if (run_count < 0) { pr_err("Run count must be a positive number\n"); @@ -2538,7 +2539,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) status = 0; for (run_idx = 0; forever || run_idx < run_count; run_idx++) { - if (run_count != 1 && verbose) + if (run_count != 1 && verbose > 0) fprintf(output, "[ perf stat: executing run #%d ... ]\n", run_idx + 1); diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 5a7fd7af3a6d..ab9077915763 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -871,7 +871,7 @@ try_again: if (perf_evsel__open(counter, top->evlist->cpus, top->evlist->threads) < 0) { if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) { - if (verbose) + if (verbose > 0) ui__warning("%s\n", msg); goto try_again; } diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 40ef9b293d1b..256f1fac6f7e 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1399,7 +1399,7 @@ static struct syscall *trace__syscall_info(struct trace *trace, return &trace->syscalls.table[id]; out_cant_read: - if (verbose) { + if (verbose > 0) { fprintf(trace->output, "Problems reading syscall %d", id); if (id <= trace->syscalls.max && trace->syscalls.table[id].name != NULL) fprintf(trace->output, "(%s)", trace->syscalls.table[id].name); @@ -1801,10 +1801,10 @@ static void print_location(FILE *f, struct perf_sample *sample, bool print_dso, bool print_sym) { - if ((verbose || print_dso) && al->map) + if ((verbose > 0 || print_dso) && al->map) fprintf(f, "%s@", al->map->dso->long_name); - if ((verbose || print_sym) && al->sym) + if ((verbose > 0 || print_sym) && al->sym) fprintf(f, "%s+0x%" PRIx64, al->sym->name, al->addr - al->sym->start); else if (al->map) diff --git a/tools/perf/pmu-events/json.c b/tools/perf/pmu-events/json.c index f67bbb0aa36e..0544398d6e2d 100644 --- a/tools/perf/pmu-events/json.c +++ b/tools/perf/pmu-events/json.c @@ -49,7 +49,7 @@ static char *mapfile(const char *fn, size_t *size) int err; int fd = open(fn, O_RDONLY); - if (fd < 0 && verbose && fn) { + if (fd < 0 && verbose > 0 && fn) { pr_err("Error opening events file '%s': %s\n", fn, strerror(errno)); } diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c index 28d1605b0338..88dc51f4c27b 100644 --- a/tools/perf/tests/attr.c +++ b/tools/perf/tests/attr.c @@ -144,7 +144,7 @@ static int run_dir(const char *d, const char *perf) int vcnt = min(verbose, (int) sizeof(v) - 1); char cmd[3*PATH_MAX]; - if (verbose) + if (verbose > 0) vcnt++; snprintf(cmd, 3*PATH_MAX, PYTHON " %s/attr.py -d %s/attr/ -p %s %.*s", diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 37e326bfd2dc..83c4669cbc5b 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -299,7 +299,7 @@ static int run_test(struct test *test, int subtest) if (!dont_fork) { pr_debug("test child forked, pid %d\n", getpid()); - if (!verbose) { + if (verbose <= 0) { int nullfd = open("/dev/null", O_WRONLY); if (nullfd >= 0) { diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index ff5bc6363a79..d1f693041324 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -599,7 +599,7 @@ static int do_test_code_reading(bool try_kcore) continue; } - if (verbose) { + if (verbose > 0) { char errbuf[512]; perf_evlist__strerror_open(evlist, errno, errbuf, sizeof(errbuf)); pr_debug("perf_evlist__open() failed!\n%s\n", errbuf); diff --git a/tools/perf/tests/fdarray.c b/tools/perf/tests/fdarray.c index a2b5ff9bf83d..bc5982f42dc3 100644 --- a/tools/perf/tests/fdarray.c +++ b/tools/perf/tests/fdarray.c @@ -19,7 +19,7 @@ static int fdarray__fprintf_prefix(struct fdarray *fda, const char *prefix, FILE { int printed = 0; - if (!verbose) + if (verbose <= 0) return 0; printed += fprintf(fp, "\n%s: ", prefix); diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c index d357dab72e68..482b5365e68d 100644 --- a/tools/perf/tests/llvm.c +++ b/tools/perf/tests/llvm.c @@ -76,7 +76,7 @@ test_llvm__fetch_bpf_obj(void **p_obj_buf, * Skip this test if user's .perfconfig doesn't set [llvm] section * and clang is not found in $PATH, and this is not perf test -v */ - if (!force && (verbose == 0 && + if (!force && (verbose <= 0 && !llvm_param.user_set_param && llvm__search_clang())) { pr_debug("No clang and no verbosive, skip this test\n"); diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index aa9276bfe3e9..1dc838014422 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -1808,7 +1808,7 @@ static void debug_warn(const char *warn, va_list params) { char msg[1024]; - if (!verbose) + if (verbose <= 0) return; vsnprintf(msg, sizeof(msg), warn, params); diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index 541da7a68f91..87893f3ba5f1 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -172,13 +172,13 @@ int test__PERF_RECORD(int subtest __maybe_unused) err = perf_evlist__parse_sample(evlist, event, &sample); if (err < 0) { - if (verbose) + if (verbose > 0) perf_event__fprintf(event, stderr); pr_debug("Couldn't parse sample\n"); goto out_delete_evlist; } - if (verbose) { + if (verbose > 0) { pr_info("%" PRIu64" %d ", sample.time, sample.cpu); perf_event__fprintf(event, stderr); } diff --git a/tools/perf/tests/python-use.c b/tools/perf/tests/python-use.c index 7a52834ee0d0..fa79509da535 100644 --- a/tools/perf/tests/python-use.c +++ b/tools/perf/tests/python-use.c @@ -15,7 +15,7 @@ int test__python_use(int subtest __maybe_unused) int ret; if (asprintf(&cmd, "echo \"import sys ; sys.path.append('%s'); import perf\" | %s %s", - PYTHONPATH, PYTHON, verbose ? "" : "2> /dev/null") < 0) + PYTHONPATH, PYTHON, verbose > 0 ? "" : "2> /dev/null") < 0) return -1; ret = system(cmd) ? -1 : 0; diff --git a/tools/perf/tests/thread-map.c b/tools/perf/tests/thread-map.c index a4a4b4625ac3..f2d2e542d0ee 100644 --- a/tools/perf/tests/thread-map.c +++ b/tools/perf/tests/thread-map.c @@ -109,7 +109,7 @@ int test__thread_map_remove(int subtest __maybe_unused) TEST_ASSERT_VAL("failed to allocate thread_map", threads); - if (verbose) + if (verbose > 0) thread_map__fprintf(threads, stderr); TEST_ASSERT_VAL("failed to remove thread", @@ -117,7 +117,7 @@ int test__thread_map_remove(int subtest __maybe_unused) TEST_ASSERT_VAL("thread_map count != 1", threads->nr == 1); - if (verbose) + if (verbose > 0) thread_map__fprintf(threads, stderr); TEST_ASSERT_VAL("failed to remove thread", @@ -125,7 +125,7 @@ int test__thread_map_remove(int subtest __maybe_unused) TEST_ASSERT_VAL("thread_map count != 0", threads->nr == 0); - if (verbose) + if (verbose > 0) thread_map__fprintf(threads, stderr); TEST_ASSERT_VAL("failed to not remove thread", diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c index 98fe69ac553c..803f893550d6 100644 --- a/tools/perf/tests/topology.c +++ b/tools/perf/tests/topology.c @@ -65,7 +65,9 @@ static int check_cpu_topology(char *path, struct cpu_map *map) session = perf_session__new(&file, false, NULL); TEST_ASSERT_VAL("can't get session", session); - for (i = 0; i < session->header.env.nr_cpus_online; i++) { + for (i = 0; i < session->header.env.nr_cpus_avail; i++) { + if (!cpu_map__has(map, i)) + continue; pr_debug("CPU %d, core %d, socket %d\n", i, session->header.env.cpu[i].core_id, session->header.env.cpu[i].socket_id); diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c index a5082331f246..862b043e5924 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -168,7 +168,7 @@ next_pair: err = -1; } - if (!verbose) + if (verbose <= 0) goto out; header_printed = false; diff --git a/tools/perf/ui/browsers/map.c b/tools/perf/ui/browsers/map.c index 98a34664bb7e..9ce142de536d 100644 --- a/tools/perf/ui/browsers/map.c +++ b/tools/perf/ui/browsers/map.c @@ -73,7 +73,7 @@ static int map_browser__run(struct map_browser *browser) if (ui_browser__show(&browser->b, browser->map->dso->long_name, "Press ESC to exit, %s / to search", - verbose ? "" : "restart with -v to use") < 0) + verbose > 0 ? "" : "restart with -v to use") < 0) return -1; while (1) { @@ -81,7 +81,7 @@ static int map_browser__run(struct map_browser *browser) switch (key) { case '/': - if (verbose) + if (verbose > 0) map_browser__search(browser); default: break; @@ -117,7 +117,7 @@ int map__browse(struct map *map) if (maxaddr < pos->end) maxaddr = pos->end; - if (verbose) { + if (verbose > 0) { u32 *idx = symbol__browser_index(pos); *idx = mb.b.nr_entries; } diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 18cfcdc90356..5d632dca672a 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -648,7 +648,7 @@ unsigned int hists__sort_list_width(struct hists *hists) ret += fmt->width(fmt, &dummy_hpp, hists); } - if (verbose && hists__has(hists, sym)) /* Addr + origin */ + if (verbose > 0 && hists__has(hists, sym)) /* Addr + origin */ ret += 3 + BITS_PER_LONG / 4; return ret; diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 06cc04e5806a..273f21fa32b5 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1768,7 +1768,7 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, printf("%-*.*s----\n", graph_dotted_len, graph_dotted_len, graph_dotted_line); - if (verbose) + if (verbose > 0) symbol__annotate_hits(sym, evsel); list_for_each_entry(pos, ¬es->src->source, node) { diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index 2c0b52264a46..8c7504939113 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c @@ -9,6 +9,7 @@ #include "asm/bug.h" static int max_cpu_num; +static int max_present_cpu_num; static int max_node_num; static int *cpunode_map; @@ -442,6 +443,7 @@ static void set_max_cpu_num(void) /* set up default */ max_cpu_num = 4096; + max_present_cpu_num = 4096; mnt = sysfs__mountpoint(); if (!mnt) @@ -455,6 +457,17 @@ static void set_max_cpu_num(void) } ret = get_max_num(path, &max_cpu_num); + if (ret) + goto out; + + /* get the highest present cpu number for a sparse allocation */ + ret = snprintf(path, PATH_MAX, "%s/devices/system/cpu/present", mnt); + if (ret == PATH_MAX) { + pr_err("sysfs path crossed PATH_MAX(%d) size\n", PATH_MAX); + goto out; + } + + ret = get_max_num(path, &max_present_cpu_num); out: if (ret) @@ -505,6 +518,15 @@ int cpu__max_cpu(void) return max_cpu_num; } +int cpu__max_present_cpu(void) +{ + if (unlikely(!max_present_cpu_num)) + set_max_cpu_num(); + + return max_present_cpu_num; +} + + int cpu__get_node(int cpu) { if (unlikely(cpunode_map == NULL)) { diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h index 06bd689f5989..1a0549af8f5c 100644 --- a/tools/perf/util/cpumap.h +++ b/tools/perf/util/cpumap.h @@ -62,6 +62,7 @@ int cpu__setup_cpunode_map(void); int cpu__max_node(void); int cpu__max_cpu(void); +int cpu__max_present_cpu(void); int cpu__get_node(int cpu); int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res, diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c index c1838b643108..03eb81f30d0d 100644 --- a/tools/perf/util/debug.c +++ b/tools/perf/util/debug.c @@ -203,11 +203,28 @@ int perf_debug_option(const char *str) v = (v < 0) || (v > 10) ? 0 : v; } + if (quiet) + v = -1; + *var->ptr = v; free(s); return 0; } +int perf_quiet_option(void) +{ + struct debug_variable *var = &debug_variables[0]; + + /* disable all debug messages */ + while (var->name) { + *var->ptr = -1; + var++; + } + + quiet = true; + return 0; +} + #define DEBUG_WRAPPER(__n, __l) \ static int pr_ ## __n ## _wrapper(const char *fmt, ...) \ { \ diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h index d242adc3d5a2..98832f5531d3 100644 --- a/tools/perf/util/debug.h +++ b/tools/perf/util/debug.h @@ -54,5 +54,6 @@ int veprintf(int level, int var, const char *fmt, va_list args); int perf_debug_option(const char *str); void perf_debug_setup(void); +int perf_quiet_option(void); #endif /* __PERF_DEBUG_H */ diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 3abe3373ce90..d38b62a700ca 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -1058,7 +1058,7 @@ int dso__name_len(const struct dso *dso) { if (!dso) return strlen("[unknown]"); - if (verbose) + if (verbose > 0) return dso->long_name_len; return dso->short_name_len; diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c index bb964e86b09d..075fc77286bf 100644 --- a/tools/perf/util/env.c +++ b/tools/perf/util/env.c @@ -66,7 +66,7 @@ int perf_env__read_cpu_topology_map(struct perf_env *env) return 0; if (env->nr_cpus_avail == 0) - env->nr_cpus_avail = sysconf(_SC_NPROCESSORS_CONF); + env->nr_cpus_avail = cpu__max_present_cpu(); nr_cpus = env->nr_cpus_avail; if (nr_cpus == -1) diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 3d12c16e5103..05714d548584 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -295,11 +295,7 @@ static int write_nrcpus(int fd, struct perf_header *h __maybe_unused, u32 nrc, nra; int ret; - nr = sysconf(_SC_NPROCESSORS_CONF); - if (nr < 0) - return -1; - - nrc = (u32)(nr & UINT_MAX); + nrc = cpu__max_present_cpu(); nr = sysconf(_SC_NPROCESSORS_ONLN); if (nr < 0) @@ -505,24 +501,29 @@ static void free_cpu_topo(struct cpu_topo *tp) static struct cpu_topo *build_cpu_topology(void) { - struct cpu_topo *tp; + struct cpu_topo *tp = NULL; void *addr; u32 nr, i; size_t sz; long ncpus; int ret = -1; + struct cpu_map *map; - ncpus = sysconf(_SC_NPROCESSORS_CONF); - if (ncpus < 0) + ncpus = cpu__max_present_cpu(); + + /* build online CPU map */ + map = cpu_map__new(NULL); + if (map == NULL) { + pr_debug("failed to get system cpumap\n"); return NULL; + } nr = (u32)(ncpus & UINT_MAX); sz = nr * sizeof(char *); - addr = calloc(1, sizeof(*tp) + 2 * sz); if (!addr) - return NULL; + goto out_free; tp = addr; tp->cpu_nr = nr; @@ -532,10 +533,16 @@ static struct cpu_topo *build_cpu_topology(void) tp->thread_siblings = addr; for (i = 0; i < nr; i++) { + if (!cpu_map__has(map, i)) + continue; + ret = build_cpu_topo(tp, i); if (ret < 0) break; } + +out_free: + cpu_map__put(map); if (ret) { free_cpu_topo(tp); tp = NULL; @@ -1126,7 +1133,7 @@ static void print_cpu_topology(struct perf_header *ph, int fd __maybe_unused, { int nr, i; char *str; - int cpu_nr = ph->env.nr_cpus_online; + int cpu_nr = ph->env.nr_cpus_avail; nr = ph->env.nr_sibling_cores; str = ph->env.sibling_cores; @@ -1781,7 +1788,7 @@ static int process_cpu_topology(struct perf_file_section *section, u32 nr, i; char *str; struct strbuf sb; - int cpu_nr = ph->env.nr_cpus_online; + int cpu_nr = ph->env.nr_cpus_avail; u64 size = 0; ph->env.cpu = calloc(cpu_nr, sizeof(*ph->env.cpu)); @@ -1862,7 +1869,7 @@ static int process_cpu_topology(struct perf_file_section *section, if (ph->needs_swap) nr = bswap_32(nr); - if (nr > (u32)cpu_nr) { + if (nr != (u32)-1 && nr > (u32)cpu_nr) { pr_debug("socket_id number is too big." "You may need to upgrade the perf tool.\n"); goto free_cpu; diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 32c6a939e4cc..eaf72a938fb4 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -69,7 +69,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) */ if (h->ms.sym) { symlen = h->ms.sym->namelen + 4; - if (verbose) + if (verbose > 0) symlen += BITS_PER_LONG / 4 + 2 + 3; hists__new_col_len(hists, HISTC_SYMBOL, symlen); } else { @@ -93,7 +93,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) if (h->branch_info) { if (h->branch_info->from.sym) { symlen = (int)h->branch_info->from.sym->namelen + 4; - if (verbose) + if (verbose > 0) symlen += BITS_PER_LONG / 4 + 2 + 3; hists__new_col_len(hists, HISTC_SYMBOL_FROM, symlen); @@ -107,7 +107,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) if (h->branch_info->to.sym) { symlen = (int)h->branch_info->to.sym->namelen + 4; - if (verbose) + if (verbose > 0) symlen += BITS_PER_LONG / 4 + 2 + 3; hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen); diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 281e44af31e2..67a8aebc67ab 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -2318,24 +2318,20 @@ int parse_events__is_hardcoded_term(struct parse_events_term *term) return term->type_term != PARSE_EVENTS__TERM_TYPE_USER; } -static int new_term(struct parse_events_term **_term, int type_val, - int type_term, char *config, - char *str, u64 num, int err_term, int err_val) +static int new_term(struct parse_events_term **_term, + struct parse_events_term *temp, + char *str, u64 num) { struct parse_events_term *term; - term = zalloc(sizeof(*term)); + term = malloc(sizeof(*term)); if (!term) return -ENOMEM; + *term = *temp; INIT_LIST_HEAD(&term->list); - term->type_val = type_val; - term->type_term = type_term; - term->config = config; - term->err_term = err_term; - term->err_val = err_val; - switch (type_val) { + switch (term->type_val) { case PARSE_EVENTS__TERM_TYPE_NUM: term->val.num = num; break; @@ -2353,15 +2349,22 @@ static int new_term(struct parse_events_term **_term, int type_val, int parse_events_term__num(struct parse_events_term **term, int type_term, char *config, u64 num, + bool no_value, void *loc_term_, void *loc_val_) { YYLTYPE *loc_term = loc_term_; YYLTYPE *loc_val = loc_val_; - return new_term(term, PARSE_EVENTS__TERM_TYPE_NUM, type_term, - config, NULL, num, - loc_term ? loc_term->first_column : 0, - loc_val ? loc_val->first_column : 0); + struct parse_events_term temp = { + .type_val = PARSE_EVENTS__TERM_TYPE_NUM, + .type_term = type_term, + .config = config, + .no_value = no_value, + .err_term = loc_term ? loc_term->first_column : 0, + .err_val = loc_val ? loc_val->first_column : 0, + }; + + return new_term(term, &temp, NULL, num); } int parse_events_term__str(struct parse_events_term **term, @@ -2371,37 +2374,45 @@ int parse_events_term__str(struct parse_events_term **term, YYLTYPE *loc_term = loc_term_; YYLTYPE *loc_val = loc_val_; - return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, type_term, - config, str, 0, - loc_term ? loc_term->first_column : 0, - loc_val ? loc_val->first_column : 0); + struct parse_events_term temp = { + .type_val = PARSE_EVENTS__TERM_TYPE_STR, + .type_term = type_term, + .config = config, + .err_term = loc_term ? loc_term->first_column : 0, + .err_val = loc_val ? loc_val->first_column : 0, + }; + + return new_term(term, &temp, str, 0); } int parse_events_term__sym_hw(struct parse_events_term **term, char *config, unsigned idx) { struct event_symbol *sym; + struct parse_events_term temp = { + .type_val = PARSE_EVENTS__TERM_TYPE_STR, + .type_term = PARSE_EVENTS__TERM_TYPE_USER, + .config = config ?: (char *) "event", + }; BUG_ON(idx >= PERF_COUNT_HW_MAX); sym = &event_symbols_hw[idx]; - if (config) - return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, - PARSE_EVENTS__TERM_TYPE_USER, config, - (char *) sym->symbol, 0, 0, 0); - else - return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, - PARSE_EVENTS__TERM_TYPE_USER, - (char *) "event", (char *) sym->symbol, - 0, 0, 0); + return new_term(term, &temp, (char *) sym->symbol, 0); } int parse_events_term__clone(struct parse_events_term **new, struct parse_events_term *term) { - return new_term(new, term->type_val, term->type_term, term->config, - term->val.str, term->val.num, - term->err_term, term->err_val); + struct parse_events_term temp = { + .type_val = term->type_val, + .type_term = term->type_term, + .config = term->config, + .err_term = term->err_term, + .err_val = term->err_val, + }; + + return new_term(new, &temp, term->val.str, term->val.num); } void parse_events_terms__purge(struct list_head *terms) diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index da246a3ddb69..1af6a267c21b 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -94,6 +94,7 @@ struct parse_events_term { int type_term; struct list_head list; bool used; + bool no_value; /* error string indexes for within parsed string */ int err_term; @@ -122,6 +123,7 @@ void parse_events__shrink_config_terms(void); int parse_events__is_hardcoded_term(struct parse_events_term *term); int parse_events_term__num(struct parse_events_term **term, int type_term, char *config, u64 num, + bool novalue, void *loc_term, void *loc_val); int parse_events_term__str(struct parse_events_term **term, int type_term, char *config, char *str, diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index a14b47ab3879..30f018ea1370 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y @@ -252,7 +252,7 @@ PE_KERNEL_PMU_EVENT sep_dc if (!strcasecmp(alias->name, $1)) { ALLOC_LIST(head); ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, - $1, 1, &@1, NULL)); + $1, 1, false, &@1, NULL)); list_add_tail(&term->list, head); if (!parse_events_add_pmu(data, list, @@ -282,7 +282,7 @@ PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc ALLOC_LIST(head); ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, - &pmu_name, 1, &@1, NULL)); + &pmu_name, 1, false, &@1, NULL)); list_add_tail(&term->list, head); ALLOC_LIST(list); @@ -548,7 +548,7 @@ PE_NAME '=' PE_VALUE struct parse_events_term *term; ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, - $1, $3, &@1, &@3)); + $1, $3, false, &@1, &@3)); $$ = term; } | @@ -566,7 +566,7 @@ PE_NAME struct parse_events_term *term; ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, - $1, 1, &@1, NULL)); + $1, 1, true, &@1, NULL)); $$ = term; } | @@ -591,7 +591,7 @@ PE_TERM '=' PE_VALUE { struct parse_events_term *term; - ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3, &@1, &@3)); + ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3, false, &@1, &@3)); $$ = term; } | @@ -599,7 +599,7 @@ PE_TERM { struct parse_events_term *term; - ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1, &@1, NULL)); + ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1, true, &@1, NULL)); $$ = term; } | @@ -620,7 +620,7 @@ PE_NAME array '=' PE_VALUE struct parse_events_term *term; ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, - $1, $4, &@1, &@4)); + $1, $4, false, &@1, &@4)); term->array = $2; $$ = term; } diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 49bfee0e3d9e..12f84dd2ac5d 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -745,7 +745,7 @@ static int pmu_resolve_param_term(struct parse_events_term *term, } } - if (verbose) + if (verbose > 0) printf("Required parameter '%s' not specified\n", term->config); return -1; @@ -803,7 +803,7 @@ static int pmu_config_term(struct list_head *formats, format = pmu_find_format(formats, term->config); if (!format) { - if (verbose) + if (verbose > 0) printf("Invalid event/parameter '%s'\n", term->config); if (err) { char *pmu_term = pmu_formats_string(formats); @@ -834,11 +834,20 @@ static int pmu_config_term(struct list_head *formats, * Either directly use a numeric term, or try to translate string terms * using event parameters. */ - if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) + if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) { + if (term->no_value && + bitmap_weight(format->bits, PERF_PMU_FORMAT_BITS) > 1) { + if (err) { + err->idx = term->err_val; + err->str = strdup("no value assigned for term"); + } + return -EINVAL; + } + val = term->val.num; - else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) { + } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) { if (strcmp(term->val.str, "?")) { - if (verbose) { + if (verbose > 0) { pr_info("Invalid sysfs entry %s=%s\n", term->config, term->val.str); } @@ -1223,7 +1232,7 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag, printf("%*s", 8, "["); wordwrap(aliases[j].desc, 8, columns, 0); printf("]\n"); - if (verbose) + if (verbose > 0) printf("%*s%s/%s/\n", 8, "", aliases[j].pmu, aliases[j].str); } else printf(" %-50s [Kernel PMU event]\n", aliases[j].name); diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 35f5b7b7715c..28fb62c32678 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -594,7 +594,7 @@ static int find_perf_probe_point_from_dwarf(struct probe_trace_point *tp, pr_debug("try to find information at %" PRIx64 " in %s\n", addr, tp->module ? : "kernel"); - dinfo = debuginfo_cache__open(tp->module, verbose == 0); + dinfo = debuginfo_cache__open(tp->module, verbose <= 0); if (dinfo) ret = debuginfo__find_probe_point(dinfo, (unsigned long)addr, pp); diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 581e0efd6356..783326cfbaa6 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -369,10 +369,10 @@ static PyObject *python_process_callchain(struct perf_sample *sample, if (node->map) { struct map *map = node->map; const char *dsoname = "[unknown]"; - if (map && map->dso && (map->dso->name || map->dso->long_name)) { + if (map && map->dso) { if (symbol_conf.show_kernel_path && map->dso->long_name) dsoname = map->dso->long_name; - else if (map->dso->name) + else dsoname = map->dso->name; } pydict_set_item_string_decref(pyelem, "dso", diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 4cdbc8f5f14d..1dd617d116b5 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -932,7 +932,7 @@ static void branch_stack__printf(struct perf_sample *sample) printf("..... %2"PRIu64": %016" PRIx64 " -> %016" PRIx64 " %hu cycles %s%s%s%s %x\n", i, e->from, e->to, - e->flags.cycles, + (unsigned short)e->flags.cycles, e->flags.mispred ? "M" : " ", e->flags.predicted ? "P" : " ", e->flags.abort ? "A" : " ", diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py index c8680984d2d6..af415febbc46 100644 --- a/tools/perf/util/setup.py +++ b/tools/perf/util/setup.py @@ -1,8 +1,15 @@ #!/usr/bin/python2 -from distutils.core import setup, Extension from os import getenv +cc = getenv("CC") +if cc == "clang": + from _sysconfigdata import build_time_vars + from re import sub + build_time_vars["CFLAGS"] = sub("-specs=[^ ]+", "", build_time_vars["CFLAGS"]) + +from distutils.core import setup, Extension + from distutils.command.build_ext import build_ext as _build_ext from distutils.command.install_lib import install_lib as _install_lib diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index df622f4e301e..0ff622288d24 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -151,7 +151,7 @@ static int64_t _sort__dso_cmp(struct map *map_l, struct map *map_r) if (!dso_l || !dso_r) return cmp_null(dso_r, dso_l); - if (verbose) { + if (verbose > 0) { dso_name_l = dso_l->long_name; dso_name_r = dso_r->long_name; } else { @@ -172,8 +172,8 @@ static int _hist_entry__dso_snprintf(struct map *map, char *bf, size_t size, unsigned int width) { if (map && map->dso) { - const char *dso_name = !verbose ? map->dso->short_name : - map->dso->long_name; + const char *dso_name = verbose > 0 ? map->dso->long_name : + map->dso->short_name; return repsep_snprintf(bf, size, "%-*.*s", width, width, dso_name); } @@ -261,7 +261,7 @@ static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym, { size_t ret = 0; - if (verbose) { + if (verbose > 0) { char o = map ? dso__symtab_origin(map->dso) : '!'; ret += repsep_snprintf(bf, size, "%-#*llx %c ", BITS_PER_LONG / 4 + 2, ip, o); diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 39345c2ddfc2..0d51334a9b46 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -344,7 +344,7 @@ int perf_stat_process_counter(struct perf_stat_config *config, for (i = 0; i < 3; i++) update_stats(&ps->res_stats[i], count[i]); - if (verbose) { + if (verbose > 0) { fprintf(config->output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n", perf_evsel__name(counter), count[0], count[1], count[2]); } diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index adbc6c02c3aa..4e59ddeb4eda 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -213,7 +213,7 @@ static bool want_demangle(bool is_kernel_sym) static char *demangle_sym(struct dso *dso, int kmodule, const char *elf_name) { - int demangle_flags = verbose ? (DMGL_PARAMS | DMGL_ANSI) : DMGL_NO_OPTS; + int demangle_flags = verbose > 0 ? (DMGL_PARAMS | DMGL_ANSI) : DMGL_NO_OPTS; char *demangled = NULL; /* |