Skip to content

Commit 0a15712

Browse files
author
Ingo Molnar
committed
Merge tag 'perf-core-for-mingo-5.1-20190220' of git://git.kernel.org/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>
2 parents 9ed8f1a + b4409ae commit 0a15712

21 files changed

+530
-256
lines changed

tools/perf/Documentation/perf-script.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,12 @@ OPTIONS
159159
the override, and the result of the above is that only S/W and H/W
160160
events are displayed with the given fields.
161161

162+
It's possible tp add/remove fields only for specific event type:
163+
164+
-Fsw:-cpu,-period
165+
166+
removes cpu and period from software events.
167+
162168
For the 'wildcard' option if a user selected field is invalid for an
163169
event type, a message is displayed to the user that the option is
164170
ignored for that type. For example:

tools/perf/Documentation/perf-trace.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,14 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs.
210210
may happen, for instance, when a thread gets migrated to a different CPU
211211
while processing a syscall.
212212

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

214222
PAGEFAULTS
215223
----------

tools/perf/Documentation/perf.data-file-format.txt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,10 @@ struct perf_file_section {
4343

4444
Flags section:
4545

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

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

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

132131
HEADER_CMDLINE = 11,
133132

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

136135
HEADER_EVENT_DESC = 12,
137136

tools/perf/builtin-script.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2560,6 +2560,10 @@ static int parse_output_fields(const struct option *opt __maybe_unused,
25602560
pr_warning("Overriding previous field request for %s events.\n",
25612561
event_type(type));
25622562

2563+
/* Don't override defaults for +- */
2564+
if (strchr(tok, '+') || strchr(tok, '-'))
2565+
goto parse;
2566+
25632567
output[type].fields = 0;
25642568
output[type].user_set = true;
25652569
output[type].wildcard_set = false;
@@ -2644,6 +2648,10 @@ static int parse_output_fields(const struct option *opt __maybe_unused,
26442648
rc = -EINVAL;
26452649
goto out;
26462650
}
2651+
if (change == REMOVE)
2652+
output[type].fields &= ~all_output_options[i].field;
2653+
else
2654+
output[type].fields |= all_output_options[i].field;
26472655
output[type].user_set = true;
26482656
output[type].wildcard_set = true;
26492657
}

tools/perf/builtin-trace.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <traceevent/event-parse.h>
2020
#include <api/fs/tracing_path.h>
2121
#include <bpf/bpf.h>
22+
#include "util/bpf_map.h"
2223
#include "builtin.h"
2324
#include "util/cgroup.h"
2425
#include "util/color.h"
@@ -87,6 +88,9 @@ struct trace {
8788
*augmented;
8889
} events;
8990
} syscalls;
91+
struct {
92+
struct bpf_map *map;
93+
} dump;
9094
struct record_opts opts;
9195
struct perf_evlist *evlist;
9296
struct machine *host;
@@ -2997,6 +3001,9 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
29973001
if (err < 0)
29983002
goto out_error_apply_filters;
29993003

