Skip to content

Commit

Permalink
Merge tag 'perf-core-for-mingo-5.1-20190307' 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/urgent

Pull perf/core changes from Arnaldo Carvalho de Melo:

perf bpf:

  Arnaldo Carvalho de Melo:

  - Automatically add BTF ELF markers to 'perf trace' BPF programs, so that
    tools such as 'bpftool map dump' can pretty print map keys and values.

perf c2c:

  Jiri Olsa:

  - Fix report for empty NUMA node.

perf diff:

  Jin Yao:

  - Support --time, --cpu, --pid and --tid filter options.

perf probe:

  Arnaldo Carvalho de Melo:

  - Clarify error message about not finding kernel modules debuginfo.

perf record:

  Jiri Olsa:

  - Fixup probing for max attr.precise_ip.

perf trace:

  Arnaldo Carvalho de Melo:

  - Add missing %s lost in the 'msg_flags' recvmmsg arg when adding prefix suppression logic.

perf annotate:

  Arnaldo Carvalho de Melo:

  - Calculate the max instruction name, align column to that, removing the
    hardcoded max 6 chars and cope with instructions with names longer than that,
    such as vpmovmskb, vpcmpeqb, etc.

kernel:

  Song Liu:

  - Consider events with attr.bpf_event set as side-band.

  Gustavo A. R. Silva:

  - Mark expected switch fall-through in perf_event_parse_addr_filter().

Libraries:

  Jiri Olsa:

  - Fix leaks and double frees on error paths.

libtraceevent:

  Tony Jones:

  - Fix buffer overflow in arg_eval().

python scripting:

  Tony Jones:

  - More python3 fixes.

Trivial:

  Yang Wei:

  - Remove needless extra semicolon in clang C++ glue code.

Intel PT/BTS:

  Adrian Hunter:

  - Improve auxtrace address filter error message when there is no DSO.

  - Fix divide by zero when TSC is not available.

  - Further improvements to the export to sqlite/posgresql python scripts
    and to the GUI sqlviewer, exporting 'parent_id' so that we have enable
    the creation of call trees.

  Andi Kleen:

  - Generalize function to copy from thread addr space from intel-bts code.

Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
  • Loading branch information
