perf/urgent fixes:

- Only print NMI watchdog hint in 'perf stat' when it is enabled (Andi Kleen)
 
 - Fix sys_mmap/sys_old_mmap shandling in s390 in 'perf trace' (Jiri Olsa)
 
 - Disable breakpoint signal tests in powerpc, that lacks the perf kernel
   glue to set breakpoint events and makes 'perf test' always fail (Jiri Olsa)
 
 - Fix 'perf annotate' for branch instruction with multiple operands (Kim Phillips)
 
 - Add missing powerpc triplet when disassembling with 'objdump' in 'perf
   annotate' (Kim Phillips)
 
 - Do not trow away partial unwound stacks when using libdw, making
   callchains produced with it similar to those produced when linked with
   the other DWARF unwind library supported in perf, libunwind (Milian Wolff)
 
 - Fixes to properly handle kernel modules when processing build-id meta
   events (Namhyung Kim)
 
 - Fix handling of compressed modules in the build-id cache (Namhyung Kim)
 
 - Fix 'perf annotate' failure when filename has special chars (Ravi Bangoria)
 
 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iQIcBAABCAAGBQJZNvv8AAoJENZQFvNTUqpAyvsP/01nEOO/fcIo3IDaTNFUxpHN
 olGvfk4C0Nxh0Nvus4Clf2z1i5GpWmAPBJ8EJkVzx3dHM7r1KBH2KITOzUf5ifok
 JY9h2mHkGT7wGXme0NqlElWNk3LyKbLYirWCdyZ1ZIRCW/XftcZLbWZn+KMxPbbS
 +PouuSUzlpCUvCd3KpmiMZMY5BmTRIF+xOVoChXFvrdqP4tZcBjPqPXTDlVl+/sp
 9DtBARXAGDssEElhcNJi1XfXXwh/tf8AqQNV67WtUJZUTDQEBqRE8ctY1fek4+qm
 0EzQvVirVlV/NFB3llgQ64XfY+ehhUVMtx+Zdqf3+1D8j+ovR0m9mjsXPKfzPwS8
 ml49zWP5slr33OEhGIkkLxS2DQIisFz0PJ8C/tZrCqQS+oDPjJNiLb2u3hISmwdS
 n6HfMbrxyfqRQ5rFNUeo9EyHERAEZJFOEt6sBUDVfHsNdKBObGjUjWR4fKf8Bn3G
 UKgDdpAmYoZgd2fwmsXP2GcfZu9FBFAGFyfZRNNbwb11a0Ozb8KAqxm0Y1ETwbnj
 XOeFZ+pE4anoBJ0BzQpD8nYXfZFT9GLVa+v8VbRxnuVTg/Ccmf6UgWFkUZc7gxmL
 gT94HpEnsbCAg+JI+Z2S5KhdcjYM9GPCBxE1HtjxaJFv5iSc8S4PnrzuTTOGG3/T
 g+Mp4KKEyazvDHM/tt0S
 =Oasi
 -----END PGP SIGNATURE-----

Merge tag 'perf-urgent-for-mingo-4.12-20170606' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent

Pull perf/urgent fixes from Arnaldo Carvalho de Melo:

 - Only print NMI watchdog hint in 'perf stat' when it is enabled (Andi Kleen)

 - Fix sys_mmap/sys_old_mmap shandling in s390 in 'perf trace' (Jiri Olsa)

 - Disable breakpoint signal tests in powerpc, that lacks the perf kernel
   glue to set breakpoint events and makes 'perf test' always fail (Jiri Olsa)

 - Fix 'perf annotate' for branch instruction with multiple operands (Kim Phillips)

 - Add missing powerpc triplet when disassembling with 'objdump' in 'perf
   annotate' (Kim Phillips)

 - Do not trow away partial unwound stacks when using libdw, making
   callchains produced with it similar to those produced when linked with
   the other DWARF unwind library supported in perf, libunwind (Milian Wolff)

 - Fixes to properly handle kernel modules when processing build-id meta
  events (Namhyung Kim)

 - Fix handling of compressed modules in the build-id cache (Namhyung Kim)

 - Fix 'perf annotate' failure when filename has special chars (Ravi Bangoria)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
