perf tools fixes for v5.13: 4th batch

- Fix NULL pointer dereference in 'perf probe' when handling
   DW_AT_const_value when looking for a variable, which is valid.
 
 - Fix for capability querying of perf_event_attr.cgroup support in older
   kernels.
 
 - Add missing cloning of evsel->use_config_name.
 
 - Honor event config name on --no-merge in 'perf stat'.
 
 - Fix some memory leaks found using ASAN.
 
 - Fix the perf entry for perf_event_attr setup with make LIBPFM4=1 on
   s390 z/VM.
 
 - Update MIPS UAPI perf_regs.h file.
 
 - Fix 'perf stat' BPF counter load return check.
 
 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYIAB0WIQR2GiIUctdOfX2qHhGyPKLppCJ+JwUCYLqEvgAKCRCyPKLppCJ+
 J8nOAPwNmtXNGu2a/aV23go751d6s69oiEjhA9tmJfKrVnLdOwEA5r9MviUjml1+
 li7TGcNo74dNaXgcuaZ9Oi854xEbvA4=
 =8qmn
 -----END PGP SIGNATURE-----

Merge tag 'perf-tools-fixes-for-v5.13-2021-06-04' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux

Pull perf tools fixes from Arnaldo Carvalho de Melo:

 - Fix NULL pointer dereference in 'perf probe' when handling
   DW_AT_const_value when looking for a variable, which is valid.

 - Fix for capability querying of perf_event_attr.cgroup support in
   older kernels.

 - Add missing cloning of evsel->use_config_name.

 - Honor event config name on --no-merge in 'perf stat'.

 - Fix some memory leaks found using ASAN.

 - Fix the perf entry for perf_event_attr setup with make LIBPFM4=1 on
   s390 z/VM.

 - Update MIPS UAPI perf_regs.h file.

 - Fix 'perf stat' BPF counter load return check.

* tag 'perf-tools-fixes-for-v5.13-2021-06-04' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux:
  perf env: Fix memory leak of bpf_prog_info_linear member
  perf symbol-elf: Fix memory leak by freeing sdt_note.args
  perf stat: Honor event config name on --no-merge
  perf evsel: Add missing cloning of evsel->use_config_name
  perf test: Test 17 fails with make LIBPFM4=1 on s390 z/VM
  perf stat: Fix error return code in bperf__load()
  perf record: Move probing cgroup sampling support
  perf probe: Fix NULL pointer dereference in convert_variable_location()
  perf tools: Copy uapi/asm/perf_regs.h from the kernel for MIPS
This commit is contained in:
Linus Torvalds 2021-06-04 18:15:33 -07:00
commit 2cb26c15a2
15 changed files with 80 additions and 13 deletions

View File

@ -0,0 +1,40 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _ASM_MIPS_PERF_REGS_H
#define _ASM_MIPS_PERF_REGS_H
enum perf_event_mips_regs {
PERF_REG_MIPS_PC,
PERF_REG_MIPS_R1,
PERF_REG_MIPS_R2,
PERF_REG_MIPS_R3,
PERF_REG_MIPS_R4,
PERF_REG_MIPS_R5,
PERF_REG_MIPS_R6,
PERF_REG_MIPS_R7,
PERF_REG_MIPS_R8,
PERF_REG_MIPS_R9,
PERF_REG_MIPS_R10,
PERF_REG_MIPS_R11,
PERF_REG_MIPS_R12,
PERF_REG_MIPS_R13,
PERF_REG_MIPS_R14,
PERF_REG_MIPS_R15,
PERF_REG_MIPS_R16,
PERF_REG_MIPS_R17,
PERF_REG_MIPS_R18,
PERF_REG_MIPS_R19,
PERF_REG_MIPS_R20,
PERF_REG_MIPS_R21,
PERF_REG_MIPS_R22,
PERF_REG_MIPS_R23,
PERF_REG_MIPS_R24,
PERF_REG_MIPS_R25,
PERF_REG_MIPS_R26,
PERF_REG_MIPS_R27,
PERF_REG_MIPS_R28,
PERF_REG_MIPS_R29,
PERF_REG_MIPS_R30,
PERF_REG_MIPS_R31,
PERF_REG_MIPS_MAX = PERF_REG_MIPS_R31 + 1,
};
#endif /* _ASM_MIPS_PERF_REGS_H */

View File

@ -90,7 +90,6 @@ endif
ifeq ($(ARCH),mips)
NO_PERF_REGS := 0
CFLAGS += -I$(OUTPUT)arch/mips/include/generated
CFLAGS += -I../../arch/mips/include/uapi -I../../arch/mips/include/generated/uapi
LIBUNWIND_LIBS = -lunwind -lunwind-mips
endif

View File

@ -2714,6 +2714,12 @@ int cmd_record(int argc, const char **argv)
rec->no_buildid = true;
}
if (rec->opts.record_cgroup && !perf_can_record_cgroup()) {
pr_err("Kernel has no cgroup sampling support.\n");
err = -EINVAL;
goto out_opts;
}
if (rec->opts.kcore)
rec->data.is_dir = true;

View File

@ -39,6 +39,7 @@ arch/x86/lib/x86-opcode-map.txt
arch/x86/tools/gen-insn-attr-x86.awk
arch/arm/include/uapi/asm/perf_regs.h
arch/arm64/include/uapi/asm/perf_regs.h
arch/mips/include/uapi/asm/perf_regs.h
arch/powerpc/include/uapi/asm/perf_regs.h
arch/s390/include/uapi/asm/perf_regs.h
arch/x86/include/uapi/asm/perf_regs.h

