aboutsummaryrefslogtreecommitdiff
path: root/tools/perf
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2011-08-05 10:32:54 +0200
committerIngo Molnar <mingo@elte.hu>2011-08-05 10:33:55 +0200
commit3272cab4063467410802367a8d69f06c65b2a866 (patch)
tree1c665f8572b0aab2a5343d32b5eaa6713669b04f /tools/perf
parentf629299b544b6cc12b4e3e85fec96f4ce5809482 (diff)
parent140d0b2108faebc77c6523296e211e509cb9f5f9 (diff)
Merge branch 'linus' into perf/urgent
Merge reason: Include most of the merge window trees, to do fixes on top. Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/Documentation/perf-annotate.txt6
-rw-r--r--tools/perf/Documentation/perf-probe.txt6
-rw-r--r--tools/perf/Documentation/perf-report.txt21
-rw-r--r--tools/perf/Documentation/perf-script.txt18
-rw-r--r--tools/perf/Makefile2
-rw-r--r--tools/perf/builtin-annotate.c15
-rw-r--r--tools/perf/builtin-probe.c3
-rw-r--r--tools/perf/builtin-record.c2
-rw-r--r--tools/perf/builtin-report.c57
-rw-r--r--tools/perf/builtin-script.c121
-rw-r--r--tools/perf/builtin-stat.c20
-rw-r--r--tools/perf/builtin-test.c249
-rw-r--r--tools/perf/builtin-top.c2
-rw-r--r--tools/perf/util/callchain.h6
-rw-r--r--tools/perf/util/dwarf-aux.c663
-rw-r--r--tools/perf/util/dwarf-aux.h100
-rw-r--r--tools/perf/util/evsel.c1
-rw-r--r--tools/perf/util/evsel.h1
-rw-r--r--tools/perf/util/header.c5
-rw-r--r--tools/perf/util/hist.c6
-rw-r--r--tools/perf/util/parse-events.c39
-rw-r--r--tools/perf/util/parse-events.h6
-rw-r--r--tools/perf/util/probe-event.c165
-rw-r--r--tools/perf/util/probe-event.h1
-rw-r--r--tools/perf/util/probe-finder.c752
-rw-r--r--tools/perf/util/probe-finder.h43
-rw-r--r--tools/perf/util/python.c17
-rw-r--r--tools/perf/util/session.c132
-rw-r--r--tools/perf/util/session.h9
-rw-r--r--tools/perf/util/sort.c223
-rw-r--r--tools/perf/util/sort.h14
-rw-r--r--tools/perf/util/string.c19
-rw-r--r--tools/perf/util/trace-event-info.c120
-rw-r--r--tools/perf/util/util.h1
34 files changed, 1816 insertions, 1029 deletions
diff --git a/tools/perf/Documentation/perf-annotate.txt b/tools/perf/Documentation/perf-annotate.txt
index 6f5a498608b..85c5f026930 100644
--- a/tools/perf/Documentation/perf-annotate.txt
+++ b/tools/perf/Documentation/perf-annotate.txt
@@ -66,6 +66,12 @@ OPTIONS
used. This interfaces starts by centering on the line with more
samples, TAB/UNTAB cycles through the lines with more samples.
+-c::
+--cpu:: Only report 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.
+
SEE ALSO
--------
linkperf:perf-record[1], linkperf:perf-report[1]
diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index 02bafce4b34..2780d9ce48b 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -34,9 +34,11 @@ OPTIONS
Specify vmlinux path which has debuginfo (Dwarf binary).
-m::
---module=MODNAME::
+--module=MODNAME|PATH::
Specify module name in which perf-probe searches probe points
- or lines.
+ or lines. If a path of module file is passed, perf-probe
+ treat it as an offline module (this means you can add a probe on
+ a module which has not been loaded yet).
-s::
--source=PATH::
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index 8ba03d6e539..04253c07d19 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -80,15 +80,24 @@ OPTIONS
--dump-raw-trace::
Dump raw trace in ASCII.
--g [type,min]::
+-g [type,min,order]::
--call-graph::
- Display call chains using type and min percent threshold.
+ Display call chains using type, min percent threshold and order.
type can be either:
- flat: single column, linear exposure of call chains.
- graph: use a graph tree, displaying absolute overhead rates.
- fractal: like graph, but displays relative rates. Each branch of
the tree is considered as a new profiled object. +
- Default: fractal,0.5.
+
+ order can be either:
+ - callee: callee based call graph.
+ - caller: inverted caller based call graph.
+
+ Default: fractal,0.5,callee.
+
+-G::
+--inverted::
+ alias for inverted caller based call graph.
--pretty=<key>::
Pretty printing style. key: normal, raw
@@ -119,6 +128,12 @@ OPTIONS
--symfs=<directory>::
Look for files with symbols relative to this directory.
+-c::
+--cpu:: Only report 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.
+
SEE ALSO
--------
linkperf:perf-stat[1]
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt
index 86c87e214b1..db017867d9e 100644
--- a/tools/perf/Documentation/perf-script.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -115,10 +115,10 @@ OPTIONS
-f::
--fields::
Comma separated list of fields to print. Options are:
- comm, tid, pid, time, cpu, event, trace, sym. Field
- list can be prepended with the type, trace, sw or hw,
+ comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr.
+ Field list can be prepended with the type, trace, sw or hw,
to indicate to which event type the field list applies.
- e.g., -f sw:comm,tid,time,sym and -f trace:time,cpu,trace
+ e.g., -f sw:comm,tid,time,ip,sym and -f trace:time,cpu,trace
perf script -f <fields>
@@ -132,17 +132,17 @@ OPTIONS
The arguments are processed in the order received. A later usage can
reset a prior request. e.g.:
- -f trace: -f comm,tid,time,sym
+ -f trace: -f comm,tid,time,ip,sym
The first -f suppresses trace events (field list is ""), but then the
- second invocation sets the fields to comm,tid,time,sym. In this case a
+ second invocation sets the fields to comm,tid,time,ip,sym. In this case a
warning is given to the user:
"Overriding previous field request for all events."
Alternativey, consider the order:
- -f comm,tid,time,sym -f trace:
+ -f comm,tid,time,ip,sym -f trace:
The first -f sets the fields for all events and the second -f
suppresses trace events. The user is given a warning message about
@@ -182,6 +182,12 @@ OPTIONS
--hide-call-graph::
When printing symbols do not display call chain.
+-c::
+--cpu:: Only report 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.
+
SEE ALSO
--------
linkperf:perf-record[1], linkperf:perf-script-perl[1],
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index c16836611d2..56d62d3fb16 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -282,6 +282,7 @@ LIB_H += util/thread.h
LIB_H += util/thread_map.h
LIB_H += util/trace-event.h
LIB_H += util/probe-finder.h
+LIB_H += util/dwarf-aux.h
LIB_H += util/probe-event.h
LIB_H += util/pstack.h
LIB_H += util/cpumap.h
@@ -438,6 +439,7 @@ else
BASIC_CFLAGS += -DDWARF_SUPPORT
EXTLIBS += -lelf -ldw
LIB_OBJS += $(OUTPUT)util/probe-finder.o
+ LIB_OBJS += $(OUTPUT)util/dwarf-aux.o
endif # PERF_HAVE_DWARF_REGS
endif # NO_DWARF
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 7b139e1e7e8..555aefd7fe0 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -28,6 +28,8 @@
#include "util/hist.h"
#include "util/session.h"
+#include <linux/bitmap.h>
+
static char const *input_name = "perf.data";
static bool force, use_tui, use_stdio;
@@ -38,6 +40,9 @@ static bool print_line;
static const char *sym_hist_filter;
+static const char *cpu_list;
+static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
+
static int perf_evlist__add_sample(struct perf_evlist *evlist,
struct perf_sample *sample,
struct perf_evsel *evsel,
@@ -90,6 +95,9 @@ static int process_sample_event(union perf_event *event,
return -1;
}
+ if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
+ return 0;
+
if (!al.filtered &&
perf_evlist__add_sample(session->evlist, sample, evsel, &al)) {
pr_warning("problem incrementing symbol count, "
@@ -177,6 +185,12 @@ static int __cmd_annotate(void)
if (session == NULL)
return -ENOMEM;
+ if (cpu_list) {
+ ret = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap);
+ if (ret)
+ goto out_delete;
+ }
+
ret = perf_session__process_events(session, &event_ops);
if (ret)
goto out_delete;
@@ -252,6 +266,7 @@ static const struct option options[] = {
"print matching source lines (may be slow)"),
OPT_BOOLEAN('P', "full-paths", &full_paths,
"Don't shorten the displayed pathnames"),
+ OPT_STRING('c', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
OPT_END()
};
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 2c0e64d0b4a..5f2a5c7046d 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -242,7 +242,8 @@ static const struct option options[] = {
OPT_STRING('s', "source", &symbol_conf.source_prefix,
"directory", "path to kernel source"),
OPT_STRING('m', "module", &params.target_module,
- "modname", "target module name"),
+ "modname|path",
+ "target module name (for online) or path (for offline)"),
#endif
OPT__DRY_RUN(&probe_event_dry_run),
OPT_INTEGER('\0', "max-probes", &params.max_probe_points,
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 8e2c8579818..80dc5b790e4 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -740,7 +740,7 @@ static bool force, append_file;
const struct option record_options[] = {
OPT_CALLBACK('e', "event", &evsel_list, "event",
"event selector. use 'perf list' to list available events",
- parse_events),
+ parse_events_option),
OPT_CALLBACK(0, "filter", &evsel_list, "filter",
"event filter", parse_filter),
OPT_INTEGER('p', "pid", &target_pid,
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 287a173523a..f854efda768 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -33,6 +33,8 @@
#include "util/sort.h"
#include "util/hist.h"
+#include <linux/bitmap.h>
+
static char const *input_name = "perf.data";
static bool force, use_tui, use_stdio;
@@ -45,9 +47,13 @@ static struct perf_read_values show_threads_values;
static const char default_pretty_printing_style[] = "normal";
static const char *pretty_printing_style = default_pretty_printing_style;
-static char callchain_default_opt[] = "fractal,0.5";
+static char callchain_default_opt[] = "fractal,0.5,callee";
+static bool inverted_callchain;
static symbol_filter_t annotate_init;
+static const char *cpu_list;
+static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
+
static int perf_session__add_hist_entry(struct perf_session *session,
struct addr_location *al,
struct perf_sample *sample,
@@ -116,6 +122,9 @@ static int process_sample_event(union perf_event *event,
if (al.filtered || (hide_unresolved && al.sym == NULL))
return 0;
+ if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
+ return 0;
+
if (al.map != NULL)
al.map->dso->hit = 1;
@@ -262,6 +271,12 @@ static int __cmd_report(void)
if (session == NULL)
return -ENOMEM;
+ if (cpu_list) {
+ ret = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap);
+ if (ret)
+ goto out_delete;
+ }
+
if (show_threads)
perf_read_values_init(&show_threads_values);
@@ -386,13 +401,29 @@ parse_callchain_opt(const struct option *opt __used, const char *arg,
if (!tok)
goto setup;
- tok2 = strtok(NULL, ",");
callchain_param.min_percent = strtod(tok, &endptr);
if (tok == endptr)
return -1;
- if (tok2)
+ /* get the print limit */
+ tok2 = strtok(NULL, ",");
+ if (!tok2)
+ goto setup;
+
+ if (tok2[0] != 'c') {
callchain_param.print_limit = strtod(tok2, &endptr);
+ tok2 = strtok(NULL, ",");
+ if (!tok2)
+ goto setup;
+ }
+
+ /* get the call chain order */
+ if (!strcmp(tok2, "caller"))
+ callchain_param.order = ORDER_CALLER;
+ else if (!strcmp(tok2, "callee"))
+ callchain_param.order = ORDER_CALLEE;
+ else
+ return -1;
setup:
if (callchain_register_param(&callchain_param) < 0) {
fprintf(stderr, "Can't register callchain params\n");
@@ -436,9 +467,10 @@ static const struct option options[] = {
"regex filter to identify parent, see: '--sort parent'"),
OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other,
"Only display entries with parent-match"),
- OPT_CALLBACK_DEFAULT('g', "call-graph", NULL, "output_type,min_percent",
- "Display callchains using output_type (graph, flat, fractal, or none) and min percent threshold. "
- "Default: fractal,0.5", &parse_callchain_opt, callchain_default_opt),
+ OPT_CALLBACK_DEFAULT('g', "call-graph", NULL, "output_type,min_percent, call_order",
+ "Display callchains using output_type (graph, flat, fractal, or none) , min percent threshold and callchain order. "
+ "Default: fractal,0.5,callee", &parse_callchain_opt, callchain_default_opt),
+ OPT_BOOLEAN('G', "inverted", &inverted_callchain, "alias for inverted call graph"),
OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
"only consider symbols in these dsos"),
OPT_STRING('C', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
@@ -455,6 +487,7 @@ static const struct option options[] = {
"Only display entries resolved to a symbol"),
OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
"Look for files with symbols relative to this directory"),
+ OPT_STRING('c', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
OPT_END()
};
@@ -467,6 +500,9 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
else if (use_tui)
use_browser = 1;
+ if (inverted_callchain)
+ callchain_param.order = ORDER_CALLER;
+
if (strcmp(input_name, "-") != 0)
setup_browser(true);
else
@@ -504,7 +540,14 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
if (parent_pattern != default_parent_pattern) {
if (sort_dimension__add("parent") < 0)
return -1;
- sort_parent.elide = 1;
+
+ /*
+ * Only show the parent fields if we explicitly
+ * sort that way. If we only use parent machinery
+ * for filtering, we don't want it.
+ */
+ if (!strstr(sort_order, "parent"))
+ sort_parent.elide = 1;
} else
symbol_conf.exclude_other = false;
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 22747de7234..09024ec2ab2 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -13,6 +13,7 @@
#include "util/util.h"
#include "util/evlist.h"
#include "util/evsel.h"
+#include <linux/bitmap.h>
static char const *script_name;
static char const *generate_script_lang;
@@ -21,6 +22,8 @@ static u64 last_timestamp;
static u64 nr_unordered;
extern const struct option record_options[];
static bool no_callchain;
+static const char *cpu_list;
+static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
enum perf_output_field {
PERF_OUTPUT_COMM = 1U << 0,
@@ -30,7 +33,10 @@ enum perf_output_field {
PERF_OUTPUT_CPU = 1U << 4,
PERF_OUTPUT_EVNAME = 1U << 5,
PERF_OUTPUT_TRACE = 1U << 6,
- PERF_OUTPUT_SYM = 1U << 7,
+ PERF_OUTPUT_IP = 1U << 7,
+ PERF_OUTPUT_SYM = 1U << 8,
+ PERF_OUTPUT_DSO = 1U << 9,
+ PERF_OUTPUT_ADDR = 1U << 10,
};
struct output_option {
@@ -44,7 +50,10 @@ struct output_option {
{.str = "cpu", .field = PERF_OUTPUT_CPU},
{.str = "event", .field = PERF_OUTPUT_EVNAME},
{.str = "trace", .field = PERF_OUTPUT_TRACE},
+ {.str = "ip", .field = PERF_OUTPUT_IP},
{.str = "sym", .field = PERF_OUTPUT_SYM},
+ {.str = "dso", .field = PERF_OUTPUT_DSO},
+ {.str = "addr", .field = PERF_OUTPUT_ADDR},
};
/* default set to maintain compatibility with current format */
@@ -60,7 +69,8 @@ static struct {
.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
- PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM,
+ PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
+ PERF_OUTPUT_SYM | PERF_OUTPUT_DSO,
.invalid_fields = PERF_OUTPUT_TRACE,
},
@@ -70,7 +80,8 @@ static struct {
.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
- PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM,
+ PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
+ PERF_OUTPUT_SYM | PERF_OUTPUT_DSO,
.invalid_fields = PERF_OUTPUT_TRACE,
},
@@ -88,7 +99,8 @@ static struct {
.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
- PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM,
+ PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
+ PERF_OUTPUT_SYM | PERF_OUTPUT_DSO,
.invalid_fields = PERF_OUTPUT_TRACE,
},
@@ -157,9 +169,9 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
!perf_session__has_traces(session, "record -R"))
return -EINVAL;
- if (PRINT_FIELD(SYM)) {
+ if (PRINT_FIELD(IP)) {
if (perf_event_attr__check_stype(attr, PERF_SAMPLE_IP, "IP",
- PERF_OUTPUT_SYM))
+ PERF_OUTPUT_IP))
return -EINVAL;
if (!no_callchain &&
@@ -167,6 +179,24 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
symbol_conf.use_callchain = false;
}
+ if (PRINT_FIELD(ADDR) &&
+ perf_event_attr__check_stype(attr, PERF_SAMPLE_ADDR, "ADDR",
+ PERF_OUTPUT_ADDR))
+ return -EINVAL;
+
+ if (PRINT_FIELD(SYM) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) {
+ pr_err("Display of symbols requested but neither sample IP nor "
+ "sample address\nis selected. Hence, no addresses to convert "
+ "to symbols.\n");
+ return -EINVAL;
+ }
+ if (PRINT_FIELD(DSO) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) {
+ pr_err("Display of DSO requested but neither sample IP nor "
+ "sample address\nis selected. Hence, no addresses to convert "
+ "to DSO.\n");
+ return -EINVAL;
+ }
+
if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) &&
perf_event_attr__check_stype(attr, PERF_SAMPLE_TID, "TID",
PERF_OUTPUT_TID|PERF_OUTPUT_PID))
@@ -230,7 +260,7 @@ static void print_sample_start(struct perf_sample *sample,
if (PRINT_FIELD(COMM)) {
if (latency_format)
printf("%8.8s ", thread->comm);
- else if (PRINT_FIELD(SYM) && symbol_conf.use_callchain)
+ else if (PRINT_FIELD(IP) && symbol_conf.use_callchain)
printf("%s ", thread->comm);
else
printf("%16s ", thread->comm);
@@ -271,6 +301,63 @@ static void print_sample_start(struct perf_sample *sample,
}
}
+static bool sample_addr_correlates_sym(struct perf_event_attr *attr)
+{
+ if ((attr->type == PERF_TYPE_SOFTWARE) &&
+ ((attr->config == PERF_COUNT_SW_PAGE_FAULTS) ||
+ (attr->config == PERF_COUNT_SW_PAGE_FAULTS_MIN) ||
+ (attr->config == PERF_COUNT_SW_PAGE_FAULTS_MAJ)))
+ return true;
+
+ return false;
+}
+
+static void print_sample_addr(union perf_event *event,
+ struct perf_sample *sample,
+ struct perf_session *session,
+ struct thread *thread,
+ struct perf_event_attr *attr)
+{
+ struct addr_location al;
+ u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+ const char *symname, *dsoname;
+
+ printf("%16" PRIx64, sample->addr);
+
+ if (!sample_addr_correlates_sym(attr))
+ return;
+
+ thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION,
+ event->ip.pid, sample->addr, &al);
+ if (!al.map)
+ thread__find_addr_map(thread, session, cpumode, MAP__VARIABLE,
+ event->ip.pid, sample->addr, &al);
+
+ al.cpu = sample->cpu;
+ al.sym = NULL;
+
+ if (al.map)
+ al.sym = map__find_symbol(al.map, al.addr, NULL);
+
+ if (PRINT_FIELD(SYM)) {
+ if (al.sym && al.sym->name)
+ symname = al.sym->name;
+ else
+ symname = "";
+
+ printf(" %16s", symname);
+ }
+
+ if (PRINT_FIELD(DSO)) {
+ if (al.map && al.map->dso && al.map->dso->name)
+ dsoname = al.map->dso->name;
+ else
+ dsoname = "";
+
+ printf(" (%s)", dsoname);
+ }
+}
+
static void process_event(union perf_event *event __unused,
struct perf_sample *sample,
struct perf_evsel *evsel,
@@ -288,12 +375,16 @@ static void process_event(union perf_event *event __unused,
print_trace_event(sample->cpu, sample->raw_data,
sample->raw_size);
- if (PRINT_FIELD(SYM)) {
+ if (PRINT_FIELD(ADDR))
+ print_sample_addr(event, sample, session, thread, attr);
+
+ if (PRINT_FIELD(IP)) {
if (!symbol_conf.use_callchain)
printf(" ");
else
printf("\n");
- perf_session__print_symbols(event, sample, session);
+ perf_session__print_ip(event, sample, session,
+ PRINT_FIELD(SYM), PRINT_FIELD(DSO));
}
printf("\n");
@@ -365,6 +456,10 @@ static int process_sample_event(union perf_event *event,
last_timestamp = sample->time;
return 0;
}
+
+ if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
+ return 0;
+
scripting_ops->process_event(event, sample, evsel, session, thread);
session->hists.stats.total_period += sample->period;
@@ -985,8 +1080,9 @@ static const struct option options[] = {
OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
"Look for files with symbols relative to this directory"),
OPT_CALLBACK('f', "fields", NULL, "str",
- "comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace,raw. Fields: comm,tid,pid,time,cpu,event,trace,sym",
+ "comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace,raw. Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,addr",
parse_output_fields),
+ OPT_STRING('c', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
OPT_END()
};
@@ -1167,6 +1263,11 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
if (session == NULL)
return -ENOMEM;
+ if (cpu_list) {
+ if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap))
+ return -1;
+ }
+
if (!no_callchain)
symbol_conf.use_callchain = true;
else
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index a9f06715e44..1ad04ce29c3 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -61,6 +61,8 @@
#include <locale.h>
#define DEFAULT_SEPARATOR " "
+#define CNTR_NOT_SUPPORTED "<not supported>"
+#define CNTR_NOT_COUNTED "<not counted>"
static struct perf_event_attr default_attrs[] = {
@@ -448,6 +450,7 @@ static int run_perf_stat(int argc __used, const char **argv)
if (verbose)
ui__warning("%s event is not supported by the kernel.\n",
event_name(counter));
+ counter->supported = false;
continue;
}
@@ -466,6 +469,7 @@ static int run_perf_stat(int argc __used, const char **argv)
die("Not all events could be opened.\n");
return -1;
}
+ counter->supported = true;
}
if (perf_evlist__set_filters(evsel_list)) {
@@ -513,7 +517,10 @@ static void print_noise_pct(double total, double avg)
if (avg)
pct = 100.0*total/avg;
- fprintf(stderr, " ( +-%6.2f%% )", pct);
+ if (csv_output)
+ fprintf(stderr, "%s%.2f%%", csv_sep, pct);
+ else
+ fprintf(stderr, " ( +-%6.2f%% )", pct);
}
static void print_noise(struct perf_evsel *evsel, double avg)
@@ -861,7 +868,7 @@ static void print_counter_aggr(struct perf_evsel *counter)
if (scaled == -1) {
fprintf(stderr, "%*s%s%*s",
csv_output ? 0 : 18,
- "<not counted>",
+ counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
csv_sep,
csv_output ? 0 : -24,
event_name(counter));
@@ -878,13 +885,13 @@ static void print_counter_aggr(struct perf_evsel *counter)
else
abs_printout(-1, counter, avg);
+ print_noise(counter, avg);
+
if (csv_output) {
fputc('\n', stderr);
return;
}
- print_noise(counter, avg);
-
if (scaled) {
double avg_enabled, avg_running;
@@ -914,7 +921,8 @@ static void print_counter(struct perf_evsel *counter)
csv_output ? 0 : -4,
evsel_list->cpus->map[cpu], csv_sep,
csv_output ? 0 : 18,
- "<not counted>", csv_sep,
+ counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
+ csv_sep,
csv_output ? 0 : -24,
event_name(counter));
@@ -1024,7 +1032,7 @@ static int stat__set_big_num(const struct option *opt __used,
static const struct option options[] = {
OPT_CALLBACK('e', "event", &evsel_list, "event",
"event selector. use 'perf list' to list available events",
- parse_events),
+ parse_events_option),
OPT_CALLBACK(0, "filter", &evsel_list, "filter",
"event filter", parse_filter),
OPT_BOOLEAN('i', "no-inherit", &no_inherit,
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c
index 2da9162262b..55f4c76f282 100644
--- a/tools/perf/builtin-test.c
+++ b/tools/perf/builtin-test.c
@@ -12,6 +12,7 @@
#include "util/parse-events.h"
#include "util/symbol.h"
#include "util/thread_map.h"
+#include "../../include/linux/hw_breakpoint.h"
static long page_size;
@@ -245,8 +246,8 @@ static int trace_event__id(const char *evname)
int err = -1, fd;
if (asprintf(&filename,
- "/sys/kernel/debug/tracing/events/syscalls/%s/id",
- evname) < 0)
+ "%s/syscalls/%s/id",
+ debugfs_path, evname) < 0)
return -1;
fd = open(filename, O_RDONLY);
@@ -600,6 +601,246 @@ out_free_threads:
#undef nsyscalls
}
+#define TEST_ASSERT_VAL(text, cond) \
+do { \
+ if (!cond) { \
+ pr_debug("FAILED %s:%d %s\n", __FILE__, __LINE__, text); \
+ return -1; \
+ } \
+} while (0)
+
+static int test__checkevent_tracepoint(struct perf_evlist *evlist)
+{
+ struct perf_evsel *evsel = list_entry(evlist->entries.next,
+ struct perf_evsel, node);
+
+ TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
+ TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type);
+ TEST_ASSERT_VAL("wrong sample_type",
+ (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) ==
+ evsel->attr.sample_type);
+ TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period);
+ return 0;
+}
+
+static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist)
+{
+ struct perf_evsel *evsel;
+
+ TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1);
+
+ list_for_each_entry(evsel, &evlist->entries, node) {
+ TEST_ASSERT_VAL("wrong type",
+ PERF_TYPE_TRACEPOINT == evsel->attr.type);
+ TEST_ASSERT_VAL("wrong sample_type",
+ (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU)
+ == evsel->attr.sample_type);
+ TEST_ASSERT_VAL("wrong sample_period",
+ 1 == evsel->attr.sample_period);
+ }
+ return 0;
+}
+
+static int test__checkevent_raw(struct perf_evlist *evlist)
+{
+ struct perf_evsel *evsel = list_entry(evlist->entries.next,
+ struct perf_evsel, node);
+
+ TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
+ TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type);
+ TEST_ASSERT_VAL("wrong conf