Skip to content

Commit 408cf67

Browse files
author
Ingo Molnar
committed
Merge tag 'perf-core-for-mingo-20160520' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: User visible changes: - We should not use the current value of the kernel.perf_event_max_stack as the default value for --max-stack in tools that can process perf.data files, they will only match if that sysctl wasn't changed from its default value at the time the perf.data file was recorded, fix it. This fixes a bug where a 'perf record -a --call-graph dwarf ; perf report' produces a glibc invalid free backtrace (Arnaldo Carvalho de Melo) - Provide a better warning when running 'perf trace' on a system where the kernel.kptr_restrict is set to 1, similar to the one produced by 'perf record', noticed on ubuntu 16.04 where this is the default kptr_restrict setting. (Arnaldo Carvalho de Melo) - Fix ordering of instructions in the annotation code, noticed when annotating ARM binaries, now that table is auto-ordered at first use, to avoid more such problems (Chris Ryder) - Set buildid dir under symfs when --symfs is provided (He Kuang) - Fix the 'exit_group()' syscall output in 'perf trace' (Arnaldo Carvalho de Melo) - Only auto set call-graph to "dwarf" in 'perf trace' when syscalls are being traced (Arnaldo Carvalho de Melo) Signed-off-by: Arnaldo Carvalho de Melo <[email protected]> Signed-off-by: Ingo Molnar <[email protected]>
2 parents 1ab9418 + a706670 commit 408cf67

19 files changed

+109
-61
lines changed

tools/perf/Documentation/perf-report.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ OPTIONS
248248
Note that when using the --itrace option the synthesized callchain size
249249
will override this value if the synthesized callchain size is bigger.
250250

251-
Default: /proc/sys/kernel/perf_event_max_stack when present, 127 otherwise.
251+
Default: 127
252252

253253
-G::
254254
--inverted::

tools/perf/Documentation/perf-script.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ include::itrace.txt[]
267267
Note that when using the --itrace option the synthesized callchain size
268268
will override this value if the synthesized callchain size is bigger.
269269

270-
Default: /proc/sys/kernel/perf_event_max_stack when present, 127 otherwise.
270+
Default: 127
271271

272272
--ns::
273273
Use 9 decimal places when displaying time (i.e. show the nanoseconds)

tools/perf/Documentation/perf-trace.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,8 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs.
143143
Implies '--call-graph dwarf' when --call-graph not present on the
144144
command line, on systems where DWARF unwinding was built in.
145145

146-
Default: /proc/sys/kernel/perf_event_max_stack when present, 127 otherwise.
146+
Default: /proc/sys/kernel/perf_event_max_stack when present for
147+
live sessions (without --input/-i), 127 otherwise.
147148

148149
--min-stack::
149150
Set the stack depth limit when parsing the callchain, anything

