Skip to content

Commit

Permalink
Merge tag 'perf-core-for-mingo-4.17-20180305' 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:

- Be more robust when drawing arrows in the annotation TUI, avoiding a
  segfault when jump instructions have as a target addresses in functions
  other that the one currently being annotated. The full fix will come in
  the following days, when jumping to other functions will work as call
  instructions (Arnaldo Carvalho de Melo)

- Allow asking for the maximum allowed sample rate in 'top' and
  'record', i.e. 'perf record -F max' will read the
  kernel.perf_event_max_sample_rate sysctl and use it (Arnaldo Carvalho de Melo)

- When the user specifies a freq above kernel.perf_event_max_sample_rate,
  Throttle it down to that max freq, and warn the user about it, add as
  well --strict-freq so that the previous behaviour of not starting the
  session when the desired freq can't be used can be selected (Arnaldo Carvalho de Melo)

- Find 'call' instruction target symbol at parsing time, used so far in
  the TUI, part of the infrastructure changes that will end up allowing
  for jumps to navigate to other functions, just like 'call'
  instructions. (Arnaldo Carvalho de Melo)

- Use xyarray dimensions to iterate fds in 'perf stat' (Andi Kleen)

- Ignore threads for which the current user hasn't permissions when
  enabling system-wide --per-thread (Jin Yao)

- Fix some backtrace perf test cases to use 'perf record' + 'perf script'
  instead, till 'perf trace' starts using ordered_events or equivalent
  to avoid symbol resolving artifacts due to reordering of
  PERF_RECORD_MMAP events (Jiri Olsa)

- Fix crash in 'perf record' pipe mode, it needs to allocate the ID
  array even for a single event, unlike non-pipe mode (Jiri Olsa)

- Make annoying fallback message on older kernels with newer 'perf top'
  binaries trying to use overwrite mode and that not being present
  in the older kernels (Kan Liang)

- Switch last users of old APIs to the newer perf_mmap__read_event()
  one, then discard those old mmap read forward APIs (Kan Liang)

- Fix the usage on the 'perf kallsyms' man page (Sangwon Hong)

- Simplify cgroup arguments when tracking multiple events (weiping zhang)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Ingo Molnar committed Mar 6, 2018
2 parents 8af3136 + 6afad54 commit 55b4ce6
Show file tree
Hide file tree
Showing 34 changed files with 328 additions and 146 deletions.
2 changes: 1 addition & 1 deletion tools/perf/Documentation/perf-kallsyms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ perf-kallsyms - Searches running kernel for symbols
SYNOPSIS
--------
[verse]
'perf kallsyms <options> symbol_name[,symbol_name...]'
'perf kallsyms' [<options>] symbol_name[,symbol_name...]

DESCRIPTION
-----------
Expand Down
15 changes: 13 additions & 2 deletions tools/perf/Documentation/perf-record.txt
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,16 @@ OPTIONS
-i::
--no-inherit::
Child tasks do not inherit counters.

-F::
--freq=::
Profile at this frequency.
Profile at this frequency. Use 'max' to use the currently maximum
allowed frequency, i.e. the value in the kernel.perf_event_max_sample_rate
sysctl. Will throttle down to the currently maximum allowed frequency.
See --strict-freq.

--strict-freq::
Fail if the specified frequency can't be used.

-m::
--mmap-pages=::
Expand Down Expand Up @@ -308,7 +315,11 @@ can be provided. Each cgroup is applied to the corresponding event, i.e., first
to first event, second cgroup to second event and so on. It is possible to provide
an empty cgroup (monitor all the time) using, e.g., -G foo,,bar. Cgroups must have
corresponding events, i.e., they always refer to events defined earlier on the command
line.
line. If the user wants to track multiple events for a specific cgroup, the user can
use '-e e1 -e e2 -G foo,foo' or just use '-e e1 -e e2 -G foo'.

If wanting to monitor, say, 'cycles' for a cgroup and also for system wide, this
command line can be used: 'perf stat -e cycles -G cgroup_name -a -e cycles'.

