Skip to content

Commit 3e411b0

Browse files
author
Ingo Molnar
committed
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 <[email protected]> Signed-off-by: Ingo Molnar <[email protected]>
2 parents ba7b238 + 2538b9e commit 3e411b0

File tree

13 files changed

+103
-22
lines changed

13 files changed

+103
-22
lines changed

tools/perf/arch/common.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const char *const arm64_triplets[] = {
2626

2727
const char *const powerpc_triplets[] = {
2828
"powerpc-unknown-linux-gnu-",
29+
"powerpc-linux-gnu-",
2930
"powerpc64-unknown-linux-gnu-",
3031
"powerpc64-linux-gnu-",
3132
"powerpc64le-linux-gnu-",

tools/perf/builtin-stat.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1578,6 +1578,7 @@ static void print_header(int argc, const char **argv)
15781578
static void print_footer(void)
15791579
{
15801580
FILE *output = stat_config.output;
1581+
int n;
15811582

15821583
if (!null_run)
15831584
fprintf(output, "\n");
@@ -1590,7 +1591,9 @@ static void print_footer(void)
15901591
}
15911592
fprintf(output, "\n\n");
15921593

1593-
if (print_free_counters_hint)
1594+
if (print_free_counters_hint &&
1595+
sysctl__read_int("kernel/nmi_watchdog", &n) >= 0 &&
1596+
n > 0)
15941597
fprintf(output,
15951598
"Some events weren't counted. Try disabling the NMI watchdog:\n"
15961599
" echo 0 > /proc/sys/kernel/nmi_watchdog\n"

tools/perf/builtin-trace.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,10 @@ static struct syscall_fmt {
681681
{ .name = "mlockall", .errmsg = true,
682682
.arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
683683
{ .name = "mmap", .hexret = true,
684+
/* The standard mmap maps to old_mmap on s390x */
685+
#if defined(__s390x__)
686+
.alias = "old_mmap",
687+
#endif
684688
.arg_scnprintf = { [0] = SCA_HEX, /* addr */
685689
[2] = SCA_MMAP_PROT, /* prot */
686690
[3] = SCA_MMAP_FLAGS, /* flags */ }, },

tools/perf/tests/bp_signal.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,3 +288,17 @@ int test__bp_signal(int subtest __maybe_unused)
288288
return count1 == 1 && overflows == 3 && count2 == 3 && overflows_2 == 3 && count3 == 2 ?
289289
TEST_OK : TEST_FAIL;
290290
}
291+
292+
bool test__bp_signal_is_supported(void)
293+
{
294+
/*
295+
* The powerpc so far does not have support to even create
296+
* instruction breakpoint using the perf event interface.
297+
* Once it's there we can release this.
298+
*/
299+
#ifdef __powerpc__
300+
return false;
301+
#else
302+
return true;
303+
#endif
304+
}

tools/perf/tests/builtin-test.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,12 @@ static struct test generic_tests[] = {
9797
{
9898
.desc = "Breakpoint overflow signal handler",
9999
.func = test__bp_signal,
100+
.is_supported = test__bp_signal_is_supported,
100101
},
101102
{
102103
.desc = "Breakpoint overflow sampling",
103104
.func = test__bp_signal_overflow,
105+
.is_supported = test__bp_signal_is_supported,
104106
},
105107
{
106108
.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)
401403
if (!perf_test__matches(t, curr, argc, argv))
402404
continue;
403405

406+
if (t->is_supported && !t->is_supported()) {
407+
pr_debug("%2d: %-*s: Disabled\n", i, width, t->desc);
408+
continue;
409+
}
410+
404411
pr_info("%2d: %-*s:", i, width, t->desc);
405412

406413
if (intlist__find(skiplist, i)) {

tools/perf/tests/tests.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ struct test {
3434
int (*get_nr)(void);
3535
const char *(*get_desc)(int subtest);
3636
} subtest;
37+
bool (*is_supported)(void);
3738
};
3839

3940
/* Tests */
@@ -99,6 +100,8 @@ const char *test__clang_subtest_get_desc(int subtest);
99100
int test__clang_subtest_get_nr(void);
100101
int test__unit_number__scnprint(int subtest);
101102

103+
bool test__bp_signal_is_supported(void);
104+
102105
#if defined(__arm__) || defined(__aarch64__)
103106
#ifdef HAVE_DWARF_UNWIND_SUPPORT
104107
struct thread;

tools/perf/util/annotate.c

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,10 +239,20 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
239239
const char *s = strchr(ops->raw, '+');
240240
const char *c = strchr(ops->raw, ',');
241241

242-
if (c++ != NULL)
242+
/*
243+
* skip over possible up to 2 operands to get to address, e.g.:
244+
* tbnz w0, #26, ffff0000083cd190 <security_file_permission+0xd0>
245+
*/
246+
if (c++ != NULL) {
243247
ops->target.addr = strtoull(c, NULL, 16);
244-
else
248+
if (!ops->target.addr) {
249+
c = strchr(c, ',');
250+
if (c++ != NULL)
251+
ops->target.addr = strtoull(c, NULL, 16);
252+
}
253+
} else {
245254
ops->target.addr = strtoull(ops->raw, NULL, 16);
255+
}
246256

247257
if (s++ != NULL) {
248258
ops->target.offset = strtoull(s, NULL, 16);
@@ -257,10 +267,27 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *op
257267
static int jump__scnprintf(struct ins *ins, char *bf, size_t size,
258268
struct ins_operands *ops)
259269
{
270+
const char *c = strchr(ops->raw, ',');
271+
260272
if (!ops->target.addr || ops->target.offset < 0)
261273
return ins__raw_scnprintf(ins, bf, size, ops);
262274

263-
return scnprintf(bf, size, "%-6.6s %" PRIx64, ins->name, ops->target.offset);
275+
if (c != NULL) {
276+
const char *c2 = strchr(c + 1, ',');
277+
278+
/* check for 3-op insn */
279+
if (c2 != NULL)
280+
c = c2;
281+
c++;
282+
283+
/* mirror arch objdump's space-after-comma style */
284+
if (*c == ' ')
285+
c++;
286+
}
287+
288+
return scnprintf(bf, size, "%-6.6s %.*s%" PRIx64,
289+
ins->name, c ? c - ops->raw : 0, ops->raw,
290+
ops->target.offset);
264291
}
265292

266293
static struct ins_ops jump_ops = {
@@ -1429,7 +1456,7 @@ int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_na
14291456
snprintf(command, sizeof(command),
14301457
"%s %s%s --start-address=0x%016" PRIx64
14311458
" --stop-address=0x%016" PRIx64
1432-
" -l -d %s %s -C %s 2>/dev/null|grep -v %s:|expand",
1459+
" -l -d %s %s -C \"%s\" 2>/dev/null|grep -v \"%s:\"|expand",
14331460
objdump_path ? objdump_path : "objdump",
14341461
disassembler_style ? "-M " : "",
14351462
disassembler_style ? disassembler_style : "",

tools/perf/util/dso.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,21 @@ int __kmod_path__parse(struct kmod_path *m, const char *path,
335335
return 0;
336336
}
337337

338+
void dso__set_module_info(struct dso *dso, struct kmod_path *m,
339+
struct machine *machine)
340+
{
341+
if (machine__is_host(machine))
342+
dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE;
343+
else
344+
dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
345+
346+
/* _KMODULE_COMP should be next to _KMODULE */
347+
if (m->kmod && m->comp)
348+
dso->symtab_type++;
349+
350+
dso__set_short_name(dso, strdup(m->name), true);
351+
}
352+
338353
/*
339354
* Global list of open DSOs and the counter.
340355
*/

tools/perf/util/dso.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,9 @@ int __kmod_path__parse(struct kmod_path *m, const char *path,
259259
#define kmod_path__parse_name(__m, __p) __kmod_path__parse(__m, __p, true , false)
260260
#define kmod_path__parse_ext(__m, __p) __kmod_path__parse(__m, __p, false, true)
261261

262+
void dso__set_module_info(struct dso *dso, struct kmod_path *m,
263+
struct machine *machine);
264+
262265
/*
263266
* The dso__data_* external interface provides following functions:
264267
* dso__data_get_fd

tools/perf/util/header.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1469,8 +1469,16 @@ static int __event_process_build_id(struct build_id_event *bev,
14691469

14701470
dso__set_build_id(dso, &bev->build_id);
14711471

1472-
if (!is_kernel_module(filename, cpumode))
1473-
dso->kernel = dso_type;
1472+
if (dso_type != DSO_TYPE_USER) {
1473+
struct kmod_path m = { .name = NULL, };
1474+
1475+
if (!kmod_path__parse_name(&m, filename) && m.kmod)
1476+
dso__set_module_info(dso, &m, machine);
1477+
else
1478+
dso->kernel = dso_type;
1479+
1480+
free(m.name);
1481+
}
14741482

14751483
build_id__sprintf(dso->build_id, sizeof(dso->build_id),
14761484
sbuild_id);

tools/perf/util/machine.c

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -572,16 +572,7 @@ static struct dso *machine__findnew_module_dso(struct machine *machine,
572572
if (dso == NULL)
573573
goto out_unlock;
574574

575-
if (machine__is_host(machine))
576-
dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE;
577-
else
578-
dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
579-
580-
/* _KMODULE_COMP should be next to _KMODULE */
581-
if (m->kmod && m->comp)
582-
dso->symtab_type++;
583-
584-
dso__set_short_name(dso, strdup(m->name), true);
575+
dso__set_module_info(dso, m, machine);
585576
dso__set_long_name(dso, strdup(filename), true);
586577
}
587578

tools/perf/util/symbol-elf.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -649,10 +649,7 @@ static int decompress_kmodule(struct dso *dso, const char *name,
649649
type != DSO_BINARY_TYPE__BUILD_ID_CACHE)
650650
return -1;
651651

652-
if (type == DSO_BINARY_TYPE__BUILD_ID_CACHE)
653-
name = dso->long_name;
654-
655-
if (kmod_path__parse_ext(&m, name) || !m.comp)
652+
if (kmod_path__parse_ext(&m, dso->long_name) || !m.comp)
656653
return -1;
657654

658655
fd = mkstemp(tmpbuf);

tools/perf/util/unwind-libdw.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ static int __report_module(struct addr_location *al, u64 ip,
3939
return 0;
4040

4141
mod = dwfl_addrmodule(ui->dwfl, ip);
42+
if (mod) {
43+
Dwarf_Addr s;
44+
45+
dwfl_module_info(mod, NULL, &s, NULL, NULL, NULL, NULL, NULL);
46+
if (s != al->map->start)
47+
mod = 0;
48+
}
49+
4250
if (!mod)
4351
mod = dwfl_report_elf(ui->dwfl, dso->short_name,
4452
dso->long_name, -1, al->map->start,
@@ -224,7 +232,7 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
224232

225233
err = dwfl_getthread_frames(ui->dwfl, thread->tid, frame_callback, ui);
226234

227-
if (err && !ui->max_stack)
235+
if (err && ui->max_stack != max_stack)
228236
err = 0;
229237

230238
/*

0 commit comments

Comments
 (0)