diff 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;  	/*  | 

