Commit d8a450a8 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'perf-tools-fixes-for-v6.0-2022-09-08' of...

Merge tag 'perf-tools-fixes-for-v6.0-2022-09-08' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux

Pull perf tools fixes from Arnaldo Carvalho de Melo:

 - Fix per-thread mmaps for multi-threaded targets, noticed with
   'perf top --pid' with multithreaded targets

 - Fix synthesis failure warnings in 'perf record'

 - Fix L2 Topdown metrics disappearance for raw events in 'perf stat'

 - Fix out of bound access in some CPU masks

 - Fix segfault if there is no CPU PMU table and a metric is sought,
   noticed when building with NO_JEVENTS=1

 - Skip dummy event attr check in 'perf script' fixing nonsensical
   warning about UREGS attribute not set, as 'dummy' events have no
   samples

 - Fix 'iregs' field handling with dummy events on hybrid systems in
   'perf script'

 - Prevent potential memory leak in c2c_he_zalloc() in 'perf c2c'

 - Don't install data files with x permissions

 - Fix types for print format in dlfilter-show-cycles

 - Switch deprecated openssl MD5_* functions to new EVP API in 'genelf'

 - Remove redundant word 'contention' in 'perf lock' help message

* tag 'perf-tools-fixes-for-v6.0-2022-09-08' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux:
  perf record: Fix synthesis failure warnings
  perf tools: Don't install data files with x permissions
  perf script: Fix Cannot print 'iregs' field for hybrid systems
  perf lock: Remove redundant word 'contention' in help message
  perf dlfilter dlfilter-show-cycles: Fix types for print format
  libperf evlist: Fix per-thread mmaps for multi-threaded targets
  perf c2c: Prevent potential memory leak in c2c_he_zalloc()
  perf genelf: Switch deprecated openssl MD5_* functions to new EVP API
  tools/perf: Fix out of bound access to cpu mask array
  perf affinity: Fix out of bound access to "sched_cpus" mask
  perf stat: Fix L2 Topdown metrics disappear for raw events
  perf script: Skip dummy event attr check
  perf metric: Return early if no CPU PMU table exists
parents 460a75a6 faf59ec8
Loading
Loading
Loading
Loading
+50 −0
Original line number Diff line number Diff line
@@ -486,6 +486,7 @@ mmap_per_evsel(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops,
			if (ops->idx)
				ops->idx(evlist, evsel, mp, idx);

			pr_debug("idx %d: mmapping fd %d\n", idx, *output);
			if (ops->mmap(map, mp, *output, evlist_cpu) < 0)
				return -1;

@@ -494,6 +495,7 @@ mmap_per_evsel(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops,
			if (!idx)
				perf_evlist__set_mmap_first(evlist, map, overwrite);
		} else {
			pr_debug("idx %d: set output fd %d -> %d\n", idx, fd, *output);
			if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, *output) != 0)
				return -1;

@@ -519,6 +521,48 @@ mmap_per_evsel(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops,
	return 0;
}

static int
mmap_per_thread(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops,
		struct perf_mmap_param *mp)
{
	int nr_threads = perf_thread_map__nr(evlist->threads);
	int nr_cpus    = perf_cpu_map__nr(evlist->all_cpus);
	int cpu, thread, idx = 0;
	int nr_mmaps = 0;

	pr_debug("%s: nr cpu values (may include -1) %d nr threads %d\n",
		 __func__, nr_cpus, nr_threads);

	/* per-thread mmaps */
	for (thread = 0; thread < nr_threads; thread++, idx++) {
		int output = -1;
		int output_overwrite = -1;

		if (mmap_per_evsel(evlist, ops, idx, mp, 0, thread, &output,
				   &output_overwrite, &nr_mmaps))
			goto out_unmap;
	}

	/* system-wide mmaps i.e. per-cpu */
	for (cpu = 1; cpu < nr_cpus; cpu++, idx++) {
		int output = -1;
		int output_overwrite = -1;

		if (mmap_per_evsel(evlist, ops, idx, mp, cpu, 0, &output,
				   &output_overwrite, &nr_mmaps))
			goto out_unmap;
	}

	if (nr_mmaps != evlist->nr_mmaps)
		pr_err("Miscounted nr_mmaps %d vs %d\n", nr_mmaps, evlist->nr_mmaps);

	return 0;

out_unmap:
	perf_evlist__munmap(evlist);
	return -1;
}

static int
mmap_per_cpu(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops,
	     struct perf_mmap_param *mp)