tools/perf/builtin-annotate.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,8 +324,9 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
324324
OPT_BOOLEAN(0, "skip-missing", &annotate.skip_missing,
325325
"Skip symbols that cannot be annotated"),
326326
OPT_STRING('C', "cpu", &annotate.cpu_list, "cpu", "list of cpus to profile"),
327-
OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
328-
"Look for files with symbols relative to this directory"),
327+
OPT_CALLBACK(0, "symfs", NULL, "directory",
328+
"Look for files with symbols relative to this directory",
329+
symbol__config_symfs),
329330
OPT_BOOLEAN(0, "source", &symbol_conf.annotate_src,
330331
"Interleave source code with assembly code (default)"),
331332
OPT_BOOLEAN(0, "asm-raw", &symbol_conf.annotate_asm_raw,

tools/perf/builtin-diff.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -812,8 +812,9 @@ static const struct option options[] = {
812812
OPT_STRING_NOEMPTY('t', "field-separator", &symbol_conf.field_sep, "separator",
813813
"separator for columns, no spaces will be added between "
814814
"columns '.' is reserved."),
815-
OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
816-
"Look for files with symbols relative to this directory"),
815+
OPT_CALLBACK(0, "symfs", NULL, "directory",
816+
"Look for files with symbols relative to this directory",
817+
symbol__config_symfs),
817818
OPT_UINTEGER('o', "order", &sort_compute, "Specify compute sorting."),
818819
OPT_CALLBACK(0, "percentage", NULL, "relative|absolute",
819820
"How to display percentage of filtered entries", parse_filter_percentage),

tools/perf/builtin-report.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
691691
.ordered_events = true,
692692
.ordering_requires_timestamps = true,
693693
},
694-
.max_stack = sysctl_perf_event_max_stack,
694+
.max_stack = PERF_MAX_STACK_DEPTH,
695695
.pretty_printing_style = "normal",
696696
.socket_filter = -1,
697697
};
@@ -770,8 +770,9 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
770770
"columns '.' is reserved."),
771771
OPT_BOOLEAN('U', "hide-unresolved", &symbol_conf.hide_unresolved,
772772
"Only display entries resolved to a symbol"),
773-
OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
774-
"Look for files with symbols relative to this directory"),
773+
OPT_CALLBACK(0, "symfs", NULL, "directory",
774+
"Look for files with symbols relative to this directory",
775+
symbol__config_symfs),
775776
OPT_STRING('C', "cpu", &report.cpu_list, "cpu",
776777
"list of cpus to profile"),
777778
OPT_BOOLEAN('I', "show-info", &report.show_full_info,

tools/perf/builtin-script.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2010,8 +2010,9 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
20102010
"file", "kallsyms pathname"),
20112011
OPT_BOOLEAN('G', "hide-call-graph", &no_callchain,
20122012
"When printing symbols do not display call chain"),
2013-
OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
2014-
"Look for files with symbols relative to this directory"),
2013+
OPT_CALLBACK(0, "symfs", NULL, "directory",
2014+
"Look for files with symbols relative to this directory",
2015+
symbol__config_symfs),
20152016
OPT_CALLBACK('F', "fields", NULL, "str",
20162017
"comma separated output fields prepend with 'type:'. "
20172018
"Valid types: hw,sw,trace,raw. "
@@ -2067,8 +2068,6 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
20672068
NULL
20682069
};
20692070

2070-
scripting_max_stack = sysctl_perf_event_max_stack;
2071-
20722071
setup_scripting();
20732072

20742073
argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage,