-b::
--branch-any::
Expand Down
6 changes: 5 additions & 1 deletion tools/perf/Documentation/perf-stat.txt
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,11 @@ can be provided. Each cgroup is applied to the corresponding event, i.e., first
to first event, second cgroup to second event and so on. It is possible to provide
an empty cgroup (monitor all the time) using, e.g., -G foo,,bar. Cgroups must have
corresponding events, i.e., they always refer to events defined earlier on the command
line.
line. If the user wants to track multiple events for a specific cgroup, the user can
use '-e e1 -e e2 -G foo,foo' or just use '-e e1 -e e2 -G foo'.

If wanting to monitor, say, 'cycles' for a cgroup and also for system wide, this
command line can be used: 'perf stat -e cycles -G cgroup_name -a -e cycles'.

-o file::
--output file::
Expand Down
4 changes: 3 additions & 1 deletion tools/perf/Documentation/perf-top.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ Default is to monitor all CPUS.

-F <freq>::
--freq=<freq>::
Profile at this frequency.
Profile at this frequency. Use 'max' to use the currently maximum
allowed frequency, i.e. the value in the kernel.perf_event_max_sample_rate
sysctl.

-i::
--inherit::
Expand Down
11 changes: 9 additions & 2 deletions tools/perf/arch/x86/tests/perf-time-to-tsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe
union perf_event *event;
u64 test_tsc, comm1_tsc, comm2_tsc;
u64 test_time, comm1_time = 0, comm2_time = 0;
struct perf_mmap *md;
u64 end, start;

threads = thread_map__new(-1, getpid(), UINT_MAX);
CHECK_NOT_NULL__(threads);
Expand Down Expand Up @@ -109,7 +111,11 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe
perf_evlist__disable(evlist);

for (i = 0; i < evlist->nr_mmaps; i++) {
while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
md = &evlist->mmap[i];
if (perf_mmap__read_init(md, false, &start, &end) < 0)
continue;

while ((event = perf_mmap__read_event(md, false, &start, end)) != NULL) {
struct perf_sample sample;

if (event->header.type != PERF_RECORD_COMM ||
Expand All @@ -128,8 +134,9 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe
comm2_time = sample.time;
}
next_event:
perf_evlist__mmap_consume(evlist, i);
perf_mmap__consume(md, false);
}
perf_mmap__read_done(md);
}