@@ -528,6 +572,8 @@ mmap_per_cpu(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops,
	int nr_mmaps = 0;
	int cpu, thread;

	pr_debug("%s: nr cpu values %d nr threads %d\n", __func__, nr_cpus, nr_threads);

	for (cpu = 0; cpu < nr_cpus; cpu++) {
		int output = -1;
		int output_overwrite = -1;
@@ -569,6 +615,7 @@ int perf_evlist__mmap_ops(struct perf_evlist *evlist,
			  struct perf_evlist_mmap_ops *ops,
			  struct perf_mmap_param *mp)
{
	const struct perf_cpu_map *cpus = evlist->all_cpus;
	struct perf_evsel *evsel;

	if (!ops || !ops->get || !ops->mmap)
@@ -588,6 +635,9 @@ int perf_evlist__mmap_ops(struct perf_evlist *evlist,
	if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0)
		return -ENOMEM;

	if (perf_cpu_map__empty(cpus))
		return mmap_per_thread(evlist, ops, mp);

	return mmap_per_cpu(evlist, ops, mp);
}

+12 −12
Original line number Diff line number Diff line
@@ -954,11 +954,11 @@ ifndef NO_LIBBPF
	$(call QUIET_INSTALL, bpf-headers) \
		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf'; \
		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf/linux'; \
		$(INSTALL) include/bpf/*.h -t '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf'; \
		$(INSTALL) include/bpf/linux/*.h -t '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf/linux'
		$(INSTALL) include/bpf/*.h -m 644 -t '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf'; \
		$(INSTALL) include/bpf/linux/*.h -m 644 -t '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf/linux'
	$(call QUIET_INSTALL, bpf-examples) \
		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf'; \
		$(INSTALL) examples/bpf/*.c -t '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf'
		$(INSTALL) examples/bpf/*.c -m 644 -t '$(DESTDIR_SQ)$(perf_examples_instdir_SQ)/bpf'
endif
	$(call QUIET_INSTALL, perf-archive) \
		$(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
@@ -967,13 +967,13 @@ endif
ifndef NO_LIBAUDIT
	$(call QUIET_INSTALL, strace/groups) \
		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(STRACE_GROUPS_INSTDIR_SQ)'; \
		$(INSTALL) trace/strace/groups/* -t '$(DESTDIR_SQ)$(STRACE_GROUPS_INSTDIR_SQ)'
		$(INSTALL) trace/strace/groups/* -m 644 -t '$(DESTDIR_SQ)$(STRACE_GROUPS_INSTDIR_SQ)'
endif
ifndef NO_LIBPERL
	$(call QUIET_INSTALL, perl-scripts) \
		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \
		$(INSTALL) scripts/perl/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \
		$(INSTALL) scripts/perl/*.pl -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl'; \
		$(INSTALL) scripts/perl/Perf-Trace-Util/lib/Perf/Trace/* -m 644 -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \
		$(INSTALL) scripts/perl/*.pl -m 644 -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl'; \
		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'; \
		$(INSTALL) scripts/perl/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'
endif
@@ -990,23 +990,23 @@ endif
		$(INSTALL) $(DLFILTERS) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/dlfilters';
	$(call QUIET_INSTALL, perf_completion-script) \
		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d'; \
		$(INSTALL) perf-completion.sh '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d/perf'
		$(INSTALL) perf-completion.sh -m 644 '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d/perf'
	$(call QUIET_INSTALL, perf-tip) \
		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(tip_instdir_SQ)'; \
		$(INSTALL) Documentation/tips.txt -t '$(DESTDIR_SQ)$(tip_instdir_SQ)'
		$(INSTALL) Documentation/tips.txt -m 644 -t '$(DESTDIR_SQ)$(tip_instdir_SQ)'

install-tests: all install-gtk
	$(call QUIET_INSTALL, tests) \
		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \
		$(INSTALL) tests/attr.py '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \
		$(INSTALL) tests/attr.py -m 644 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \
		$(INSTALL) tests/pe-file.exe* '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \
		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \
		$(INSTALL) tests/attr/* '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \
		$(INSTALL) tests/attr/* -m 644 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \
		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \
		$(INSTALL) tests/shell/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \
		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \
		$(INSTALL) tests/shell/lib/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \
		$(INSTALL) tests/shell/lib/*.py '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'
		$(INSTALL) tests/shell/lib/*.sh -m 644 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \
		$(INSTALL) tests/shell/lib/*.py -m 644 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'

install-bin: install-tools install-tests install-traceevent-plugins

+9 −3
Original line number Diff line number Diff line
@@ -146,15 +146,15 @@ static void *c2c_he_zalloc(size_t size)

	c2c_he->cpuset = bitmap_zalloc(c2c.cpus_cnt);
	if (!c2c_he->cpuset)
		return NULL;
		goto out_free;

	c2c_he->nodeset = bitmap_zalloc(c2c.nodes_cnt);
	if (!c2c_he->nodeset)
		return NULL;
		goto out_free;

	c2c_he->node_stats = zalloc(c2c.nodes_cnt * sizeof(*c2c_he->node_stats));
	if (!c2c_he->node_stats)
		return NULL;
		goto out_free;

	init_stats(&c2c_he->cstats.lcl_hitm);
	init_stats(&c2c_he->cstats.rmt_hitm);
@@ -163,6 +163,12 @@ static void *c2c_he_zalloc(size_t size)
	init_stats(&c2c_he->cstats.load);

	return &c2c_he->he;

out_free:
	free(c2c_he->nodeset);
	free(c2c_he->cpuset);
	free(c2c_he);
	return NULL;
}

static void c2c_he_free(void *he)
+1 −2
Original line number Diff line number Diff line
@@ -1874,8 +1874,7 @@ int cmd_lock(int argc, const char **argv)
		NULL
	};
	const char *const lock_subcommands[] = { "record", "report", "script",
						 "info", "contention",
						 "contention", NULL };
						 "info", "contention", NULL };
	const char *lock_usage[] = {
		NULL,
		NULL
+26 −8
Original line number Diff line number Diff line
@@ -1906,14 +1906,18 @@ static int record__synthesize(struct record *rec, bool tail)

	err = perf_event__synthesize_bpf_events(session, process_synthesized_event,
						machine, opts);
	if (err < 0)
	if (err < 0) {
		pr_warning("Couldn't synthesize bpf events.\n");
		err = 0;
	}

	if (rec->opts.synth & PERF_SYNTH_CGROUP) {
		err = perf_event__synthesize_cgroups(tool, process_synthesized_event,
						     machine);
		if (err < 0)
		if (err < 0) {
			pr_warning("Couldn't synthesize cgroup events.\n");
			err = 0;
		}
	}

	if (rec->opts.nr_threads_synthesize > 1) {
@@ -3358,18 +3362,24 @@ static struct option __record_options[] = {

struct option *record_options = __record_options;

static void record__mmap_cpu_mask_init(struct mmap_cpu_mask *mask, struct perf_cpu_map *cpus)
static int record__mmap_cpu_mask_init(struct mmap_cpu_mask *mask, struct perf_cpu_map *cpus)
{
	struct perf_cpu cpu;
	int idx;

	if (cpu_map__is_dummy(cpus))
		return;
		return 0;

	perf_cpu_map__for_each_cpu(cpu, idx, cpus)
	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
		/* Return ENODEV is input cpu is greater than max cpu */
		if ((unsigned long)cpu.cpu > mask->nbits)
			return -ENODEV;
		set_bit(cpu.cpu, mask->bits);
	}

	return 0;
}