Ingo Molnar committed Mar 9, 2019
2 parents 43aa378 + b8f7d86 commit b339da4
Show file tree
Hide file tree
Showing 51 changed files with 977 additions and 448 deletions.
3 changes: 2 additions & 1 deletion kernel/events/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -4238,7 +4238,8 @@ static bool is_sb_event(struct perf_event *event)
if (attr->mmap || attr->mmap_data || attr->mmap2 ||
attr->comm || attr->comm_exec ||
attr->task || attr->ksymbol ||
attr->context_switch)
attr->context_switch ||
attr->bpf_event)
return true;
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion tools/lib/traceevent/event-parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -2457,7 +2457,7 @@ static int arg_num_eval(struct tep_print_arg *arg, long long *val)
static char *arg_eval (struct tep_print_arg *arg)
{
long long val;
static char buf[20];
static char buf[24];

switch (arg->type) {
case TEP_PRINT_ATOM:
Expand Down
56 changes: 56 additions & 0 deletions tools/perf/Documentation/perf-diff.txt
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,62 @@ OPTIONS
sum of shown entries will be always 100%. "absolute" means it retains
the original value before and after the filter is applied.

--time::
Analyze samples within given time window. It supports time
percent with multiple time ranges. Time string is 'a%/n,b%/m,...'
or 'a%-b%,c%-%d,...'.

For example:

Select the second 10% time slice to diff:

perf diff --time 10%/2

Select from 0% to 10% time slice to diff:

perf diff --time 0%-10%

Select the first and the second 10% time slices to diff:

perf diff --time 10%/1,10%/2

Select from 0% to 10% and 30% to 40% slices to diff:

perf diff --time 0%-10%,30%-40%

It also supports analyzing samples within a given time window
<start>,<stop>. Times have the format seconds.microseconds. If 'start'
is not given (i.e., time string is ',x.y') then analysis starts at
the beginning of the file. If stop time is not given (i.e, time
string is 'x.y,') then analysis goes to the end of the file. Time string is
'a1.b1,c1.d1:a2.b2,c2.d2'. Use ':' to separate timestamps for different
perf.data files.

For example, we get the timestamp information from 'perf script'.

perf script -i perf.data.old
mgen 13940 [000] 3946.361400: ...

perf script -i perf.data
mgen 13940 [000] 3971.150589 ...

perf diff --time 3946.361400,:3971.150589,

It analyzes the perf.data.old from the timestamp 3946.361400 to
the end of perf.data.old and analyzes the perf.data from the
timestamp 3971.150589 to the end of perf.data.

--cpu:: Only diff samples for the list of CPUs provided. Multiple CPUs can
be provided as a comma-separated list with no space: 0,1. Ranges of
CPUs are specified with -: 0-2. Default is to report samples on all
CPUs.

--pid=::
Only diff samples for given process ID (comma separated list).

--tid=::
Only diff samples for given thread ID (comma separated list).

COMPARISON
----------
The comparison is governed by the baseline file. The baseline perf.data
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/arch/arm64/annotate/instructions.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ static int arm64_mov__parse(struct arch *arch __maybe_unused,
}

static int mov__scnprintf(struct ins *ins, char *bf, size_t size,
struct ins_operands *ops);
struct ins_operands *ops, int max_ins_name);

static struct ins_ops arm64_mov_ops = {
.parse = arm64_mov__parse,
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/arch/s390/annotate/instructions.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ static int s390_call__parse(struct arch *arch, struct ins_operands *ops,
}

static int call__scnprintf(struct ins *ins, char *bf, size_t size,
struct ins_operands *ops);
struct ins_operands *ops, int max_ins_name);

static struct ins_ops s390_call_ops = {
.parse = s390_call__parse,
Expand Down
8 changes: 6 additions & 2 deletions tools/perf/builtin-c2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -2056,6 +2056,12 @@ static int setup_nodes(struct perf_session *session)
if (!set)
return -ENOMEM;

nodes[node] = set;

/* empty node, skip */
if (cpu_map__empty(map))
continue;

for (cpu = 0; cpu < map->nr; cpu++) {
set_bit(map->map[cpu], set);

Expand All @@ -2064,8 +2070,6 @@ static int setup_nodes(struct perf_session *session)

cpu2node[map->map[cpu]] = node;
}

nodes[node] = set;
}

setup_nodes_header();
Expand Down
168 changes: 154 additions & 14 deletions tools/perf/builtin-diff.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,21 @@
#include "util/util.h"
#include "util/data.h"
#include "util/config.h"
#include "util/time-utils.h"

#include <errno.h>
#include <inttypes.h>
#include <stdlib.h>
#include <math.h>

struct perf_diff {
struct perf_tool tool;
const char *time_str;
struct perf_time_interval *ptime_range;
int range_size;
int range_num;
};

/* Diff command specific HPP columns. */
enum {
PERF_HPP_DIFF__BASELINE,
Expand Down Expand Up @@ -74,6 +83,9 @@ static unsigned int sort_compute = 1;
static s64 compute_wdiff_w1;
static s64 compute_wdiff_w2;

static const char *cpu_list;
static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);

enum {
COMPUTE_DELTA,
COMPUTE_RATIO,
Expand Down Expand Up @@ -323,22 +335,33 @@ static int formula_fprintf(struct hist_entry *he, struct hist_entry *pair,
return -1;
}

static int diff__process_sample_event(struct perf_tool *tool __maybe_unused,
static int diff__process_sample_event(struct perf_tool *tool,
union perf_event *event,
struct perf_sample *sample,
struct perf_evsel *evsel,
struct machine *machine)
{
struct perf_diff *pdiff = container_of(tool, struct perf_diff, tool);
struct addr_location al;
struct hists *hists = evsel__hists(evsel);
int ret = -1;

if (perf_time__ranges_skip_sample(pdiff->ptime_range, pdiff->range_num,
sample->time)) {
return 0;
}

if (machine__resolve(machine, &al, sample) < 0) {
pr_warning("problem processing %d event, skipping it.\n",
event->header.type);
return -1;
}

if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) {
ret = 0;
goto out_put;
}

if (!hists__add_entry(hists, &al, NULL, NULL, NULL, sample, true)) {
pr_warning("problem incrementing symbol period, skipping event\n");
goto out_put;
Expand All @@ -359,17 +382,19 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused,
return ret;
}

static struct perf_tool tool = {
.sample = diff__process_sample_event,
.mmap = perf_event__process_mmap,
.mmap2 = perf_event__process_mmap2,
.comm = perf_event__process_comm,
.exit = perf_event__process_exit,
.fork = perf_event__process_fork,
.lost = perf_event__process_lost,
.namespaces = perf_event__process_namespaces,
.ordered_events = true,
.ordering_requires_timestamps = true,
static struct perf_diff pdiff = {
.tool = {
.sample = diff__process_sample_event,
.mmap = perf_event__process_mmap,
.mmap2 = perf_event__process_mmap2,
.comm = perf_event__process_comm,
.exit = perf_event__process_exit,
.fork = perf_event__process_fork,
.lost = perf_event__process_lost,
.namespaces = perf_event__process_namespaces,
.ordered_events = true,
.ordering_requires_timestamps = true,
},
};

static struct perf_evsel *evsel_match(struct perf_evsel *evsel,
Expand Down Expand Up @@ -771,26 +796,127 @@ static void data__free(struct data__file *d)
}
}

static int abstime_str_dup(char **pstr)
{
char *str = NULL;

if (pdiff.time_str && strchr(pdiff.time_str, ':')) {
str = strdup(pdiff.time_str);
if (!str)
return -ENOMEM;
}

*pstr = str;
return 0;
}

static int parse_absolute_time(struct data__file *d, char **pstr)
{
char *p = *pstr;
int ret;

/*
* Absolute timestamp for one file has the format: a.b,c.d
* For multiple files, the format is: a.b,c.d:a.b,c.d
*/
p = strchr(*pstr, ':');
if (p) {
if (p == *pstr) {
pr_err("Invalid time string\n");
return -EINVAL;
}

*p = 0;
p++;
if (*p == 0) {
pr_err("Invalid time string\n");
return -EINVAL;
}
}

ret = perf_time__parse_for_ranges(*pstr, d->session,
&pdiff.ptime_range,
&pdiff.range_size,
&pdiff.range_num);
if (ret < 0)
return ret;

if (!p || *p == 0)
*pstr = NULL;
else
*pstr = p;

return ret;
}

static int parse_percent_time(struct data__file *d)
{
int ret;

ret = perf_time__parse_for_ranges(pdiff.time_str, d->session,
&pdiff.ptime_range,
&pdiff.range_size,
&pdiff.range_num);
return ret;
}

static int parse_time_str(struct data__file *d, char *abstime_ostr,
char **pabstime_tmp)
{
int ret = 0;

if (abstime_ostr)
ret = parse_absolute_time(d, pabstime_tmp);
else if (pdiff.time_str)
ret = parse_percent_time(d);

return ret;
}

static int __cmd_diff(void)
{
struct data__file *d;
int ret = -EINVAL, i;
int ret, i;
char *abstime_ostr, *abstime_tmp;

ret = abstime_str_dup(&abstime_ostr);
if (ret)
return ret;

abstime_tmp = abstime_ostr;
ret = -EINVAL;

data__for_each_file(i, d) {
d->session = perf_session__new(&d->data, false, &tool);
d->session = perf_session__new(&d->data, false, &pdiff.tool);
if (!d->session) {
pr_err("Failed to open %s\n", d->data.path);
ret = -1;
goto out_delete;
}

if (pdiff.time_str) {
ret = parse_time_str(d, abstime_ostr, &abstime_tmp);
if (ret < 0)
goto out_delete;
}

if (cpu_list) {
ret = perf_session__cpu_bitmap(d->session, cpu_list,
cpu_bitmap);
if (ret < 0)
goto out_delete;
}

ret = perf_session__process_events(d->session);
if (ret) {
pr_err("Failed to process %s\n", d->data.path);
goto out_delete;
}

perf_evlist__collapse_resort(d->session->evlist);

if (pdiff.ptime_range)
zfree(&pdiff.ptime_range);
}

data_process();
Expand All @@ -802,6 +928,13 @@ static int __cmd_diff(void)
}

free(data__files);

if (pdiff.ptime_range)
zfree(&pdiff.ptime_range);

if (abstime_ostr)
free(abstime_ostr);

return ret;
}

Expand Down Expand Up @@ -849,6 +982,13 @@ static const struct option options[] = {
OPT_UINTEGER('o', "order", &sort_compute, "Specify compute sorting."),
OPT_CALLBACK(0, "percentage", NULL, "relative|absolute",
"How to display percentage of filtered entries", parse_filter_percentage),
OPT_STRING(0, "time", &pdiff.time_str, "str",
"Time span (time percent or absolute timestamp)"),
OPT_STRING(0, "cpu", &cpu_list, "cpu", "list of cpus to profile"),
OPT_STRING(0, "pid", &symbol_conf.pid_list_str, "pid[,pid...]",
"only consider symbols in these pids"),
OPT_STRING(0, "tid", &symbol_conf.tid_list_str, "tid[,tid...]",
"only consider symbols in these tids"),
OPT_END()
};

Expand Down
Loading

0 comments on commit b339da4

Please sign in to comment.