3004+
if (trace->dump.map)
3005+
bpf_map__fprintf(trace->dump.map, trace->output);
3006+
30003007
err = perf_evlist__mmap(evlist, trace->opts.mmap_pages);
30013008
if (err < 0)
30023009
goto out_error_mmap;
@@ -3686,6 +3693,7 @@ int cmd_trace(int argc, const char **argv)
36863693
.max_stack = UINT_MAX,
36873694
.max_events = ULONG_MAX,
36883695
};
3696+
const char *map_dump_str = NULL;
36893697
const char *output_name = NULL;
36903698
const struct option trace_options[] = {
36913699
OPT_CALLBACK('e', "event", &trace, "event",
@@ -3718,6 +3726,9 @@ int cmd_trace(int argc, const char **argv)
37183726
OPT_CALLBACK(0, "duration", &trace, "float",
37193727
"show only events with duration > N.M ms",
37203728
trace__set_duration),
3729+
#ifdef HAVE_LIBBPF_SUPPORT
3730+
OPT_STRING(0, "map-dump", &map_dump_str, "BPF map", "BPF map to periodically dump"),
3731+
#endif
37213732
OPT_BOOLEAN(0, "sched", &trace.sched, "show blocking scheduler events"),
37223733
OPT_INCR('v', "verbose", &verbose, "be more verbose"),
37233734
OPT_BOOLEAN('T', "time", &trace.full_time,
@@ -3812,6 +3823,14 @@ int cmd_trace(int argc, const char **argv)
38123823

38133824
err = -1;
38143825

3826+
if (map_dump_str) {
3827+
trace.dump.map = bpf__find_map_by_name(map_dump_str);
3828+
if (trace.dump.map == NULL) {
3829+
pr_err("ERROR: BPF map \"%s\" not found\n", map_dump_str);
3830+
goto out;
3831+
}
3832+
}
3833+
38153834
if (trace.trace_pgfaults) {
38163835
trace.opts.sample_address = true;
38173836
trace.opts.sample_time = true;

tools/perf/tests/evsel-tp-sched.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ int test__perf_evsel__tp_sched_test(struct test *test __maybe_unused, int subtes
4343
return -1;
4444
}
4545

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

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

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

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

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

7979
if (perf_evsel__test_field(evsel, "pid", 4, true))

tools/perf/tests/shell/lib/probe.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,8 @@ skip_if_no_perf_probe() {
44
perf probe 2>&1 | grep -q 'is not a perf-command' && return 2
55
return 0
66
}
7+
8+
skip_if_no_perf_trace() {
9+
perf trace -h 2>&1 | grep -q -e 'is not a perf-command' -e 'trace command not available' && return 2
10+
return 0
11+
}

tools/perf/tests/shell/trace+probe_vfs_getname.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
. $(dirname $0)/lib/probe.sh
1313

1414
skip_if_no_perf_probe || exit 2
15+
skip_if_no_perf_trace || exit 2
1516

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

tools/perf/util/Build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ perf-y += hist.o
6969
perf-y += util.o
7070
perf-y += xyarray.o
7171
perf-y += cpumap.o
72+
perf-y += cputopo.o
7273
perf-y += cgroup.o
7374
perf-y += target.o
7475
perf-y += rblist.o
@@ -114,6 +115,7 @@ perf-y += branch.o
114115
perf-y += mem2node.o
115116

116117
perf-$(CONFIG_LIBBPF) += bpf-loader.o
118+
perf-$(CONFIG_LIBBPF) += bpf_map.o
117119
perf-$(CONFIG_BPF_PROLOGUE) += bpf-prologue.o
118120
perf-$(CONFIG_LIBELF) += symbol-elf.o
119121
perf-$(CONFIG_LIBELF) += probe-file.o

tools/perf/util/bpf-event.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ int perf_event__synthesize_bpf_events(struct perf_tool *tool,
233233
err = 0;
234234
break;
235235
}
236-
pr_debug("%s: can't get next program: %s%s",
236+
pr_debug("%s: can't get next program: %s%s\n",
237237
__func__, strerror(errno),
238238
errno == EINVAL ? " -- kernel too old?" : "");
239239
/* don't report error on old kernel or EPERM */

tools/perf/util/bpf_map.c

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
2+
3+
#include "util/bpf_map.h"
4+
#include <bpf/bpf.h>
5+
#include <bpf/libbpf.h>
6+
#include <linux/err.h>
7+
#include <linux/kernel.h>
8+
#include <stdbool.h>
9+
#include <stdlib.h>
10+
#include <unistd.h>
11+
12+
static bool bpf_map_def__is_per_cpu(const struct bpf_map_def *def)
13+
{
14+
return def->type == BPF_MAP_TYPE_PERCPU_HASH ||
15+
def->type == BPF_MAP_TYPE_PERCPU_ARRAY ||
16+
def->type == BPF_MAP_TYPE_LRU_PERCPU_HASH ||
17+
def->type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE;
18+
}
19+
20+
static void *bpf_map_def__alloc_value(const struct bpf_map_def *def)
21+
{
22+
if (bpf_map_def__is_per_cpu(def))
23+
return malloc(round_up(def->value_size, 8) * sysconf(_SC_NPROCESSORS_CONF));
24+
25+
return malloc(def->value_size);
26+
}
27+
28+
int bpf_map__fprintf(struct bpf_map *map, FILE *fp)
29+
{
30+
const struct bpf_map_def *def = bpf_map__def(map);
31+
void *prev_key = NULL, *key, *value;
32+
int fd = bpf_map__fd(map), err;
33+
int printed = 0;
34+
35+
if (fd < 0)
36+
return fd;
37+
38+
if (IS_ERR(def))
39+
return PTR_ERR(def);
40+
41+
err = -ENOMEM;
42+
key = malloc(def->key_size);
43+
if (key == NULL)
44+
goto out;
45+
46+
value = bpf_map_def__alloc_value(def);
47+
if (value == NULL)
48+
goto out_free_key;
49+
50+
while ((err = bpf_map_get_next_key(fd, prev_key, key) == 0)) {
51+
int intkey = *(int *)key;
52+
53+
if (!bpf_map_lookup_elem(fd, key, value)) {
54+
bool boolval = *(bool *)value;
55+
if (boolval)
56+
printed += fprintf(fp, "[%d] = %d,\n", intkey, boolval);
57+
} else {
58+
printed += fprintf(fp, "[%d] = ERROR,\n", intkey);
59+
}
60+
61+
prev_key = key;
62+
}
63+
64+
if (err == ENOENT)
65+
err = printed;
66+
67+
free(value);
68+
out_free_key:
69+
free(key);
70+
out:
71+
return err;
72+
}

tools/perf/util/bpf_map.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
2+
#ifndef __PERF_BPF_MAP_H
3+
#define __PERF_BPF_MAP_H 1
4+
5+
#include <stdio.h>
6+
#include <linux/compiler.h>
7+
struct bpf_map;
8+
9+
#ifdef HAVE_LIBBPF_SUPPORT
10+
11+
int bpf_map__fprintf(struct bpf_map *map, FILE *fp);
12+
13+
#else
14+
15+
static inline int bpf_map__fprintf(struct bpf_map *map __maybe_unused, FILE *fp __maybe_unused)
16+
{
17+
return 0;
18+
}
19+
20+
#endif // HAVE_LIBBPF_SUPPORT
21+
22+
#endif // __PERF_BPF_MAP_H

tools/perf/util/cpumap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,7 @@ size_t cpu_map__snprint(struct cpu_map *map, char *buf, size_t size)
681681

682682
#undef COMMA
683683

684-
pr_debug("cpumask list: %s\n", buf);
684+
pr_debug2("cpumask list: %s\n", buf);
685685
return ret;
686686
}
687687

0 commit comments

Comments
 (0)