tools/perf/builtin-timechart.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1945,8 +1945,9 @@ int cmd_timechart(int argc, const char **argv,
19451945
OPT_CALLBACK('p', "process", NULL, "process",
19461946
"process selector. Pass a pid or process name.",
19471947
parse_process),
1948-
OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
1949-
"Look for files with symbols relative to this directory"),
1948+
OPT_CALLBACK(0, "symfs", NULL, "directory",
1949+
"Look for files with symbols relative to this directory",
1950+
symbol__config_symfs),
19501951
OPT_INTEGER('n', "proc-num", &tchart.proc_num,
19511952
"min. number of tasks to print"),
19521953
OPT_BOOLEAN('t', "topology", &tchart.topology,

tools/perf/builtin-top.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ static void perf_event__process_sample(struct perf_tool *tool,
732732
if (machine__resolve(machine, &al, sample) < 0)
733733
return;
734734

735-
if (!top->kptr_restrict_warned &&
735+
if (!machine->kptr_restrict_warned &&
736736
symbol_conf.kptr_restrict &&
737737
al.cpumode == PERF_RECORD_MISC_KERNEL) {
738738
ui__warning(
@@ -743,7 +743,7 @@ static void perf_event__process_sample(struct perf_tool *tool,
743743
" modules" : "");
744744
if (use_browser <= 0)
745745
sleep(5);
746-
top->kptr_restrict_warned = true;
746+
machine->kptr_restrict_warned = true;
747747
}
748748

749749
if (al.sym == NULL) {
@@ -759,7 +759,7 @@ static void perf_event__process_sample(struct perf_tool *tool,
759759
* --hide-kernel-symbols, even if the user specifies an
760760
* invalid --vmlinux ;-)
761761
*/
762-
if (!top->kptr_restrict_warned && !top->vmlinux_warned &&
762+
if (!machine->kptr_restrict_warned && !top->vmlinux_warned &&
763763
al.map == machine->vmlinux_maps[MAP__FUNCTION] &&
764764
RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) {
765765
if (symbol_conf.vmlinux_name) {

tools/perf/builtin-trace.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,6 +1160,24 @@ static int trace__tool_process(struct perf_tool *tool,
11601160
return trace__process_event(trace, machine, event, sample);
11611161
}
11621162

1163+
static char *trace__machine__resolve_kernel_addr(void *vmachine, unsigned long long *addrp, char **modp)
1164+
{
1165+
struct machine *machine = vmachine;
1166+
1167+
if (machine->kptr_restrict_warned)
1168+
return NULL;
1169+
1170+
if (symbol_conf.kptr_restrict) {
1171+
pr_warning("Kernel address maps (/proc/{kallsyms,modules}) are restricted.\n\n"
1172+
"Check /proc/sys/kernel/kptr_restrict.\n\n"
1173+
"Kernel samples will not be resolved.\n");
1174+
machine->kptr_restrict_warned = true;
1175+
return NULL;
1176+
}
1177+
1178+
return machine__resolve_kernel_addr(vmachine, addrp, modp);
1179+
}
1180+
11631181
static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
11641182
{
11651183
int err = symbol__init(NULL);
@@ -1171,7 +1189,7 @@ static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
11711189
if (trace->host == NULL)
11721190
return -ENOMEM;
11731191

1174-
if (trace_event__register_resolver(trace->host, machine__resolve_kernel_addr) < 0)
1192+
if (trace_event__register_resolver(trace->host, trace__machine__resolve_kernel_addr) < 0)
11751193
return -errno;
11761194

11771195
err = __machine__synthesize_threads(trace->host, &trace->tool, &trace->opts.target,
@@ -1534,7 +1552,7 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
15341552
if (sc->is_exit) {
15351553
if (!(trace->duration_filter || trace->summary_only || trace->min_stack)) {
15361554
trace__fprintf_entry_head(trace, thread, 1, sample->time, trace->output);
1537-
fprintf(trace->output, "%-70s\n", ttrace->entry_str);
1555+
fprintf(trace->output, "%-70s)\n", ttrace->entry_str);
15381556
}
15391557
} else {
15401558
ttrace->entry_pending = true;
@@ -2887,12 +2905,12 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
28872905
mmap_pages_user_set = false;
28882906

28892907
if (trace.max_stack == UINT_MAX) {
2890-
trace.max_stack = sysctl_perf_event_max_stack;
2908+
trace.max_stack = input_name ? PERF_MAX_STACK_DEPTH : sysctl_perf_event_max_stack;
28912909
max_stack_user_set = false;
28922910
}
28932911

28942912
#ifdef HAVE_DWARF_UNWIND_SUPPORT
2895-
if ((trace.min_stack || max_stack_user_set) && !callchain_param.enabled)
2913+
if ((trace.min_stack || max_stack_user_set) && !callchain_param.enabled && trace.trace_syscalls)
28962914
record_opts__parse_callchain(&trace.opts, &callchain_param, "dwarf", false);
28972915
#endif
28982916

tools/perf/util/annotate.c

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -354,9 +354,6 @@ static struct ins_ops nop_ops = {
354354
.scnprintf = nop__scnprintf,
355355
};
356356

357-
/*
358-
* Must be sorted by name!
359-
*/
360357
static struct ins instructions[] = {
361358
{ .name = "add", .ops = &mov_ops, },
362359
{ .name = "addl", .ops = &mov_ops, },
@@ -372,8 +369,8 @@ static struct ins instructions[] = {
372369
{ .name = "bgt", .ops = &jump_ops, },
373370
{ .name = "bhi", .ops = &jump_ops, },
374371
{ .name = "bl", .ops = &call_ops, },
375-
{ .name = "blt", .ops = &jump_ops, },
376372
{ .name = "bls", .ops = &jump_ops, },
373+
{ .name = "blt", .ops = &jump_ops, },
377374
{ .name = "blx", .ops = &call_ops, },
378375
{ .name = "bne", .ops = &jump_ops, },
379376
#endif
@@ -449,18 +446,39 @@ static struct ins instructions[] = {
449446
{ .name = "xbeginq", .ops = &jump_ops, },
450447
};
451448

452-
static int ins__cmp(const void *name, const void *insp)
449+
static int ins__key_cmp(const void *name, const void *insp)
453450
{
454451
const struct ins *ins = insp;
455452

456453
return strcmp(name, ins->name);
457454
}
458455

456+
static int ins__cmp(const void *a, const void *b)
457+
{
458+
const struct ins *ia = a;
459+
const struct ins *ib = b;
460+
461+
return strcmp(ia->name, ib->name);
462+
}
463+
464+
static void ins__sort(void)
465+
{
466+
const int nmemb = ARRAY_SIZE(instructions);
467+
468+
qsort(instructions, nmemb, sizeof(struct ins), ins__cmp);
469+
}
470+
459471
static struct ins *ins__find(const char *name)
460472
{
461473
const int nmemb = ARRAY_SIZE(instructions);
474+
static bool sorted;
475+
476+
if (!sorted) {
477+
ins__sort();
478+
sorted = true;
479+
}
462480

463-
return bsearch(name, instructions, nmemb, sizeof(struct ins), ins__cmp);
481+
return bsearch(name, instructions, nmemb, sizeof(struct ins), ins__key_cmp);
464482
}
465483

466484
int symbol__annotate_init(struct map *map __maybe_unused, struct symbol *sym)

tools/perf/util/db-export.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,8 +298,7 @@ static struct call_path *call_path_from_sample(struct db_export *dbe,
298298
*/
299299
callchain_param.order = ORDER_CALLER;
300300
err = thread__resolve_callchain(thread, &callchain_cursor, evsel,
301-
sample, NULL, NULL,
302-
sysctl_perf_event_max_stack);
301+
sample, NULL, NULL, PERF_MAX_STACK_DEPTH);
303302
if (err) {
304303
callchain_param.order = saved_order;
305304
return NULL;

tools/perf/util/dso.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,7 @@ int dso__read_binary_type_filename(const struct dso *dso,
6363
}
6464
break;
6565
case DSO_BINARY_TYPE__BUILD_ID_CACHE:
66-
/* skip the locally configured cache if a symfs is given */
67-
if (symbol_conf.symfs[0] ||
68-
(dso__build_id_filename(dso, filename, size) == NULL))
66+
if (dso__build_id_filename(dso, filename, size) == NULL)
6967
ret = -1;
7068
break;
7169

tools/perf/util/machine.c

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
4343

4444
machine->symbol_filter = NULL;
4545
machine->id_hdr_size = 0;
46+
machine->kptr_restrict_warned = false;
4647
machine->comm_exec = false;
4748
machine->kernel_start = 0;
4849

@@ -1135,10 +1136,10 @@ int machine__create_kernel_maps(struct machine *machine)
11351136
{
11361137
struct dso *kernel = machine__get_kernel(machine);
11371138
const char *name;
1138-
u64 addr = machine__get_running_kernel_start(machine, &name);
1139+
u64 addr;
11391140
int ret;
11401141

1141-
if (!addr || kernel == NULL)
1142+
if (kernel == NULL)
11421143
return -1;
11431144

11441145
ret = __machine__create_kernel_maps(machine, kernel);
@@ -1160,8 +1161,9 @@ int machine__create_kernel_maps(struct machine *machine)
11601161
*/
11611162
map_groups__fixup_end(&machine->kmaps);
11621163

1163-
if (maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, name,
1164-
addr)) {
1164+
addr = machine__get_running_kernel_start(machine, &name);
1165+
if (!addr) {
1166+
} else if (maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, name, addr)) {
11651167
machine__destroy_kernel_maps(machine);
11661168
return -1;
11671169
}
@@ -1769,11 +1771,6 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
17691771
*/
17701772
int mix_chain_nr = i + 1 + lbr_nr + 1;
17711773

1772-
if (mix_chain_nr > (int)sysctl_perf_event_max_stack + PERF_MAX_BRANCH_DEPTH) {
1773-
pr_warning("corrupted callchain. skipping...\n");
1774-
return 0;
1775-
}
1776-
17771774
for (j = 0; j < mix_chain_nr; j++) {
17781775
if (callchain_param.order == ORDER_CALLEE) {
17791776
if (j < i + 1)
@@ -1813,7 +1810,7 @@ static int thread__resolve_callchain_sample(struct thread *thread,
18131810
struct ip_callchain *chain = sample->callchain;
18141811
int chain_nr = chain->nr;
18151812
u8 cpumode = PERF_RECORD_MISC_USER;
1816-
int i, j, err, nr_entries, nr_contexts;
1813+
int i, j, err, nr_entries;
18171814
int skip_idx = -1;
18181815
int first_call = 0;
18191816

@@ -1828,8 +1825,7 @@ static int thread__resolve_callchain_sample(struct thread *thread,
18281825
* Based on DWARF debug information, some architectures skip
18291826
* a callchain entry saved by the kernel.
18301827
*/
1831-
if (chain_nr < sysctl_perf_event_max_stack)
1832-
skip_idx = arch_skip_callchain_idx(thread, chain);
1828+
skip_idx = arch_skip_callchain_idx(thread, chain);
18331829

18341830
/*
18351831
* Add branches to call stack for easier browsing. This gives
@@ -1889,7 +1885,7 @@ static int thread__resolve_callchain_sample(struct thread *thread,
18891885
}
18901886

18911887
check_calls:
1892-
for (i = first_call, nr_entries = 0, nr_contexts = 0;
1888+
for (i = first_call, nr_entries = 0;
18931889
i < chain_nr && nr_entries < max_stack; i++) {
18941890
u64 ip;
18951891

@@ -1904,13 +1900,8 @@ static int thread__resolve_callchain_sample(struct thread *thread,
19041900
#endif
19051901
ip = chain->ips[j];
19061902

1907-
if (ip >= PERF_CONTEXT_MAX) {
1908-
if (++nr_contexts > sysctl_perf_event_max_contexts_per_stack)
1909-
goto out_corrupted_callchain;
1910-
} else {
1911-
if (++nr_entries > sysctl_perf_event_max_stack)
1912-
goto out_corrupted_callchain;
1913-
}
1903+
if (ip < PERF_CONTEXT_MAX)
1904+
++nr_entries;
19141905

19151906
err = add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip);
19161907

@@ -1919,10 +1910,6 @@ static int thread__resolve_callchain_sample(struct thread *thread,
19191910
}
19201911

19211912
return 0;
1922-
1923-
out_corrupted_callchain:
1924-
pr_warning("corrupted callchain. skipping...\n");
1925-
return 0;
19261913
}
19271914

19281915
static int unwind_entry(struct unwind_entry *entry, void *arg)

tools/perf/util/machine.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ struct machine {
2828
pid_t pid;
2929
u16 id_hdr_size;
3030
bool comm_exec;
31+
bool kptr_restrict_warned;
3132
char *root_dir;
3233
struct rb_root threads;
3334
pthread_rwlock_t threads_lock;

tools/perf/util/scripting-engines/trace-event-perl.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,7 @@ static SV *perl_process_callchain(struct perf_sample *sample,
264264
goto exit;
265265

266266
if (thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
267-
sample, NULL, NULL,
268-
sysctl_perf_event_max_stack) != 0) {
267+
sample, NULL, NULL, scripting_max_stack) != 0) {
269268
pr_err("Failed to resolve callchain. Skipping\n");
270269
goto exit;
271270
}

0 commit comments

Comments
 (0)