Commit f6986c95 authored by Adrian Hunter's avatar Adrian Hunter Committed by Arnaldo Carvalho de Melo

perf session: Add instruction tracing options

It is assumed that AUX area decoding will synthesize events for
consumption by other tools.

At this time, the main use of AUX area tracing will be to capture
instruction trace (aka processor trace) data.

The nature of instruction tracing suggests the initial inclusion of
options for "instructions" and "branches" events, but more could be
added as needed.
Signed-off-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1428594864-29309-10-git-send-email-adrian.hunter@intel.com
[ Added ref to tools/perf/Documentation/perf-script.txt describing what is parsed ]
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent c446870d
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "event.h" #include "event.h"
#include "debug.h" #include "debug.h"
#include "parse-options.h"
int auxtrace_mmap__mmap(struct auxtrace_mmap *mm, int auxtrace_mmap__mmap(struct auxtrace_mmap *mm,
struct auxtrace_mmap_params *mp, struct auxtrace_mmap_params *mp,
...@@ -200,6 +201,141 @@ int perf_event__synthesize_auxtrace_info(struct auxtrace_record *itr, ...@@ -200,6 +201,141 @@ int perf_event__synthesize_auxtrace_info(struct auxtrace_record *itr,
return err; return err;
} }
#define PERF_ITRACE_DEFAULT_PERIOD_TYPE PERF_ITRACE_PERIOD_NANOSECS
#define PERF_ITRACE_DEFAULT_PERIOD 100000
#define PERF_ITRACE_DEFAULT_CALLCHAIN_SZ 16
#define PERF_ITRACE_MAX_CALLCHAIN_SZ 1024
void itrace_synth_opts__set_default(struct itrace_synth_opts *synth_opts)
{
synth_opts->instructions = true;
synth_opts->branches = true;
synth_opts->errors = true;
synth_opts->period_type = PERF_ITRACE_DEFAULT_PERIOD_TYPE;
synth_opts->period = PERF_ITRACE_DEFAULT_PERIOD;
synth_opts->callchain_sz = PERF_ITRACE_DEFAULT_CALLCHAIN_SZ;
}
/*
* Please check tools/perf/Documentation/perf-script.txt for information
* about the options parsed here, which is introduced after this cset,
* when support in 'perf script' for these options is introduced.
*/
int itrace_parse_synth_opts(const struct option *opt, const char *str,
int unset)
{
struct itrace_synth_opts *synth_opts = opt->value;
const char *p;
char *endptr;
synth_opts->set = true;
if (unset) {
synth_opts->dont_decode = true;
return 0;
}
if (!str) {
itrace_synth_opts__set_default(synth_opts);
return 0;
}
for (p = str; *p;) {
switch (*p++) {
case 'i':
synth_opts->instructions = true;
while (*p == ' ' || *p == ',')
p += 1;
if (isdigit(*p)) {
synth_opts->period = strtoull(p, &endptr, 10);
p = endptr;
while (*p == ' ' || *p == ',')
p += 1;
switch (*p++) {
case 'i':
synth_opts->period_type =
PERF_ITRACE_PERIOD_INSTRUCTIONS;
break;
case 't':
synth_opts->period_type =
PERF_ITRACE_PERIOD_TICKS;
break;
case 'm':
synth_opts->period *= 1000;
/* Fall through */
case 'u':
synth_opts->period *= 1000;
/* Fall through */
case 'n':
if (*p++ != 's')
goto out_err;
synth_opts->period_type =
PERF_ITRACE_PERIOD_NANOSECS;
break;
case '\0':
goto out;
default:
goto out_err;
}
}
break;
case 'b':
synth_opts->branches = true;
break;
case 'e':
synth_opts->errors = true;
break;
case 'd':
synth_opts->log = true;
break;
case 'c':
synth_opts->branches = true;
synth_opts->calls = true;
break;
case 'r':
synth_opts->branches = true;
synth_opts->returns = true;
break;
case 'g':
synth_opts->instructions = true;
synth_opts->callchain = true;
synth_opts->callchain_sz =
PERF_ITRACE_DEFAULT_CALLCHAIN_SZ;
while (*p == ' ' || *p == ',')
p += 1;
if (isdigit(*p)) {
unsigned int val;
val = strtoul(p, &endptr, 10);
p = endptr;
if (!val || val > PERF_ITRACE_MAX_CALLCHAIN_SZ)
goto out_err;
synth_opts->callchain_sz = val;
}
break;
case ' ':
case ',':
break;
default:
goto out_err;
}
}
out:
if (synth_opts->instructions) {
if (!synth_opts->period_type)
synth_opts->period_type =
PERF_ITRACE_DEFAULT_PERIOD_TYPE;
if (!synth_opts->period)
synth_opts->period = PERF_ITRACE_DEFAULT_PERIOD;
}
return 0;
out_err:
pr_err("Bad Instruction Tracing options '%s'\n", str);
return -EINVAL;
}
int auxtrace_mmap__read(struct auxtrace_mmap *mm, struct auxtrace_record *itr, int auxtrace_mmap__read(struct auxtrace_mmap *mm, struct auxtrace_record *itr,
struct perf_tool *tool, process_auxtrace_t fn) struct perf_tool *tool, process_auxtrace_t fn)
{ {
......
...@@ -29,9 +29,49 @@ union perf_event; ...@@ -29,9 +29,49 @@ union perf_event;
struct perf_session; struct perf_session;
struct perf_evlist; struct perf_evlist;
struct perf_tool; struct perf_tool;
struct option;
struct record_opts; struct record_opts;
struct auxtrace_info_event; struct auxtrace_info_event;
enum itrace_period_type {
PERF_ITRACE_PERIOD_INSTRUCTIONS,
PERF_ITRACE_PERIOD_TICKS,
PERF_ITRACE_PERIOD_NANOSECS,
};
/**
* struct itrace_synth_opts - AUX area tracing synthesis options.
* @set: indicates whether or not options have been set
* @inject: indicates the event (not just the sample) must be fully synthesized
* because 'perf inject' will write it out
* @instructions: whether to synthesize 'instructions' events
* @branches: whether to synthesize 'branches' events
* @errors: whether to synthesize decoder error events
* @dont_decode: whether to skip decoding entirely
* @log: write a decoding log
* @calls: limit branch samples to calls (can be combined with @returns)
* @returns: limit branch samples to returns (can be combined with @calls)
* @callchain: add callchain to 'instructions' events
* @callchain_sz: maximum callchain size
* @period: 'instructions' events period
* @period_type: 'instructions' events period type
*/
struct itrace_synth_opts {
bool set;
bool inject;
bool instructions;
bool branches;
bool errors;
bool dont_decode;
bool log;
bool calls;
bool returns;
bool callchain;
unsigned int callchain_sz;
unsigned long long period;
enum itrace_period_type period_type;
};
/** /**
* struct auxtrace - session callbacks to allow AUX area data decoding. * struct auxtrace - session callbacks to allow AUX area data decoding.
* @process_event: lets the decoder see all session events * @process_event: lets the decoder see all session events
...@@ -186,6 +226,9 @@ int perf_event__synthesize_auxtrace_info(struct auxtrace_record *itr, ...@@ -186,6 +226,9 @@ int perf_event__synthesize_auxtrace_info(struct auxtrace_record *itr,
struct perf_tool *tool, struct perf_tool *tool,
struct perf_session *session, struct perf_session *session,
perf_event__handler_t process); perf_event__handler_t process);
int itrace_parse_synth_opts(const struct option *opt, const char *str,
int unset);
void itrace_synth_opts__set_default(struct itrace_synth_opts *synth_opts);
static inline int auxtrace__process_event(struct perf_session *session, static inline int auxtrace__process_event(struct perf_session *session,
union perf_event *event, union perf_event *event,
......
...@@ -16,12 +16,14 @@ struct ip_callchain; ...@@ -16,12 +16,14 @@ struct ip_callchain;
struct thread; struct thread;
struct auxtrace; struct auxtrace;
struct itrace_synth_opts;
struct perf_session { struct perf_session {
struct perf_header header; struct perf_header header;
struct machines machines; struct machines machines;
struct perf_evlist *evlist; struct perf_evlist *evlist;
struct auxtrace *auxtrace; struct auxtrace *auxtrace;
struct itrace_synth_opts *itrace_synth_opts;
struct trace_event tevent; struct trace_event tevent;
bool repipe; bool repipe;
bool one_mmap; bool one_mmap;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment