Skip to content

Commit

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

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

perf report:

  He Kuang:

  - Don't shadow inlined symbol with different addr range.

perf script:

  Jiri Olsa:

  - Allow +- operator to ask for -F to add/remove fields to
    the default set, for instance to ask for the removal of the
    'cpu' field in tracepoint events, adding 'period' to that
    kind of events, etc.

perf test:

  Thomas Richter:

  - Fix scheduler tracepoint signedness of COMM fields failure of
    'evsel-tp-sched' test on s390 and other arches.

  Tommi Rantala:

  - Skip trace+probe_vfs_getname.sh when 'perf trace' is not built.

perf trace:

  Arnaldo Carvalho de Melo:

  - Add initial BPF map dumper, initially just for the current, minimal
    needs of the augmented_raw_syscalls BPF example used to collect
    pointer args payloads that uses BPF maps for pid and syscall filtering,
    but will in time have features similar to 'perf stat' --interval-print,
    --interval-clear, ways to signal from a BPF event that a specific
    map (or range of that map) should be printed, optionally as a
    histogram, etc.

General:

  Jiri Olsa:

  - Add CPU and NUMA topologies classes for further reuse, fixing some
    issues in the process.

  - Fixup some warnings and debug levels.

  - Make rm_rf() remove single file, not just directories.

Documentation:

  Jonas Rabenstein:

  - Fix HEADER_CMDLINE description in perf.data documentation.

  - Fix documentation of the Flags section in perf.data.

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 28, 2019
2 parents 9ed8f1a + b4409ae commit 0a15712
Show file tree
Hide file tree
Showing 21 changed files with 530 additions and 256 deletions.
6 changes: 6 additions & 0 deletions tools/perf/Documentation/perf-script.txt
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,12 @@ OPTIONS
the override, and the result of the above is that only S/W and H/W
events are displayed with the given fields.

It's possible tp add/remove fields only for specific event type:

-Fsw:-cpu,-period

removes cpu and period from software events.

For the 'wildcard' option if a user selected field is invalid for an
event type, a message is displayed to the user that the option is
ignored for that type. For example:
Expand Down
8 changes: 8 additions & 0 deletions tools/perf/Documentation/perf-trace.txt
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,14 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs.
may happen, for instance, when a thread gets migrated to a different CPU
while processing a syscall.

--map-dump::
Dump BPF maps setup by events passed via -e, for instance the augmented_raw_syscalls
living in tools/perf/examples/bpf/augmented_raw_syscalls.c. For now this
dumps just boolean map values and integer keys, in time this will print in hex
by default and use BTF when available, as well as use functions to do pretty
printing using the existing 'perf trace' syscall arg beautifiers to map integer
arguments to strings (pid to comm, syscall id to syscall name, etc).


PAGEFAULTS
----------
Expand Down
11 changes: 5 additions & 6 deletions tools/perf/Documentation/perf.data-file-format.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,10 @@ struct perf_file_section {

Flags section:

The header is followed by different optional headers, described by the bits set
in flags. Only headers for which the bit is set are included. Each header
consists of a perf_file_section located after the initial header.
The respective perf_file_section points to the data of the additional
header and defines its size.
For each of the optional features a perf_file_section it placed after the data
section if the feature bit is set in the perf_header flags bitset. The
respective perf_file_section points to the data of the additional header and
defines its size.

Some headers consist of strings, which are defined like this:

Expand Down Expand Up @@ -131,7 +130,7 @@ An uint64_t with the total memory in bytes.

HEADER_CMDLINE = 11,

A perf_header_string with the perf command line used to collect the data.
A perf_header_string_list with the perf arg-vector used to collect the data.

HEADER_EVENT_DESC = 12,

Expand Down
8 changes: 8 additions & 0 deletions tools/perf/builtin-script.c
Original file line number Diff line number Diff line change
Expand Up @@ -2560,6 +2560,10 @@ static int parse_output_fields(const struct option *opt __maybe_unused,
pr_warning("Overriding previous field request for %s events.\n",
event_type(type));

/* Don't override defaults for +- */
if (strchr(tok, '+') || strchr(tok, '-'))
goto parse;

output[type].fields = 0;
output[type].user_set = true;
output[type].wildcard_set = false;
Expand Down Expand Up @@ -2644,6 +2648,10 @@ static int parse_output_fields(const struct option *opt __maybe_unused,
rc = -EINVAL;
goto out;
}
if (change == REMOVE)
output[type].fields &= ~all_output_options[i].field;
else
output[type].fields |= all_output_options[i].field;
output[type].user_set = true;
output[type].wildcard_set = true;
}
Expand Down
19 changes: 19 additions & 0 deletions tools/perf/builtin-trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <traceevent/event-parse.h>
#include <api/fs/tracing_path.h>
#include <bpf/bpf.h>
#include "util/bpf_map.h"
#include "builtin.h"
#include "util/cgroup.h"
#include "util/color.h"
Expand Down Expand Up @@ -87,6 +88,9 @@ struct trace {
*augmented;
} events;
} syscalls;
struct {
struct bpf_map *map;
} dump;
struct record_opts opts;
struct perf_evlist *evlist;
struct machine *host;
Expand Down Expand Up @@ -2997,6 +3001,9 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
if (err < 0)
goto out_error_apply_filters;