static int record__mmap_cpu_mask_init_spec(struct mmap_cpu_mask *mask, const char *mask_spec)
{
	struct perf_cpu_map *cpus;
@@ -3379,7 +3389,9 @@ static int record__mmap_cpu_mask_init_spec(struct mmap_cpu_mask *mask, const cha
		return -ENOMEM;

	bitmap_zero(mask->bits, mask->nbits);
	record__mmap_cpu_mask_init(mask, cpus);
	if (record__mmap_cpu_mask_init(mask, cpus))
		return -ENODEV;

	perf_cpu_map__put(cpus);

	return 0;
@@ -3461,7 +3473,12 @@ static int record__init_thread_masks_spec(struct record *rec, struct perf_cpu_ma
		pr_err("Failed to allocate CPUs mask\n");
		return ret;
	}
	record__mmap_cpu_mask_init(&cpus_mask, cpus);

	ret = record__mmap_cpu_mask_init(&cpus_mask, cpus);
	if (ret) {
		pr_err("Failed to init cpu mask\n");
		goto out_free_cpu_mask;
	}

	ret = record__thread_mask_alloc(&full_mask, cpu__max_cpu().cpu);
	if (ret) {
@@ -3702,7 +3719,8 @@ static int record__init_thread_default_masks(struct record *rec, struct perf_cpu
	if (ret)
		return ret;

	record__mmap_cpu_mask_init(&rec->thread_masks->maps, cpus);
	if (record__mmap_cpu_mask_init(&rec->thread_masks->maps, cpus))
		return -ENODEV;

	rec->nr_threads = 1;

Loading