if (!comm1_time || !comm2_time)
Expand Down
17 changes: 13 additions & 4 deletions tools/perf/builtin-kvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -743,16 +743,24 @@ static bool verify_vcpu(int vcpu)
static s64 perf_kvm__mmap_read_idx(struct perf_kvm_stat *kvm, int idx,
u64 *mmap_time)
{
struct perf_evlist *evlist = kvm->evlist;
union perf_event *event;
struct perf_mmap *md;
u64 end, start;
u64 timestamp;
s64 n = 0;
int err;

*mmap_time = ULLONG_MAX;
while ((event = perf_evlist__mmap_read(kvm->evlist, idx)) != NULL) {
err = perf_evlist__parse_sample_timestamp(kvm->evlist, event, &timestamp);
md = &evlist->mmap[idx];
err = perf_mmap__read_init(md, false, &start, &end);
if (err < 0)
return (err == -EAGAIN) ? 0 : -1;

while ((event = perf_mmap__read_event(md, false, &start, end)) != NULL) {
err = perf_evlist__parse_sample_timestamp(evlist, event, &timestamp);
if (err) {
perf_evlist__mmap_consume(kvm->evlist, idx);
perf_mmap__consume(md, false);
pr_err("Failed to parse sample\n");
return -1;
}
Expand All @@ -762,7 +770,7 @@ static s64 perf_kvm__mmap_read_idx(struct perf_kvm_stat *kvm, int idx,
* FIXME: Here we can't consume the event, as perf_session__queue_event will
* point to it, and it'll get possibly overwritten by the kernel.
*/
perf_evlist__mmap_consume(kvm->evlist, idx);
perf_mmap__consume(md, false);

if (err) {
pr_err("Failed to enqueue sample: %d\n", err);
Expand All @@ -779,6 +787,7 @@ static s64 perf_kvm__mmap_read_idx(struct perf_kvm_stat *kvm, int idx,
break;
}

perf_mmap__read_done(md);
return n;
}

Expand Down
18 changes: 17 additions & 1 deletion tools/perf/builtin-record.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@

#include <errno.h>
#include <inttypes.h>
#include <locale.h>
#include <poll.h>
#include <unistd.h>
#include <sched.h>
Expand Down Expand Up @@ -881,6 +882,15 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
}
}

/*
* If we have just single event and are sending data
* through pipe, we need to force the ids allocation,
* because we synthesize event name through the pipe
* and need the id for that.
*/
if (data->is_pipe && rec->evlist->nr_entries == 1)
rec->opts.sample_id = true;

if (record__open(rec) != 0) {
err = -1;
goto out_child;
Expand Down Expand Up @@ -1542,7 +1552,11 @@ static struct option __record_options[] = {
OPT_BOOLEAN(0, "tail-synthesize", &record.opts.tail_synthesize,
"synthesize non-sample events at the end of output"),
OPT_BOOLEAN(0, "overwrite", &record.opts.overwrite, "use overwrite mode"),
OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"),
OPT_BOOLEAN(0, "strict-freq", &record.opts.strict_freq,
"Fail if the specified frequency can't be used"),
OPT_CALLBACK('F', "freq", &record.opts, "freq or 'max'",
"profile at this frequency",
record__parse_freq),
OPT_CALLBACK('m', "mmap-pages", &record.opts, "pages[,pages]",
"number of mmap data pages and AUX area tracing mmap pages",
record__parse_mmap_pages),
Expand Down Expand Up @@ -1651,6 +1665,8 @@ int cmd_record(int argc, const char **argv)
struct record *rec = &record;
char errbuf[BUFSIZ];

setlocale(LC_ALL, "");

#ifndef HAVE_LIBBPF_SUPPORT
# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, "NO_LIBBPF=1", c)
set_nobuild('\0', "clang-path", true);
Expand Down
25 changes: 18 additions & 7 deletions tools/perf/builtin-stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,14 +508,13 @@ static int perf_stat_synthesize_config(bool is_pipe)

#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))

static int __store_counter_ids(struct perf_evsel *counter,
struct cpu_map *cpus,
struct thread_map *threads)
static int __store_counter_ids(struct perf_evsel *counter)
{
int cpu, thread;

for (cpu = 0; cpu < cpus->nr; cpu++) {
for (thread = 0; thread < threads->nr; thread++) {
for (cpu = 0; cpu < xyarray__max_x(counter->fd); cpu++) {
for (thread = 0; thread < xyarray__max_y(counter->fd);
thread++) {
int fd = FD(counter, cpu, thread);

if (perf_evlist__id_add_fd(evsel_list, counter,
Expand All @@ -535,7 +534,7 @@ static int store_counter_ids(struct perf_evsel *counter)
if (perf_evsel__alloc_id(counter, cpus->nr, threads->nr))
return -ENOMEM;

return __store_counter_ids(counter, cpus, threads);
return __store_counter_ids(counter);
}

static bool perf_evsel__should_store_id(struct perf_evsel *counter)
Expand Down Expand Up @@ -638,7 +637,19 @@ static int __run_perf_stat(int argc, const char **argv)
if (verbose > 0)
ui__warning("%s\n", msg);
goto try_again;
}
} else if (target__has_per_thread(&target) &&
evsel_list->threads &&
evsel_list->threads->err_thread != -1) {
/*
* For global --per-thread case, skip current
* error thread.
*/
if (!thread_map__remove(evsel_list->threads,
evsel_list->threads->err_thread)) {
evsel_list->threads->err_thread = -1;
goto try_again;
}
}

perf_evsel__open_strerror(counter, &target,
errno, msg, sizeof(msg));
Expand Down
6 changes: 4 additions & 2 deletions tools/perf/builtin-top.c
Original file line number Diff line number Diff line change
Expand Up @@ -991,7 +991,7 @@ static int perf_top_overwrite_fallback(struct perf_top *top,
evlist__for_each_entry(evlist, counter)
counter->attr.write_backward = false;
opts->overwrite = false;
ui__warning("fall back to non-overwrite mode\n");
pr_debug2("fall back to non-overwrite mode\n");
return 1;
}

Expand Down Expand Up @@ -1307,7 +1307,9 @@ int cmd_top(int argc, const char **argv)
OPT_STRING(0, "sym-annotate", &top.sym_filter, "symbol name",
"symbol to annotate"),
OPT_BOOLEAN('z', "zero", &top.zero, "zero history across updates"),
OPT_UINTEGER('F', "freq", &opts->user_freq, "profile at this frequency"),
OPT_CALLBACK('F', "freq", &top.record_opts, "freq or 'max'",
"profile at this frequency",
record__parse_freq),
OPT_INTEGER('E', "entries", &top.print_entries,
"display this many functions"),
OPT_BOOLEAN('U', "hide_user_symbols", &top.hide_user_symbols,
Expand Down
11 changes: 9 additions & 2 deletions tools/perf/builtin-trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -2472,8 +2472,14 @@ static int trace__run(struct trace *trace, int argc, const char **argv)

for (i = 0; i < evlist->nr_mmaps; i++) {
union perf_event *event;
struct perf_mmap *md;
u64 end, start;

while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
md = &evlist->mmap[i];
if (perf_mmap__read_init(md, false, &start, &end) < 0)
continue;

while ((event = perf_mmap__read_event(md, false, &start, end)) != NULL) {
struct perf_sample sample;

++trace->nr_events;
Expand All @@ -2486,7 +2492,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)

trace__handle_event(trace, event, &sample);
next_event:
perf_evlist__mmap_consume(evlist, i);
perf_mmap__consume(md, false);

if (interrupted)
goto out_disable;
Expand All @@ -2496,6 +2502,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
draining = true;
}
}
perf_mmap__read_done(md);
}

if (trace->nr_events == before) {
Expand Down
4 changes: 4 additions & 0 deletions tools/perf/perf.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ struct record_opts {
bool tail_synthesize;
bool overwrite;
bool ignore_missing_thread;
bool strict_freq;
bool sample_id;
unsigned int freq;
unsigned int mmap_pages;
unsigned int auxtrace_mmap_pages;
Expand All @@ -82,4 +84,6 @@ struct record_opts {
struct option;
extern const char * const *record_usage;
extern struct option *record_options;

int record__parse_freq(const struct option *opt, const char *str, int unset);
#endif
9 changes: 8 additions & 1 deletion tools/perf/tests/bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,20 @@ static int do_test(struct bpf_object *obj, int (*func)(void),

for (i = 0; i < evlist->nr_mmaps; i++) {
union perf_event *event;
struct perf_mmap *md;
u64 end, start;

while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
md = &evlist->mmap[i];
if (perf_mmap__read_init(md, false, &start, &end) < 0)
continue;

while ((event = perf_mmap__read_event(md, false, &start, end)) != NULL) {
const u32 type = event->header.type;

if (type == PERF_RECORD_SAMPLE)
count ++;
}
perf_mmap__read_done(md);
}

if (count != expect) {
Expand Down
11 changes: 9 additions & 2 deletions tools/perf/tests/code-reading.c
Original file line number Diff line number Diff line change
Expand Up @@ -409,15 +409,22 @@ static int process_events(struct machine *machine, struct perf_evlist *evlist,
struct state *state)
{
union perf_event *event;
struct perf_mmap *md;
u64 end, start;
int i, ret;

for (i = 0; i < evlist->nr_mmaps; i++) {
while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
md = &evlist->mmap[i];
if (perf_mmap__read_init(md, false, &start, &end) < 0)
continue;

while ((event = perf_mmap__read_event(md, false, &start, end)) != NULL) {
ret = process_event(machine, evlist, event, state);
perf_evlist__mmap_consume(evlist, i);
perf_mmap__consume(md, false);
if (ret < 0)
return ret;
}
perf_mmap__read_done(md);
}
return 0;
}
Expand Down
10 changes: 8 additions & 2 deletions tools/perf/tests/keep-tracking.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,24 @@
static int find_comm(struct perf_evlist *evlist, const char *comm)
{
union perf_event *event;
struct perf_mmap *md;
u64 end, start;
int i, found;

found = 0;
for (i = 0; i < evlist->nr_mmaps; i++) {
while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
md = &evlist->mmap[i];
if (perf_mmap__read_init(md, false, &start, &end) < 0)
continue;
while ((event = perf_mmap__read_event(md, false, &start, end)) != NULL) {
if (event->header.type == PERF_RECORD_COMM &&
(pid_t)event->comm.pid == getpid() &&
(pid_t)event->comm.tid == getpid() &&
strcmp(event->comm.comm, comm) == 0)
found += 1;
perf_evlist__mmap_consume(evlist, i);
perf_mmap__consume(md, false);
}
perf_mmap__read_done(md);
}
return found;
}
Expand Down
Loading

0 comments on commit 55b4ce6

Please sign in to comment.