Ingo Molnar 2017-06-07 17:50:19 +02:00
commit 3e411b0ee7
13 changed files with 103 additions and 22 deletions

View File

@ -26,6 +26,7 @@ const char *const arm64_triplets[] = {
const char *const powerpc_triplets[] = { const char *const powerpc_triplets[] = {
"powerpc-unknown-linux-gnu-", "powerpc-unknown-linux-gnu-",
"powerpc-linux-gnu-",
"powerpc64-unknown-linux-gnu-", "powerpc64-unknown-linux-gnu-",
"powerpc64-linux-gnu-", "powerpc64-linux-gnu-",
"powerpc64le-linux-gnu-", "powerpc64le-linux-gnu-",

View File

@ -1578,6 +1578,7 @@ static void print_header(int argc, const char **argv)
static void print_footer(void) static void print_footer(void)
{ {
FILE *output = stat_config.output; FILE *output = stat_config.output;
int n;
if (!null_run) if (!null_run)
fprintf(output, "\n"); fprintf(output, "\n");
@ -1590,7 +1591,9 @@ static void print_footer(void)
} }
fprintf(output, "\n\n"); fprintf(output, "\n\n");
if (print_free_counters_hint) if (print_free_counters_hint &&
sysctl__read_int("kernel/nmi_watchdog", &n) >= 0 &&
n > 0)
fprintf(output, fprintf(output,
"Some events weren't counted. Try disabling the NMI watchdog:\n" "Some events weren't counted. Try disabling the NMI watchdog:\n"
" echo 0 > /proc/sys/kernel/nmi_watchdog\n" " echo 0 > /proc/sys/kernel/nmi_watchdog\n"

View File

@ -681,6 +681,10 @@ static struct syscall_fmt {
{ .name = "mlockall", .errmsg = true, { .name = "mlockall", .errmsg = true,
.arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, }, .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
{ .name = "mmap", .hexret = true, { .name = "mmap", .hexret = true,
/* The standard mmap maps to old_mmap on s390x */
#if defined(__s390x__)
.alias = "old_mmap",
#endif
.arg_scnprintf = { [0] = SCA_HEX, /* addr */ .arg_scnprintf = { [0] = SCA_HEX, /* addr */
[2] = SCA_MMAP_PROT, /* prot */ [2] = SCA_MMAP_PROT, /* prot */
[3] = SCA_MMAP_FLAGS, /* flags */ }, }, [3] = SCA_MMAP_FLAGS, /* flags */ }, },

View File

@ -288,3 +288,17 @@ int test__bp_signal(int subtest __maybe_unused)
return count1 == 1 && overflows == 3 && count2 == 3 && overflows_2 == 3 && count3 == 2 ? return count1 == 1 && overflows == 3 && count2 == 3 && overflows_2 == 3 && count3 == 2 ?
TEST_OK : TEST_FAIL; TEST_OK : TEST_FAIL;
} }
bool test__bp_signal_is_supported(void)
{
/*
* The powerpc so far does not have support to even create
* instruction breakpoint using the perf event interface.
* Once it's there we can release this.
*/
#ifdef __powerpc__
return false;
#else
return true;
#endif
}

View File

@ -97,10 +97,12 @@ static struct test generic_tests[] = {
{ {
.desc = "Breakpoint overflow signal handler", .desc = "Breakpoint overflow signal handler",
.func = test__bp_signal, .func = test__bp_signal,
.is_supported = test__bp_signal_is_supported,
}, },
{ {
.desc = "Breakpoint overflow sampling", .desc = "Breakpoint overflow sampling",
.func = test__bp_signal_overflow, .func = test__bp_signal_overflow,
.is_supported = test__bp_signal_is_supported,
}, },
{ {
.desc = "Number of exit events of a simple workload", .desc = "Number of exit events of a simple workload",
@ -401,6 +403,11 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
if (!perf_test__matches(t, curr, argc, argv)) if (!perf_test__matches(t, curr, argc, argv))
continue; continue;
if (t->is_supported && !t->is_supported()) {
pr_debug("%2d: %-*s: Disabled\n", i, width, t->desc);
continue;
}
pr_info("%2d: %-*s:", i, width, t->desc); pr_info("%2d: %-*s:", i, width, t->desc);
if (intlist__find(skiplist, i)) { if (intlist__find(skiplist, i)) {

View File

@ -34,6 +34,7 @@ struct test {
int (*get_nr)(void); int (*get_nr)(void);
const char *(*get_desc)(int subtest); const char *(*get_desc)(int subtest);
} subtest; } subtest;
bool (*is_supported)(void);
}; };
/* Tests */ /* Tests */
@ -99,6 +100,8 @@ const char *test__clang_subtest_get_desc(int subtest);
int test__clang_subtest_get_nr(void); int test__clang_subtest_get_nr(void);
int test__unit_number__scnprint(int subtest); int test__unit_number__scnprint(int subtest);
bool test__bp_signal_is_supported(void);
#if defined(__arm__) || defined(__aarch64__) #if defined(__arm__) || defined(__aarch64__)
#ifdef HAVE_DWARF_UNWIND_SUPPORT #ifdef HAVE_DWARF_UNWIND_SUPPORT
struct thread; struct thread;

View File

@ -239,10 +239,20 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
const char *s = strchr(ops->raw, '+'); const char *s = strchr(ops->raw, '+');
const char *c = strchr(ops->raw, ','); const char *c = strchr(ops->raw, ',');
if (c++ != NULL) /*
* skip over possible up to 2 operands to get to address, e.g.:
* tbnz w0, #26, ffff0000083cd190 <security_file_permission+0xd0>
*/
if (c++ != NULL) {
ops->target.addr = strtoull(c, NULL, 16); ops->target.addr = strtoull(c, NULL, 16);
else if (!ops->target.addr) {
c = strchr(c, ',');
if (c++ != NULL)
ops->target.addr = strtoull(c, NULL, 16);
}
} else {
ops->target.addr = strtoull(ops->raw, NULL, 16); ops->target.addr = strtoull(ops->raw, NULL, 16);
}
if (s++ != NULL) { if (s++ != NULL) {
ops->target.offset = strtoull(s, NULL, 16); ops->target.offset = strtoull(s, NULL, 16);
@ -257,10 +267,27 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
static int jump__scnprintf(struct ins *ins, char *bf, size_t size, static int jump__scnprintf(struct ins *ins, char *bf, size_t size,
struct ins_operands *ops) struct ins_operands *ops)
{ {
const char *c = strchr(ops->raw, ',');
if (!ops->target.addr || ops->target.offset < 0) if (!ops->target.addr || ops->target.offset < 0)
return ins__raw_scnprintf(ins, bf, size, ops); return ins__raw_scnprintf(ins, bf, size, ops);
return scnprintf(bf, size, "%-6.6s %" PRIx64, ins->name, ops->target.offset); if (c != NULL) {
const char *c2 = strchr(c + 1, ',');
/* check for 3-op insn */
if (c2 != NULL)
c = c2;
c++;
/* mirror arch objdump's space-after-comma style */
if (*c == ' ')
c++;
}
return scnprintf(bf, size, "%-6.6s %.*s%" PRIx64,
ins->name, c ? c - ops->raw : 0, ops->raw,
ops->target.offset);
} }
static struct ins_ops jump_ops = { static struct ins_ops jump_ops = {
@ -1429,7 +1456,7 @@ int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_na
snprintf(command, sizeof(command), snprintf(command, sizeof(command),
"%s %s%s --start-address=0x%016" PRIx64 "%s %s%s --start-address=0x%016" PRIx64
" --stop-address=0x%016" PRIx64 " --stop-address=0x%016" PRIx64
" -l -d %s %s -C %s 2>/dev/null|grep -v %s:|expand", " -l -d %s %s -C \"%s\" 2>/dev/null|grep -v \"%s:\"|expand",
objdump_path ? objdump_path : "objdump", objdump_path ? objdump_path : "objdump",
disassembler_style ? "-M " : "", disassembler_style ? "-M " : "",
disassembler_style ? disassembler_style : "", disassembler_style ? disassembler_style : "",

View File

@ -335,6 +335,21 @@ int __kmod_path__parse(struct kmod_path *m, const char *path,
return 0; return 0;
} }
void dso__set_module_info(struct dso *dso, struct kmod_path *m,
struct machine *machine)
{
if (machine__is_host(machine))
dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE;
else
dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
/* _KMODULE_COMP should be next to _KMODULE */
if (m->kmod && m->comp)
dso->symtab_type++;
dso__set_short_name(dso, strdup(m->name), true);
}
/* /*
* Global list of open DSOs and the counter. * Global list of open DSOs and the counter.
*/ */

View File

@ -259,6 +259,9 @@ int __kmod_path__parse(struct kmod_path *m, const char *path,
#define kmod_path__parse_name(__m, __p) __kmod_path__parse(__m, __p, true , false) #define kmod_path__parse_name(__m, __p) __kmod_path__parse(__m, __p, true , false)
#define kmod_path__parse_ext(__m, __p) __kmod_path__parse(__m, __p, false, true) #define kmod_path__parse_ext(__m, __p) __kmod_path__parse(__m, __p, false, true)
void dso__set_module_info(struct dso *dso, struct kmod_path *m,
struct machine *machine);
/* /*
* The dso__data_* external interface provides following functions: * The dso__data_* external interface provides following functions:
* dso__data_get_fd * dso__data_get_fd

View File

@ -1469,8 +1469,16 @@ static int __event_process_build_id(struct build_id_event *bev,
dso__set_build_id(dso, &bev->build_id); dso__set_build_id(dso, &bev->build_id);
if (!is_kernel_module(filename, cpumode)) if (dso_type != DSO_TYPE_USER) {
dso->kernel = dso_type; struct kmod_path m = { .name = NULL, };
if (!kmod_path__parse_name(&m, filename) && m.kmod)
dso__set_module_info(dso, &m, machine);
else
dso->kernel = dso_type;
free(m.name);
}
build_id__sprintf(dso->build_id, sizeof(dso->build_id), build_id__sprintf(dso->build_id, sizeof(dso->build_id),
sbuild_id); sbuild_id);

View File

@ -572,16 +572,7 @@ static struct dso *machine__findnew_module_dso(struct machine *machine,
if (dso == NULL) if (dso == NULL)
goto out_unlock; goto out_unlock;
if (machine__is_host(machine)) dso__set_module_info(dso, m, machine);
dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE;
else
dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
/* _KMODULE_COMP should be next to _KMODULE */
if (m->kmod && m->comp)
dso->symtab_type++;
dso__set_short_name(dso, strdup(m->name), true);
dso__set_long_name(dso, strdup(filename), true); dso__set_long_name(dso, strdup(filename), true);
} }

View File

@ -649,10 +649,7 @@ static int decompress_kmodule(struct dso *dso, const char *name,
type != DSO_BINARY_TYPE__BUILD_ID_CACHE) type != DSO_BINARY_TYPE__BUILD_ID_CACHE)
return -1; return -1;
if (type == DSO_BINARY_TYPE__BUILD_ID_CACHE) if (kmod_path__parse_ext(&m, dso->long_name) || !m.comp)
name = dso->long_name;
if (kmod_path__parse_ext(&m, name) || !m.comp)
return -1; return -1;
fd = mkstemp(tmpbuf); fd = mkstemp(tmpbuf);

View File

@ -39,6 +39,14 @@ static int __report_module(struct addr_location *al, u64 ip,
return 0; return 0;
mod = dwfl_addrmodule(ui->dwfl, ip); mod = dwfl_addrmodule(ui->dwfl, ip);
if (mod) {
Dwarf_Addr s;
dwfl_module_info(mod, NULL, &s, NULL, NULL, NULL, NULL, NULL);
if (s != al->map->start)
mod = 0;
}
if (!mod) if (!mod)
mod = dwfl_report_elf(ui->dwfl, dso->short_name, mod = dwfl_report_elf(ui->dwfl, dso->short_name,
dso->long_name, -1, al->map->start, dso->long_name, -1, al->map->start,
@ -224,7 +232,7 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
err = dwfl_getthread_frames(ui->dwfl, thread->tid, frame_callback, ui); err = dwfl_getthread_frames(ui->dwfl, thread->tid, frame_callback, ui);
if (err && !ui->max_stack) if (err && ui->max_stack != max_stack)
err = 0; err = 0;
/* /*