if (trace->dump.map)
bpf_map__fprintf(trace->dump.map, trace->output);

err = perf_evlist__mmap(evlist, trace->opts.mmap_pages);
if (err < 0)
goto out_error_mmap;
Expand Down Expand Up @@ -3686,6 +3693,7 @@ int cmd_trace(int argc, const char **argv)
.max_stack = UINT_MAX,
.max_events = ULONG_MAX,
};
const char *map_dump_str = NULL;
const char *output_name = NULL;
const struct option trace_options[] = {
OPT_CALLBACK('e', "event", &trace, "event",
Expand Down Expand Up @@ -3718,6 +3726,9 @@ int cmd_trace(int argc, const char **argv)
OPT_CALLBACK(0, "duration", &trace, "float",
"show only events with duration > N.M ms",
trace__set_duration),
#ifdef HAVE_LIBBPF_SUPPORT
OPT_STRING(0, "map-dump", &map_dump_str, "BPF map", "BPF map to periodically dump"),
#endif
OPT_BOOLEAN(0, "sched", &trace.sched, "show blocking scheduler events"),
OPT_INCR('v', "verbose", &verbose, "be more verbose"),
OPT_BOOLEAN('T', "time", &trace.full_time,
Expand Down Expand Up @@ -3812,6 +3823,14 @@ int cmd_trace(int argc, const char **argv)

err = -1;

if (map_dump_str) {
trace.dump.map = bpf__find_map_by_name(map_dump_str);
if (trace.dump.map == NULL) {
pr_err("ERROR: BPF map \"%s\" not found\n", map_dump_str);
goto out;
}
}

if (trace.trace_pgfaults) {
trace.opts.sample_address = true;
trace.opts.sample_time = true;
Expand Down
6 changes: 3 additions & 3 deletions tools/perf/tests/evsel-tp-sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ int test__perf_evsel__tp_sched_test(struct test *test __maybe_unused, int subtes
return -1;
}

if (perf_evsel__test_field(evsel, "prev_comm", 16, true))
if (perf_evsel__test_field(evsel, "prev_comm", 16, false))
ret = -1;

if (perf_evsel__test_field(evsel, "prev_pid", 4, true))
Expand All @@ -55,7 +55,7 @@ int test__perf_evsel__tp_sched_test(struct test *test __maybe_unused, int subtes
if (perf_evsel__test_field(evsel, "prev_state", sizeof(long), true))
ret = -1;

if (perf_evsel__test_field(evsel, "next_comm", 16, true))
if (perf_evsel__test_field(evsel, "next_comm", 16, false))
ret = -1;

if (perf_evsel__test_field(evsel, "next_pid", 4, true))
Expand All @@ -73,7 +73,7 @@ int test__perf_evsel__tp_sched_test(struct test *test __maybe_unused, int subtes
return -1;
}

if (perf_evsel__test_field(evsel, "comm", 16, true))
if (perf_evsel__test_field(evsel, "comm", 16, false))
ret = -1;

if (perf_evsel__test_field(evsel, "pid", 4, true))
Expand Down
5 changes: 5 additions & 0 deletions tools/perf/tests/shell/lib/probe.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@ skip_if_no_perf_probe() {
perf probe 2>&1 | grep -q 'is not a perf-command' && return 2
return 0
}

skip_if_no_perf_trace() {
perf trace -h 2>&1 | grep -q -e 'is not a perf-command' -e 'trace command not available' && return 2
return 0
}
1 change: 1 addition & 0 deletions tools/perf/tests/shell/trace+probe_vfs_getname.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
. $(dirname $0)/lib/probe.sh

skip_if_no_perf_probe || exit 2
skip_if_no_perf_trace || exit 2

. $(dirname $0)/lib/probe_vfs_getname.sh

Expand Down
2 changes: 2 additions & 0 deletions tools/perf/util/Build
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ perf-y += hist.o
perf-y += util.o
perf-y += xyarray.o
perf-y += cpumap.o
perf-y += cputopo.o
perf-y += cgroup.o
perf-y += target.o
perf-y += rblist.o
Expand Down Expand Up @@ -114,6 +115,7 @@ perf-y += branch.o
perf-y += mem2node.o

perf-$(CONFIG_LIBBPF) += bpf-loader.o
perf-$(CONFIG_LIBBPF) += bpf_map.o
perf-$(CONFIG_BPF_PROLOGUE) += bpf-prologue.o
perf-$(CONFIG_LIBELF) += symbol-elf.o
perf-$(CONFIG_LIBELF) += probe-file.o
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/util/bpf-event.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ int perf_event__synthesize_bpf_events(struct perf_tool *tool,
err = 0;
break;
}
pr_debug("%s: can't get next program: %s%s",
pr_debug("%s: can't get next program: %s%s\n",
__func__, strerror(errno),
errno == EINVAL ? " -- kernel too old?" : "");
/* don't report error on old kernel or EPERM */
Expand Down
72 changes: 72 additions & 0 deletions tools/perf/util/bpf_map.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)

#include "util/bpf_map.h"
#include <bpf/bpf.h>
#include <bpf/libbpf.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>

static bool bpf_map_def__is_per_cpu(const struct bpf_map_def *def)
{
return def->type == BPF_MAP_TYPE_PERCPU_HASH ||
def->type == BPF_MAP_TYPE_PERCPU_ARRAY ||
def->type == BPF_MAP_TYPE_LRU_PERCPU_HASH ||
def->type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE;
}

static void *bpf_map_def__alloc_value(const struct bpf_map_def *def)
{
if (bpf_map_def__is_per_cpu(def))
return malloc(round_up(def->value_size, 8) * sysconf(_SC_NPROCESSORS_CONF));

return malloc(def->value_size);
}

int bpf_map__fprintf(struct bpf_map *map, FILE *fp)
{
const struct bpf_map_def *def = bpf_map__def(map);
void *prev_key = NULL, *key, *value;
int fd = bpf_map__fd(map), err;
int printed = 0;

if (fd < 0)
return fd;

if (IS_ERR(def))
return PTR_ERR(def);

err = -ENOMEM;
key = malloc(def->key_size);
if (key == NULL)
goto out;

value = bpf_map_def__alloc_value(def);
if (value == NULL)
goto out_free_key;

while ((err = bpf_map_get_next_key(fd, prev_key, key) == 0)) {
int intkey = *(int *)key;

if (!bpf_map_lookup_elem(fd, key, value)) {
bool boolval = *(bool *)value;
if (boolval)
printed += fprintf(fp, "[%d] = %d,\n", intkey, boolval);
} else {
printed += fprintf(fp, "[%d] = ERROR,\n", intkey);
}

prev_key = key;
}

if (err == ENOENT)
err = printed;

free(value);
out_free_key:
free(key);
out:
return err;
}
22 changes: 22 additions & 0 deletions tools/perf/util/bpf_map.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
#ifndef __PERF_BPF_MAP_H
#define __PERF_BPF_MAP_H 1

#include <stdio.h>
#include <linux/compiler.h>
struct bpf_map;

#ifdef HAVE_LIBBPF_SUPPORT

int bpf_map__fprintf(struct bpf_map *map, FILE *fp);

#else

static inline int bpf_map__fprintf(struct bpf_map *map __maybe_unused, FILE *fp __maybe_unused)
{
return 0;
}

#endif // HAVE_LIBBPF_SUPPORT

#endif // __PERF_BPF_MAP_H
2 changes: 1 addition & 1 deletion tools/perf/util/cpumap.c
Original file line number Diff line number Diff line change
Expand Up @@ -681,7 +681,7 @@ size_t cpu_map__snprint(struct cpu_map *map, char *buf, size_t size)

#undef COMMA

pr_debug("cpumask list: %s\n", buf);
pr_debug2("cpumask list: %s\n", buf);
return ret;
}

Expand Down
Loading

0 comments on commit 0a15712

Please sign in to comment.