Commit d8a450a8 authored by Linus Torvalds's avatar Linus Torvalds

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
......@@ -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);
}
......
......@@ -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
......
......@@ -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)
......
......@@ -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
......
......@@ -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,16 +3362,22 @@ 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)
......@@ -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;
......
......@@ -445,6 +445,9 @@ static int evsel__check_attr(struct evsel *evsel, struct perf_session *session)
struct perf_event_attr *attr = &evsel->core.attr;
bool allow_user_set;
if (evsel__is_dummy_event(evsel))
return 0;
if (perf_header__has_feat(&session->header, HEADER_STAT))
return 0;
......@@ -566,6 +569,8 @@ static struct evsel *find_first_output_type(struct evlist *evlist,
struct evsel *evsel;
evlist__for_each_entry(evlist, evsel) {
if (evsel__is_dummy_event(evsel))
continue;
if (output_type(evsel->core.attr.type) == (int)type)
return evsel;
}
......
......@@ -1932,6 +1932,9 @@ static int add_default_attributes(void)
free(str);
}
if (!stat_config.topdown_level)
stat_config.topdown_level = TOPDOWN_MAX_LEVEL;
if (!evsel_list->core.nr_entries) {
if (target__has_cpu(&target))
default_attrs0[0].config = PERF_COUNT_SW_CPU_CLOCK;
......@@ -1948,8 +1951,6 @@ static int add_default_attributes(void)
}
if (evlist__add_default_attrs(evsel_list, default_attrs1) < 0)
return -1;
stat_config.topdown_level = TOPDOWN_MAX_LEVEL;
/* Platform specific attrs */
if (evlist__add_default_attrs(evsel_list, default_null_attrs) < 0)
return -1;
......
......@@ -98,9 +98,9 @@ int filter_event_early(void *data, const struct perf_dlfilter_sample *sample, vo
static void print_vals(__u64 cycles, __u64 delta)
{
if (delta)
printf("%10llu %10llu ", cycles, delta);
printf("%10llu %10llu ", (unsigned long long)cycles, (unsigned long long)delta);
else
printf("%10llu %10s ", cycles, "");
printf("%10llu %10s ", (unsigned long long)cycles, "");
}
int filter_event(void *data, const struct perf_dlfilter_sample *sample, void *ctx)
......
......@@ -49,8 +49,14 @@ void affinity__set(struct affinity *a, int cpu)
{
int cpu_set_size = get_cpu_set_size();
if (cpu == -1)
/*
* Return:
* - if cpu is -1
* - restrict out of bound access to sched_cpus
*/
if (cpu == -1 || ((cpu >= (cpu_set_size * 8))))
return;
a->changed = true;
set_bit(cpu, a->sched_cpus);
/*
......
......@@ -30,10 +30,6 @@
#define BUILD_ID_URANDOM /* different uuid for each run */
// FIXME, remove this and fix the deprecation warnings before its removed and
// We'll break for good here...
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#ifdef HAVE_LIBCRYPTO_SUPPORT
#define BUILD_ID_MD5
......@@ -45,6 +41,7 @@
#endif
#ifdef BUILD_ID_MD5
#include <openssl/evp.h>
#include <openssl/md5.h>
#endif
#endif
......@@ -142,15 +139,20 @@ gen_build_id(struct buildid_note *note,
static void
gen_build_id(struct buildid_note *note, unsigned long load_addr, const void *code, size_t csize)
{
MD5_CTX context;
EVP_MD_CTX *mdctx;
if (sizeof(note->build_id) < 16)
errx(1, "build_id too small for MD5");
MD5_Init(&context);
MD5_Update(&context, &load_addr, sizeof(load_addr));
MD5_Update(&context, code, csize);
MD5_Final((unsigned char *)note->build_id, &context);
mdctx = EVP_MD_CTX_new();
if (!mdctx)
errx(2, "failed to create EVP_MD_CTX");
EVP_DigestInit_ex(mdctx, EVP_md5(), NULL);
EVP_DigestUpdate(mdctx, &load_addr, sizeof(load_addr));
EVP_DigestUpdate(mdctx, code, csize);
EVP_DigestFinal_ex(mdctx, (unsigned char *)note->build_id, NULL);
EVP_MD_CTX_free(mdctx);
}
#endif
......
......@@ -1655,6 +1655,9 @@ int metricgroup__parse_groups(const struct option *opt,
struct evlist *perf_evlist = *(struct evlist **)opt->value;
const struct pmu_events_table *table = pmu_events_table__find();
if (!table)
return -EINVAL;
return parse_groups(perf_evlist, str, metric_no_group,
metric_no_merge, NULL, metric_events, table);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment