Skip to content

Commit

Permalink
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/acme/linux into perf/core

Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:

User visible changes:

 - Rename the "colors.code" ~/.perfconfig variable to "colors.jump_arrows",
   as it controls just the that UI element in the annotate browser (Taeung Song)

 - Avoid trying to read ELF symtabs from device files, noticed while doing
   memory profiling work (Jiri Olsa)

 - Improve context detection when offering options in the hists browser,
   i.e.  some options don't make sense when the browser is not working with
   a perf.data file ('perf top' mode), only in 'perf report' mode, like
   scripting (Namhyung Kim)

Infrastructure changes:

 - Elliminate duplication in the hists browser filter functions, getting the
   common part into a function that receives callbacks for filtering by
   DSO, thread, etc. (Namhyung Kim)

 - Fix misleadingly indented assignment, found using
   gcc6 -Wmisleading-indentation (Markus Trippelsdorf)

 - Handle LLVM relocation oddities in libbpf, introducing a 'perf test' that
   detects such problems and then fixing the problem, so that the test now
   passes (Wang Nan)

 - More improvements to the build infrastructure to allow reusing the
   feature detection facilities (Wang Nan)

 - Auto initialize the globals needed by cpu__max_{cpu,node}() routines
   (Arnaldo Carvalho de Melo)

Documentation changes:

 - Document the perf sysctls in Documentation/sysctl/kernel.txt (Ben Hutchings)

 - Document a bunch more ~/.perfconfig knobs (Taeung Song)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Ingo Molnar committed Feb 3, 2016
2 parents 34229b2 + 5ac7628 commit 402e8db
Show file tree
Hide file tree
Showing 31 changed files with 507 additions and 184 deletions.
13 changes: 13 additions & 0 deletions Documentation/sysctl/kernel.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ show up in /proc/sys/kernel:
- panic_on_stackoverflow
- panic_on_unrecovered_nmi
- panic_on_warn
- perf_cpu_time_max_percent
- perf_event_paranoid
- pid_max
- powersave-nap [ PPC only ]
- printk
Expand Down Expand Up @@ -639,6 +641,17 @@ allowed to execute.

==============================================================

perf_event_paranoid:

Controls use of the performance events system by unprivileged
users (without CAP_SYS_ADMIN). The default value is 1.

-1: Allow use of (almost) all events by all users
>=0: Disallow raw tracepoint access by users without CAP_IOC_LOCK
>=1: Disallow CPU event access by users without CAP_SYS_ADMIN
>=2: Disallow kernel profiling by users without CAP_SYS_ADMIN

==============================================================

pid_max:

Expand Down
21 changes: 20 additions & 1 deletion tools/build/Makefile.feature
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ endef
# the rule that uses them - an example for that is the 'bionic'
# feature check. ]
#
FEATURE_TESTS ?= \
FEATURE_TESTS_BASIC := \
backtrace \
dwarf \
fortify-source \
Expand Down Expand Up @@ -56,6 +56,25 @@ FEATURE_TESTS ?= \
get_cpuid \
bpf

# FEATURE_TESTS_BASIC + FEATURE_TESTS_EXTRA is the complete list
# of all feature tests
FEATURE_TESTS_EXTRA := \
bionic \
compile-32 \
compile-x32 \
cplus-demangle \
hello \
libbabeltrace \
liberty \
liberty-z \
libunwind-debug-frame

FEATURE_TESTS ?= $(FEATURE_TESTS_BASIC)

ifeq ($(FEATURE_TESTS),all)
FEATURE_TESTS := $(FEATURE_TESTS_BASIC) $(FEATURE_TESTS_EXTRA)
endif

FEATURE_DISPLAY ?= \
dwarf \
glibc \
Expand Down
34 changes: 22 additions & 12 deletions tools/lib/bpf/libbpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ struct bpf_object {
Elf_Data *data;
} *reloc;
int nr_reloc;
int maps_shndx;
} efile;
/*
* All loaded bpf_object is linked in a list, which is
Expand Down Expand Up @@ -350,6 +351,7 @@ static struct bpf_object *bpf_object__new(const char *path,
*/
obj->efile.obj_buf = obj_buf;
obj->efile.obj_buf_sz = obj_buf_sz;
obj->efile.maps_shndx = -1;

obj->loaded = false;

Expand Down Expand Up @@ -529,12 +531,12 @@ bpf_object__init_maps(struct bpf_object *obj, void *data,
}

static int
bpf_object__init_maps_name(struct bpf_object *obj, int maps_shndx)
bpf_object__init_maps_name(struct bpf_object *obj)
{
int i;
Elf_Data *symbols = obj->efile.symbols;

if (!symbols || maps_shndx < 0)
if (!symbols || obj->efile.maps_shndx < 0)
return -EINVAL;

for (i = 0; i < symbols->d_size / sizeof(GElf_Sym); i++) {
Expand All @@ -544,7 +546,7 @@ bpf_object__init_maps_name(struct bpf_object *obj, int maps_shndx)

if (!gelf_getsym(symbols, i, &sym))
continue;
if (sym.st_shndx != maps_shndx)
if (sym.st_shndx != obj->efile.maps_shndx)
continue;

map_name = elf_strptr(obj->efile.elf,
Expand Down Expand Up @@ -572,7 +574,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
Elf *elf = obj->efile.elf;
GElf_Ehdr *ep = &obj->efile.ehdr;
Elf_Scn *scn = NULL;
int idx = 0, err = 0, maps_shndx = -1;
int idx = 0, err = 0;

/* Elf is corrupted/truncated, avoid calling elf_strptr. */
if (!elf_rawdata(elf_getscn(elf, ep->e_shstrndx), NULL)) {
Expand Down Expand Up @@ -625,7 +627,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
else if (strcmp(name, "maps") == 0) {
err = bpf_object__init_maps(obj, data->d_buf,
data->d_size);
maps_shndx = idx;
obj->efile.maps_shndx = idx;
} else if (sh.sh_type == SHT_SYMTAB) {
if (obj->efile.symbols) {
pr_warning("bpf: multiple SYMTAB in %s\n",
Expand Down Expand Up @@ -674,8 +676,8 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
pr_warning("Corrupted ELF file: index of strtab invalid\n");
return LIBBPF_ERRNO__FORMAT;
}
if (maps_shndx >= 0)
err = bpf_object__init_maps_name(obj, maps_shndx);
if (obj->efile.maps_shndx >= 0)
err = bpf_object__init_maps_name(obj);
out:
return err;
}
Expand All @@ -697,7 +699,8 @@ bpf_object__find_prog_by_idx(struct bpf_object *obj, int idx)
static int
bpf_program__collect_reloc(struct bpf_program *prog,
size_t nr_maps, GElf_Shdr *shdr,
Elf_Data *data, Elf_Data *symbols)
Elf_Data *data, Elf_Data *symbols,
int maps_shndx)
{
int i, nrels;

Expand All @@ -724,9 +727,6 @@ bpf_program__collect_reloc(struct bpf_program *prog,
return -LIBBPF_ERRNO__FORMAT;
}

insn_idx = rel.r_offset / sizeof(struct bpf_insn);
pr_debug("relocation: insn_idx=%u\n", insn_idx);

if (!gelf_getsym(symbols,
GELF_R_SYM(rel.r_info),
&sym)) {
Expand All @@ -735,6 +735,15 @@ bpf_program__collect_reloc(struct bpf_program *prog,
return -LIBBPF_ERRNO__FORMAT;
}

if (sym.st_shndx != maps_shndx) {
pr_warning("Program '%s' contains non-map related relo data pointing to section %u\n",
prog->section_name, sym.st_shndx);
return -LIBBPF_ERRNO__RELOC;
}

insn_idx = rel.r_offset / sizeof(struct bpf_insn);
pr_debug("relocation: insn_idx=%u\n", insn_idx);

if (insns[insn_idx].code != (BPF_LD | BPF_IMM | BPF_DW)) {
pr_warning("bpf: relocation: invalid relo for insns[%d].code 0x%x\n",
insn_idx, insns[insn_idx].code);
Expand Down Expand Up @@ -863,7 +872,8 @@ static int bpf_object__collect_reloc(struct bpf_object *obj)

err = bpf_program__collect_reloc(prog, nr_maps,
shdr, data,
obj->efile.symbols);
obj->efile.symbols,
obj->efile.maps_shndx);
if (err)
return err;
}
Expand Down
200 changes: 199 additions & 1 deletion tools/perf/Documentation/perf-config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Given a $HOME/.perfconfig like this:
medium = green, default
normal = lightgray, default
selected = white, lightgray
code = blue, default
jump_arrows = blue, default
addr = magenta, default
root = white, blue

Expand Down Expand Up @@ -98,6 +98,204 @@ Given a $HOME/.perfconfig like this:
order = caller
sort-key = function

Variables
~~~~~~~~~

colors.*::
The variables for customizing the colors used in the output for the
'report', 'top' and 'annotate' in the TUI. They should specify the
foreground and background colors, separated by a comma, for example:

medium = green, lightgray

If you want to use the color configured for you terminal, just leave it
as 'default', for example:

medium = default, lightgray

Available colors:
red, yellow, green, cyan, gray, black, blue,
white, default, magenta, lightgray

colors.top::
'top' means a overhead percentage which is more than 5%.
And values of this variable specify percentage colors.
Basic key values are foreground-color 'red' and
background-color 'default'.
colors.medium::
'medium' means a overhead percentage which has more than 0.5%.
Default values are 'green' and 'default'.
colors.normal::
'normal' means the rest of overhead percentages
except 'top', 'medium', 'selected'.
Default values are 'lightgray' and 'default'.
colors.selected::
This selects the colors for the current entry in a list of entries
from sub-commands (top, report, annotate).
Default values are 'black' and 'lightgray'.
colors.jump_arrows::
Colors for jump arrows on assembly code listings
such as 'jns', 'jmp', 'jane', etc.
Default values are 'blue', 'default'.
colors.addr::
This selects colors for addresses from 'annotate'.
Default values are 'magenta', 'default'.
colors.root::
Colors for headers in the output of a sub-commands (top, report).
Default values are 'white', 'blue'.

tui.*, gtk.*::
Subcommands that can be configured here are 'top', 'report' and 'annotate'.
These values are booleans, for example:

[tui]
top = true

will make the TUI be the default for the 'top' subcommand. Those will be
available if the required libs were detected at tool build time.

buildid.*::
buildid.dir::
Each executable and shared library in modern distributions comes with a
content based identifier that, if available, will be inserted in a
'perf.data' file header to, at analysis time find what is needed to do
symbol resolution, code annotation, etc.

The recording tools also stores a hard link or copy in a per-user
directory, $HOME/.debug/, of binaries, shared libraries, /proc/kallsyms
and /proc/kcore files to be used at analysis time.

The buildid.dir variable can be used to either change this directory
cache location, or to disable it altogether. If you want to disable it,
set buildid.dir to /dev/null. The default is $HOME/.debug

annotate.*::
These options work only for TUI.
These are in control of addresses, jump function, source code
in lines of assembly code from a specific program.

annotate.hide_src_code::
If a program which is analyzed has source code,
this option lets 'annotate' print a list of assembly code with the source code.
For example, let's see a part of a program. There're four lines.
If this option is 'true', they can be printed
without source code from a program as below.

│ push %rbp
│ mov %rsp,%rbp
│ sub $0x10,%rsp
│ mov (%rdi),%rdx

But if this option is 'false', source code of the part
can be also printed as below. Default is 'false'.

│ struct rb_node *rb_next(const struct rb_node *node)
│ {
│ push %rbp
│ mov %rsp,%rbp
│ sub $0x10,%rsp
│ struct rb_node *parent;
│ if (RB_EMPTY_NODE(node))
│ mov (%rdi),%rdx
│ return n;

annotate.use_offset::
Basing on a first address of a loaded function, offset can be used.
Instead of using original addresses of assembly code,
addresses subtracted from a base address can be printed.
Let's illustrate an example.
If a base address is 0XFFFFFFFF81624d50 as below,

ffffffff81624d50 <load0>

an address on assembly code has a specific absolute address as below

ffffffff816250b8:│ mov 0x8(%r14),%rdi

but if use_offset is 'true', an address subtracted from a base address is printed.
Default is true. This option is only applied to TUI.

368:│ mov 0x8(%r14),%rdi

annotate.jump_arrows::
There can be jump instruction among assembly code.
Depending on a boolean value of jump_arrows,
arrows can be printed or not which represent
where do the instruction jump into as below.

│ ┌──jmp 1333
│ │ xchg %ax,%ax
│1330:│ mov %r15,%r10
│1333:└─→cmp %r15,%r14

If jump_arrow is 'false', the arrows isn't printed as below.
Default is 'false'.

│ ↓ jmp 1333
│ xchg %ax,%ax
│1330: mov %r15,%r10
│1333: cmp %r15,%r14

annotate.show_linenr::
When showing source code if this option is 'true',
line numbers are printed as below.

│1628 if (type & PERF_SAMPLE_IDENTIFIER) {
│ ↓ jne 508
│1628 data->id = *array;
│1629 array++;
│1630 }

However if this option is 'false', they aren't printed as below.
Default is 'false'.

│ if (type & PERF_SAMPLE_IDENTIFIER) {
│ ↓ jne 508
│ data->id = *array;
│ array++;
│ }

annotate.show_nr_jumps::
Let's see a part of assembly code.

│1382: movb $0x1,-0x270(%rbp)

If use this, the number of branches jumping to that address can be printed as below.
Default is 'false'.

│1 1382: movb $0x1,-0x270(%rbp)

annotate.show_total_period::
To compare two records on an instruction base, with this option
provided, display total number of samples that belong to a line
in assembly code. If this option is 'true', total periods are printed
instead of percent values as below.

302 │ mov %eax,%eax

But if this option is 'false', percent values for overhead are printed i.e.
Default is 'false'.

99.93 │ mov %eax,%eax

hist.*::
hist.percentage::
This option control the way to calculate overhead of filtered entries -
that means the value of this option is effective only if there's a
filter (by comm, dso or symbol name). Suppose a following example:

Overhead Symbols
........ .......
33.33% foo
33.33% bar
33.33% baz

This is an original overhead and we'll filter out the first 'foo'
entry. The value of 'relative' would increase the overhead of 'bar'
and 'baz' to 50.00% for each, while 'absolute' would show their
current overhead (33.33%).

SEE ALSO
--------
linkperf:perf[1]
2 changes: 1 addition & 1 deletion tools/perf/Documentation/perfconfig.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
medium = green, lightgray
normal = black, lightgray
selected = lightgray, magenta
code = blue, lightgray
jump_arrows = blue, lightgray
addr = magenta, lightgray

[tui]
Expand Down
Loading

0 comments on commit 402e8db

Please sign in to comment.