View File

@ -16,7 +16,7 @@ pinned=0
exclusive=0
exclude_user=0
exclude_kernel=0|1
exclude_hv=0
exclude_hv=0|1
exclude_idle=0
mmap=1
comm=1

View File

@ -521,9 +521,10 @@ static int bperf__load(struct evsel *evsel, struct target *target)
evsel->bperf_leader_link_fd = bpf_link_get_fd_by_id(entry.link_id);
if (evsel->bperf_leader_link_fd < 0 &&
bperf_reload_leader_program(evsel, attr_map_fd, &entry))
bperf_reload_leader_program(evsel, attr_map_fd, &entry)) {
err = -1;
goto out;
}
/*
* The bpf_link holds reference to the leader program, and the
* leader program holds reference to the maps. Therefore, if
@ -550,6 +551,7 @@ static int bperf__load(struct evsel *evsel, struct target *target)
/* Step 2: load the follower skeleton */
evsel->follower_skel = bperf_follower_bpf__open();
if (!evsel->follower_skel) {
err = -1;
pr_err("Failed to open follower skeleton\n");
goto out;
}

View File

@ -975,9 +975,13 @@ static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data)
if ((tag == DW_TAG_formal_parameter ||
tag == DW_TAG_variable) &&
die_compare_name(die_mem, fvp->name) &&
/* Does the DIE have location information or external instance? */
/*
* Does the DIE have location information or const value
* or external instance?
*/
(dwarf_attr(die_mem, DW_AT_external, &attr) ||
dwarf_attr(die_mem, DW_AT_location, &attr)))
dwarf_attr(die_mem, DW_AT_location, &attr) ||
dwarf_attr(die_mem, DW_AT_const_value, &attr)))
return DIE_FIND_CB_END;
if (dwarf_haspc(die_mem, fvp->addr))
return DIE_FIND_CB_CONTINUE;

View File

@ -144,6 +144,7 @@ static void perf_env__purge_bpf(struct perf_env *env)
node = rb_entry(next, struct bpf_prog_info_node, rb_node);
next = rb_next(&node->rb_node);
rb_erase(&node->rb_node, root);
free(node->info_linear);
free(node);
}

View File

@ -428,6 +428,7 @@ struct evsel *evsel__clone(struct evsel *orig)
evsel->auto_merge_stats = orig->auto_merge_stats;
evsel->collect_stat = orig->collect_stat;
evsel->weak_group = orig->weak_group;
evsel->use_config_name = orig->use_config_name;
if (evsel__copy_config_terms(evsel, orig) < 0)
goto out_err;

View File

@ -83,8 +83,10 @@ struct evsel {
bool collect_stat;
bool weak_group;
bool bpf_counter;
bool use_config_name;
int bpf_fd;
struct bpf_object *bpf_obj;
struct list_head config_terms;
};
/*
@ -116,10 +118,8 @@ struct evsel {
bool merged_stat;
bool reset_group;
bool errored;
bool use_config_name;
struct hashmap *per_pkg_mask;
struct evsel *leader;
struct list_head config_terms;
int err;
int cpu_iter;
struct {

View File

@ -103,6 +103,11 @@ static void perf_probe_build_id(struct evsel *evsel)
evsel->core.attr.build_id = 1;
}
static void perf_probe_cgroup(struct evsel *evsel)
{
evsel->core.attr.cgroup = 1;
}
bool perf_can_sample_identifier(void)
{
return perf_probe_api(perf_probe_sample_identifier);
@ -182,3 +187,8 @@ bool perf_can_record_build_id(void)
{
return perf_probe_api(perf_probe_build_id);
}
bool perf_can_record_cgroup(void)
{
return perf_probe_api(perf_probe_cgroup);
}

View File

@ -12,5 +12,6 @@ bool perf_can_record_switch_events(void);
bool perf_can_record_text_poke_events(void);
bool perf_can_sample_identifier(void);
bool perf_can_record_build_id(void);
bool perf_can_record_cgroup(void);
#endif // __PERF_API_PROBE_H

View File

@ -190,6 +190,9 @@ static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
immediate_value_is_supported()) {
Dwarf_Sword snum;
if (!tvar)
return 0;
dwarf_formsdata(&attr, &snum);
ret = asprintf(&tvar->value, "\\%ld", (long)snum);

View File

@ -541,7 +541,7 @@ static void uniquify_event_name(struct evsel *counter)
char *config;
int ret = 0;
if (counter->uniquified_name ||
if (counter->uniquified_name || counter->use_config_name ||
!counter->pmu_name || !strncmp(counter->name, counter->pmu_name,
strlen(counter->pmu_name)))
return;
@ -555,10 +555,8 @@ static void uniquify_event_name(struct evsel *counter)
}
} else {
if (perf_pmu__has_hybrid()) {
if (!counter->use_config_name) {
ret = asprintf(&new_name, "%s/%s/",
counter->pmu_name, counter->name);
}
ret = asprintf(&new_name, "%s/%s/",
counter->pmu_name, counter->name);
} else {
ret = asprintf(&new_name, "%s [%s]",
counter->name, counter->pmu_name);

View File

@ -2412,6 +2412,7 @@ int cleanup_sdt_note_list(struct list_head *sdt_notes)
list_for_each_entry_safe(pos, tmp, sdt_notes, note_list) {
list_del_init(&pos->note_list);
zfree(&pos->args);
zfree(&pos->name);
zfree(&pos->provider);
free(pos);