perf tools: Stop using a global trace events description list

The pevent thing is per perf.data file, so I made it stop being static
and become a perf_session member, so tools processing perf.data files
use perf_session and _there_ we read the trace events description into
session->pevent and then change everywhere to stop using that single
global pevent variable and use the per session one.

Note that it _doesn't_ fall backs to trace__event_id, as we're not
interested at all in what is present in the
/sys/kernel/debug/tracing/events in the workstation doing the analysis,
just in what is in the perf.data file.

This patch also introduces perf_session__set_tracepoints_handlers that
is the perf perf.data/session way to associate handlers to tracepoint
events by resolving their IDs using the events descriptions stored in a
perf.data file. Make 'perf sched' use it.
Reported-by: default avatarDmitry Antipov <dmitry.antipov@linaro.org>
Tested-by: default avatarDmitry Antipov <dmitry.antipov@linaro.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: linaro-dev@lists.linaro.org
Cc: patches@linaro.org
Link: http://lkml.kernel.org/r/20120625232016.GA28525@infradead.orgSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 7a25b2d3
...@@ -57,6 +57,11 @@ static unsigned long nr_allocs, nr_cross_allocs; ...@@ -57,6 +57,11 @@ static unsigned long nr_allocs, nr_cross_allocs;
#define PATH_SYS_NODE "/sys/devices/system/node" #define PATH_SYS_NODE "/sys/devices/system/node"
struct perf_kmem {
struct perf_tool tool;
struct perf_session *session;
};
static void init_cpunode_map(void) static void init_cpunode_map(void)
{ {
FILE *fp; FILE *fp;
...@@ -278,14 +283,16 @@ static void process_free_event(void *data, ...@@ -278,14 +283,16 @@ static void process_free_event(void *data,
s_alloc->alloc_cpu = -1; s_alloc->alloc_cpu = -1;
} }
static void process_raw_event(union perf_event *raw_event __used, void *data, static void process_raw_event(struct perf_tool *tool,
union perf_event *raw_event __used, void *data,
int cpu, u64 timestamp, struct thread *thread) int cpu, u64 timestamp, struct thread *thread)
{ {
struct perf_kmem *kmem = container_of(tool, struct perf_kmem, tool);
struct event_format *event; struct event_format *event;
int type; int type;
type = trace_parse_common_type(data); type = trace_parse_common_type(kmem->session->pevent, data);
event = trace_find_event(type); event = pevent_find_event(kmem->session->pevent, type);
if (!strcmp(event->name, "kmalloc") || if (!strcmp(event->name, "kmalloc") ||
!strcmp(event->name, "kmem_cache_alloc")) { !strcmp(event->name, "kmem_cache_alloc")) {
...@@ -306,7 +313,7 @@ static void process_raw_event(union perf_event *raw_event __used, void *data, ...@@ -306,7 +313,7 @@ static void process_raw_event(union perf_event *raw_event __used, void *data,
} }
} }
static int process_sample_event(struct perf_tool *tool __used, static int process_sample_event(struct perf_tool *tool,
union perf_event *event, union perf_event *event,
struct perf_sample *sample, struct perf_sample *sample,
struct perf_evsel *evsel __used, struct perf_evsel *evsel __used,
...@@ -322,16 +329,18 @@ static int process_sample_event(struct perf_tool *tool __used, ...@@ -322,16 +329,18 @@ static int process_sample_event(struct perf_tool *tool __used,
dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
process_raw_event(event, sample->raw_data, sample->cpu, process_raw_event(tool, event, sample->raw_data, sample->cpu,
sample->time, thread); sample->time, thread);
return 0; return 0;
} }
static struct perf_tool perf_kmem = { static struct perf_kmem perf_kmem = {
.sample = process_sample_event, .tool = {
.comm = perf_event__process_comm, .sample = process_sample_event,
.ordered_samples = true, .comm = perf_event__process_comm,
.ordered_samples = true,
},
}; };
static double fragmentation(unsigned long n_req, unsigned long n_alloc) static double fragmentation(unsigned long n_req, unsigned long n_alloc)
...@@ -486,11 +495,15 @@ static void sort_result(void) ...@@ -486,11 +495,15 @@ static void sort_result(void)
static int __cmd_kmem(void) static int __cmd_kmem(void)
{ {
int err = -EINVAL; int err = -EINVAL;
struct perf_session *session = perf_session__new(input_name, O_RDONLY, struct perf_session *session;
0, false, &perf_kmem);
session = perf_session__new(input_name, O_RDONLY, 0, false,
&perf_kmem.tool);
if (session == NULL) if (session == NULL)
return -ENOMEM; return -ENOMEM;
perf_kmem.session = session;
if (perf_session__create_kernel_maps(session) < 0) if (perf_session__create_kernel_maps(session) < 0)
goto out_delete; goto out_delete;
...@@ -498,7 +511,7 @@ static int __cmd_kmem(void) ...@@ -498,7 +511,7 @@ static int __cmd_kmem(void)
goto out_delete; goto out_delete;
setup_pager(); setup_pager();
err = perf_session__process_events(session, &perf_kmem); err = perf_session__process_events(session, &perf_kmem.tool);
if (err != 0) if (err != 0)
goto out_delete; goto out_delete;
sort_result(); sort_result();
......
...@@ -724,8 +724,8 @@ process_raw_event(void *data, int cpu, u64 timestamp, struct thread *thread) ...@@ -724,8 +724,8 @@ process_raw_event(void *data, int cpu, u64 timestamp, struct thread *thread)
struct event_format *event; struct event_format *event;
int type; int type;
type = trace_parse_common_type(data); type = trace_parse_common_type(session->pevent, data);
event = trace_find_event(type); event = pevent_find_event(session->pevent, type);
if (!strcmp(event->name, "lock_acquire")) if (!strcmp(event->name, "lock_acquire"))
process_lock_acquire_event(data, event, cpu, timestamp, thread); process_lock_acquire_event(data, event, cpu, timestamp, thread);
......
...@@ -43,6 +43,11 @@ static u64 sleep_measurement_overhead; ...@@ -43,6 +43,11 @@ static u64 sleep_measurement_overhead;
static unsigned long nr_tasks; static unsigned long nr_tasks;
struct perf_sched {
struct perf_tool tool;
struct perf_session *session;
};
struct sched_atom; struct sched_atom;
struct task_desc { struct task_desc {
...@@ -1597,6 +1602,8 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool, ...@@ -1597,6 +1602,8 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool,
struct perf_evsel *evsel, struct perf_evsel *evsel,
struct machine *machine) struct machine *machine)
{ {
struct perf_sched *sched = container_of(tool, struct perf_sched, tool);
struct pevent *pevent = sched->session->pevent;
struct thread *thread = machine__findnew_thread(machine, sample->pid); struct thread *thread = machine__findnew_thread(machine, sample->pid);
if (thread == NULL) { if (thread == NULL) {
...@@ -1612,7 +1619,8 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool, ...@@ -1612,7 +1619,8 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool,
tracepoint_handler f = evsel->handler.func; tracepoint_handler f = evsel->handler.func;
if (evsel->handler.data == NULL) if (evsel->handler.data == NULL)
evsel->handler.data = trace_find_event(evsel->attr.config); evsel->handler.data = pevent_find_event(pevent,
evsel->attr.config);
f(tool, evsel->handler.data, sample, machine, thread); f(tool, evsel->handler.data, sample, machine, thread);
} }
...@@ -1620,12 +1628,14 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool, ...@@ -1620,12 +1628,14 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool,
return 0; return 0;
} }
static struct perf_tool perf_sched = { static struct perf_sched perf_sched = {
.sample = perf_sched__process_tracepoint_sample, .tool = {
.comm = perf_event__process_comm, .sample = perf_sched__process_tracepoint_sample,
.lost = perf_event__process_lost, .comm = perf_event__process_comm,
.fork = perf_event__process_task, .lost = perf_event__process_lost,
.ordered_samples = true, .fork = perf_event__process_task,
.ordered_samples = true,
},
}; };
static void read_events(bool destroy, struct perf_session **psession) static void read_events(bool destroy, struct perf_session **psession)
...@@ -1640,16 +1650,20 @@ static void read_events(bool destroy, struct perf_session **psession) ...@@ -1640,16 +1650,20 @@ static void read_events(bool destroy, struct perf_session **psession)
{ "sched:sched_process_exit", process_sched_exit_event, }, { "sched:sched_process_exit", process_sched_exit_event, },
{ "sched:sched_migrate_task", process_sched_migrate_task_event, }, { "sched:sched_migrate_task", process_sched_migrate_task_event, },
}; };
struct perf_session *session = perf_session__new(input_name, O_RDONLY, struct perf_session *session;
0, false, &perf_sched);
session = perf_session__new(input_name, O_RDONLY, 0, false,
&perf_sched.tool);
if (session == NULL) if (session == NULL)
die("No Memory"); die("No Memory");
err = perf_evlist__set_tracepoints_handlers_array(session->evlist, handlers); perf_sched.session = session;
err = perf_session__set_tracepoints_handlers(session, handlers);
assert(err == 0); assert(err == 0);
if (perf_session__has_traces(session, "record -R")) { if (perf_session__has_traces(session, "record -R")) {
err = perf_session__process_events(session, &perf_sched); err = perf_session__process_events(session, &perf_sched.tool);
if (err) if (err)
die("Failed to process events, error %d", err); die("Failed to process events, error %d", err);
......
...@@ -28,6 +28,11 @@ static bool system_wide; ...@@ -28,6 +28,11 @@ static bool system_wide;
static const char *cpu_list; static const char *cpu_list;
static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
struct perf_script {
struct perf_tool tool;
struct perf_session *session;
};
enum perf_output_field { enum perf_output_field {
PERF_OUTPUT_COMM = 1U << 0, PERF_OUTPUT_COMM = 1U << 0,
PERF_OUTPUT_TID = 1U << 1, PERF_OUTPUT_TID = 1U << 1,
...@@ -257,7 +262,8 @@ static int perf_session__check_output_opt(struct perf_session *session) ...@@ -257,7 +262,8 @@ static int perf_session__check_output_opt(struct perf_session *session)
return 0; return 0;
} }
static void print_sample_start(struct perf_sample *sample, static void print_sample_start(struct pevent *pevent,
struct perf_sample *sample,
struct thread *thread, struct thread *thread,
struct perf_evsel *evsel) struct perf_evsel *evsel)
{ {
...@@ -302,8 +308,14 @@ static void print_sample_start(struct perf_sample *sample, ...@@ -302,8 +308,14 @@ static void print_sample_start(struct perf_sample *sample,
if (PRINT_FIELD(EVNAME)) { if (PRINT_FIELD(EVNAME)) {
if (attr->type == PERF_TYPE_TRACEPOINT) { if (attr->type == PERF_TYPE_TRACEPOINT) {
type = trace_parse_common_type(sample->raw_data); /*
event = trace_find_event(type); * XXX Do we really need this here?
* perf_evlist__set_tracepoint_names should have done
* this already
*/
type = trace_parse_common_type(pevent,
sample->raw_data);
event = pevent_find_event(pevent, type);
if (event) if (event)
evname = event->name; evname = event->name;
} else } else
...@@ -404,6 +416,7 @@ static void print_sample_bts(union perf_event *event, ...@@ -404,6 +416,7 @@ static void print_sample_bts(union perf_event *event,
} }
static void process_event(union perf_event *event __unused, static void process_event(union perf_event *event __unused,
struct pevent *pevent,
struct perf_sample *sample, struct perf_sample *sample,
struct perf_evsel *evsel, struct perf_evsel *evsel,
struct machine *machine, struct machine *machine,
...@@ -414,7 +427,7 @@ static void process_event(union perf_event *event __unused, ...@@ -414,7 +427,7 @@ static void process_event(union perf_event *event __unused,
if (output[attr->type].fields == 0) if (output[attr->type].fields == 0)
return; return;
print_sample_start(sample, thread, evsel); print_sample_start(pevent, sample, thread, evsel);
if (is_bts_event(attr)) { if (is_bts_event(attr)) {
print_sample_bts(event, sample, evsel, machine, thread); print_sample_bts(event, sample, evsel, machine, thread);
...@@ -422,7 +435,7 @@ static void process_event(union perf_event *event __unused, ...@@ -422,7 +435,7 @@ static void process_event(union perf_event *event __unused,
} }
if (PRINT_FIELD(TRACE)) if (PRINT_FIELD(TRACE))
print_trace_event(sample->cpu, sample->raw_data, print_trace_event(pevent, sample->cpu, sample->raw_data,
sample->raw_size); sample->raw_size);
if (PRINT_FIELD(ADDR)) if (PRINT_FIELD(ADDR))
...@@ -453,7 +466,8 @@ static int default_stop_script(void) ...@@ -453,7 +466,8 @@ static int default_stop_script(void)
return 0; return 0;
} }
static int default_generate_script(const char *outfile __unused) static int default_generate_script(struct pevent *pevent __unused,
const char *outfile __unused)
{ {
return 0; return 0;
} }
...@@ -491,6 +505,7 @@ static int process_sample_event(struct perf_tool *tool __used, ...@@ -491,6 +505,7 @@ static int process_sample_event(struct perf_tool *tool __used,
struct machine *machine) struct machine *machine)
{ {
struct addr_location al; struct addr_location al;
struct perf_script *scr = container_of(tool, struct perf_script, tool);
struct thread *thread = machine__findnew_thread(machine, event->ip.tid); struct thread *thread = machine__findnew_thread(machine, event->ip.tid);
if (thread == NULL) { if (thread == NULL) {
...@@ -522,24 +537,27 @@ static int process_sample_event(struct perf_tool *tool __used, ...@@ -522,24 +537,27 @@ static int process_sample_event(struct perf_tool *tool __used,
if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
return 0; return 0;
scripting_ops->process_event(event, sample, evsel, machine, thread); scripting_ops->process_event(event, scr->session->pevent,
sample, evsel, machine, thread);
evsel->hists.stats.total_period += sample->period; evsel->hists.stats.total_period += sample->period;
return 0; return 0;
} }
static struct perf_tool perf_script = { static struct perf_script perf_script = {
.sample = process_sample_event, .tool = {
.mmap = perf_event__process_mmap, .sample = process_sample_event,
.comm = perf_event__process_comm, .mmap = perf_event__process_mmap,
.exit = perf_event__process_task, .comm = perf_event__process_comm,
.fork = perf_event__process_task, .exit = perf_event__process_task,
.attr = perf_event__process_attr, .fork = perf_event__process_task,
.event_type = perf_event__process_event_type, .attr = perf_event__process_attr,
.tracing_data = perf_event__process_tracing_data, .event_type = perf_event__process_event_type,
.build_id = perf_event__process_build_id, .tracing_data = perf_event__process_tracing_data,
.ordered_samples = true, .build_id = perf_event__process_build_id,
.ordering_requires_timestamps = true, .ordered_samples = true,
.ordering_requires_timestamps = true,
},
}; };
extern volatile int session_done; extern volatile int session_done;
...@@ -555,7 +573,7 @@ static int __cmd_script(struct perf_session *session) ...@@ -555,7 +573,7 @@ static int __cmd_script(struct perf_session *session)
signal(SIGINT, sig_handler); signal(SIGINT, sig_handler);
ret = perf_session__process_events(session, &perf_script); ret = perf_session__process_events(session, &perf_script.tool);
if (debug_mode) if (debug_mode)
pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered); pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
...@@ -1337,10 +1355,13 @@ int cmd_script(int argc, const char **argv, const char *prefix __used) ...@@ -1337,10 +1355,13 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
if (!script_name) if (!script_name)
setup_pager(); setup_pager();
session = perf_session__new(input_name, O_RDONLY, 0, false, &perf_script); session = perf_session__new(input_name, O_RDONLY, 0, false,
&perf_script.tool);
if (session == NULL) if (session == NULL)
return -ENOMEM; return -ENOMEM;
perf_script.session = session;
if (cpu_list) { if (cpu_list) {
if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap)) if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap))
return -1; return -1;
...@@ -1386,7 +1407,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __used) ...@@ -1386,7 +1407,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
return -1; return -1;
} }
err = scripting_ops->generate_script("perf-script"); err = scripting_ops->generate_script(session->pevent,
"perf-script");
goto out; goto out;
} }
......
...@@ -224,8 +224,8 @@ int perf_evlist__add_tracepoints(struct perf_evlist *evlist, ...@@ -224,8 +224,8 @@ int perf_evlist__add_tracepoints(struct perf_evlist *evlist,
return err; return err;
} }
static struct perf_evsel * struct perf_evsel *
perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id) perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id)
{ {
struct perf_evsel *evsel; struct perf_evsel *evsel;
......
...@@ -73,6 +73,9 @@ int perf_evlist__set_tracepoints_handlers(struct perf_evlist *evlist, ...@@ -73,6 +73,9 @@ int perf_evlist__set_tracepoints_handlers(struct perf_evlist *evlist,
#define perf_evlist__set_tracepoints_handlers_array(evlist, array) \ #define perf_evlist__set_tracepoints_handlers_array(evlist, array) \
perf_evlist__set_tracepoints_handlers(evlist, array, ARRAY_SIZE(array)) perf_evlist__set_tracepoints_handlers(evlist, array, ARRAY_SIZE(array))
struct perf_evsel *
perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id);
void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel, void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel,
int cpu, int thread, u64 id); int cpu, int thread, u64 id);
......
...@@ -1474,15 +1474,15 @@ static int perf_header__read_build_ids(struct perf_header *header, ...@@ -1474,15 +1474,15 @@ static int perf_header__read_build_ids(struct perf_header *header,
static int process_tracing_data(struct perf_file_section *section __unused, static int process_tracing_data(struct perf_file_section *section __unused,
struct perf_header *ph __unused, struct perf_header *ph __unused,
int feat __unused, int fd) int feat __unused, int fd, void *data)
{ {
trace_report(fd, false); trace_report(fd, data, false);
return 0; return 0;
} }
static int process_build_id(struct perf_file_section *section, static int process_build_id(struct perf_file_section *section,
struct perf_header *ph, struct perf_header *ph,
int feat __unused, int fd) int feat __unused, int fd, void *data __used)
{ {
if (perf_header__read_build_ids(ph, fd, section->offset, section->size)) if (perf_header__read_build_ids(ph, fd, section->offset, section->size))
pr_debug("Failed to read buildids, continuing...\n"); pr_debug("Failed to read buildids, continuing...\n");
...@@ -1493,7 +1493,7 @@ struct feature_ops { ...@@ -1493,7 +1493,7 @@ struct feature_ops {
int (*write)(int fd, struct perf_header *h, struct perf_evlist *evlist); int (*write)(int fd, struct perf_header *h, struct perf_evlist *evlist);
void (*print)(struct perf_header *h, int fd, FILE *fp); void (*print)(struct perf_header *h, int fd, FILE *fp);
int (*process)(struct perf_file_section *section, int (*process)(struct perf_file_section *section,
struct perf_header *h, int feat, int fd); struct perf_header *h, int feat, int fd, void *data);
const char *name; const char *name;
bool full_only; bool full_only;
}; };
...@@ -1988,7 +1988,7 @@ int perf_file_header__read(struct perf_file_header *header, ...@@ -1988,7 +1988,7 @@ int perf_file_header__read(struct perf_file_header *header,
static int perf_file_section__process(struct perf_file_section *section, static int perf_file_section__process(struct perf_file_section *section,
struct perf_header *ph, struct perf_header *ph,
int feat, int fd, void *data __used) int feat, int fd, void *data)
{ {
if (lseek(fd, section->offset, SEEK_SET) == (off_t)-1) { if (lseek(fd, section->offset, SEEK_SET) == (off_t)-1) {
pr_debug("Failed to lseek to %" PRIu64 " offset for feature " pr_debug("Failed to lseek to %" PRIu64 " offset for feature "
...@@ -2004,7 +2004,7 @@ static int perf_file_section__process(struct perf_file_section *section, ...@@ -2004,7 +2004,7 @@ static int perf_file_section__process(struct perf_file_section *section,
if (!feat_ops[feat].process) if (!feat_ops[feat].process)
return 0; return 0;
return feat_ops[feat].process(section, ph, feat, fd); return feat_ops[feat].process(section, ph, feat, fd, data);
} }
static int perf_file_header__read_pipe(struct perf_pipe_file_header *header, static int perf_file_header__read_pipe(struct perf_pipe_file_header *header,
...@@ -2093,9 +2093,11 @@ static int read_attr(int fd, struct perf_header *ph, ...@@ -2093,9 +2093,11 @@ static int read_attr(int fd, struct perf_header *ph,
return ret <= 0 ? -1 : 0; return ret <= 0 ? -1 : 0;
} }
static int perf_evsel__set_tracepoint_name(struct perf_evsel *evsel) static int perf_evsel__set_tracepoint_name(struct perf_evsel *evsel,
struct pevent *pevent)
{ {
struct event_format *event = trace_find_event(evsel->attr.config); struct event_format *event = pevent_find_event(pevent,
evsel->attr.config);
char bf[128]; char bf[128];
if (event == NULL) if (event == NULL)
...@@ -2109,13 +2111,14 @@ static int perf_evsel__set_tracepoint_name(struct perf_evsel *evsel) ...@@ -2109,13 +2111,14 @@ static int perf_evsel__set_tracepoint_name(struct perf_evsel *evsel)
return 0; return 0;
} }
static int perf_evlist__set_tracepoint_names(struct perf_evlist *evlist) static int perf_evlist__set_tracepoint_names(struct perf_evlist *evlist,
struct pevent *pevent)
{ {
struct perf_evsel *pos; struct perf_evsel *pos;
list_for_each_entry(pos, &evlist->entries, node) { list_for_each_entry(pos, &evlist->entries, node) {
if (pos->attr.type == PERF_TYPE_TRACEPOINT && if (pos->attr.type == PERF_TYPE_TRACEPOINT &&
perf_evsel__set_tracepoint_name(pos)) perf_evsel__set_tracepoint_name(pos, pevent))
return -1; return -1;
} }
...@@ -2198,12 +2201,12 @@ int perf_session__read_header(struct perf_session *session, int fd) ...@@ -2198,12 +2201,12 @@ int perf_session__read_header(struct perf_session *session, int fd)
event_count = f_header.event_types.size / sizeof(struct perf_trace_event_type); event_count = f_header.event_types.size / sizeof(struct perf_trace_event_type);
} }
perf_header__process_sections(header, fd, NULL, perf_header__process_sections(header, fd, &session->pevent,
perf_file_section__process); perf_file_section__process);
lseek(fd, header->data_offset, SEEK_SET); lseek(fd, header->data_offset, SEEK_SET);
if (perf_evlist__set_tracepoint_names(session->evlist)) if (perf_evlist__set_tracepoint_names(session->evlist, session->pevent))
goto out_delete_evlist; goto out_delete_evlist;
header->frozen = 1; header->frozen = 1;
...@@ -2419,8 +2422,8 @@ int perf_event__process_tracing_data(union perf_event *event, ...@@ -2419,8 +2422,8 @@ int perf_event__process_tracing_data(union perf_event *event,
lseek(session->fd, offset + sizeof(struct tracing_data_event), lseek(session->fd, offset + sizeof(struct tracing_data_event),
SEEK_SET); SEEK_SET);
size_read = trace_report(session->fd, session->repipe); size_read = trace_report(session->fd, &session->pevent,
session->repipe);
padding = ALIGN(size_read, sizeof(u64)) - size_read; padding = ALIGN(size_read, sizeof(u64)) - size_read;
if (read(session->fd, buf, padding) < 0) if (read(session->fd, buf, padding) < 0)
......
...@@ -233,7 +233,8 @@ static void define_event_symbols(struct event_format *event, ...@@ -233,7 +233,8 @@ static void define_event_symbols(struct event_format *event,
define_event_symbols(event, ev_name, args->next); define_event_symbols(event, ev_name, args->next);
} }
static inline struct event_format *find_cache_event(int type) static inline
struct event_format *find_cache_event(struct pevent *pevent, int type)
{ {
static char ev_name[256]; static char ev_name[256];
struct event_format *event; struct event_format *event;
...@@ -241,7 +242,7 @@ static inline struct event_format *find_cache_event(int type) ...@@ -241,7 +242,7 @@ static inline struct event_format *find_cache_event(int type)
if (events[type]) if (events[type])
return events[type]; return events[type];
events[type] = event = trace_find_event(type); events[type] = event = pevent_find_event(pevent, type);
if (!event) if (!event)
return NULL; return NULL;
...@@ -252,7 +253,8 @@ static inline struct event_format *find_cache_event(int type) ...@@ -252,7 +253,8 @@ static inline struct event_format *find_cache_event(int type)
return event; return event;
} }
static void perl_process_tracepoint(union perf_event *pevent __unused, static void perl_process_tracepoint(union perf_event *perf_event __unused,
struct pevent *pevent,
struct perf_sample *sample, struct perf_sample *sample,
struct perf_evsel *evsel, struct perf_evsel *evsel,
struct machine *machine __unused, struct machine *machine __unused,
...@@ -275,13 +277,13 @@ static void perl_process_tracepoint(union perf_event *pevent __unused, ...@@ -275,13 +277,13 @@ static void perl_process_tracepoint(union perf_event *pevent __unused,
if (evsel->attr.type != PERF_TYPE_TRACEPOINT) if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
return; return;
type = trace_parse_common_type(data); type = trace_parse_common_type(pevent, data);
event = find_cache_event(type); event = find_cache_event(pevent, type);
if (!event) if (!event)
die("ug! no event found for type %d", type); die("ug! no event found for type %d", type);
pid = trace_parse_common_pid(data); pid = trace_parse_common_pid(pevent, data);
sprintf(handler, "%s::%s", event->system, event->name); sprintf(handler, "%s::%s", event->system, event->name);
...@@ -314,7 +316,8 @@ static void perl_process_tracepoint(union perf_event *pevent __unused, ...@@ -314,7 +316,8 @@ static void perl_process_tracepoint(union perf_event *pevent __unused,
offset = field->offset; offset = field->offset;
XPUSHs(sv_2mortal(newSVpv((char *)data + offset, 0))); XPUSHs(sv_2mortal(newSVpv((char *)data + offset, 0)));
} else { /* FIELD_IS_NUMERIC */ } else { /* FIELD_IS_NUMERIC */
val = read_size(data + field->offset, field->size); val = read_size(pevent, data + field->offset,
field->size);
if (field->flags & FIELD_IS_SIGNED) { if (field->flags & FIELD_IS_SIGNED) {
XPUSHs(sv_2mortal(newSViv(val))); XPUSHs(sv_2mortal(newSViv(val)));
} else { } else {
...@@ -368,14 +371,15 @@ static void perl_process_event_generic(union perf_event *pevent __unused, ...@@ -368,14 +371,15 @@ static void perl_process_event_generic(union perf_event *pevent __unused,
LEAVE; LEAVE;
} }
static void perl_process_event(union perf_event *pevent, static void perl_process_event(union perf_event *event,
struct pevent *pevent,
struct perf_sample *sample, struct perf_sample *sample,
struct perf_evsel *evsel, struct perf_evsel *evsel,
struct machine *machine, struct machine *machine,
struct thread *thread) struct thread *thread)
{ {
perl_process_tracepoint(pevent, sample, evsel, machine, thread); perl_process_tracepoint(event, pevent, sample, evsel, machine, thread);
perl_process_event_generic(pevent, sample, evsel, machine, thread); perl_process_event_generic(event, sample, evsel, machine, thread);
} }
static void run_start_sub(void) static void run_start_sub(void)
...@@ -448,7 +452,7 @@ static int perl_stop_script(void) ...@@ -448,7 +452,7 @@ static int perl_stop_script(void)
return 0; return 0;
} }
static int perl_generate_script(const char *outfile) static int perl_generate_script(struct pevent *pevent, const char *outfile)
{ {
struct event_format *event = NULL; struct event_format *event = NULL;
struct format_field *f; struct format_field *f;
...@@ -495,7 +499,7 @@ static int perl_generate_script(const char *outfile) ...@@ -495,7 +499,7 @@ static int perl_generate_script(const char *outfile)
fprintf(ofp, "sub trace_begin\n{\n\t# optional\n}\n\n"); fprintf(ofp, "sub trace_begin\n{\n\t# optional\n}\n\n");
fprintf(ofp, "sub trace_end\n{\n\t# optional\n}\n\n"); fprintf(ofp, "sub trace_end\n{\n\t# optional\n}\n\n");
while ((event = trace_find_next_event(event))) { while ((event = trace_find_next_event(pevent, event))) {
fprintf(ofp, "sub %s::%s\n{\n", event->system, event->name); fprintf(ofp, "sub %s::%s\n{\n", event->system, event->name);
fprintf(ofp, "\tmy ("); fprintf(ofp, "\tmy (");
......
...@@ -190,7 +190,8 @@ static void define_event_symbols(struct event_format *event, ...@@ -190,7 +190,8 @@ static void define_event_symbols(struct event_format *event,
define_event_symbols(event, ev_name, args->next); define_event_symbols(event, ev_name, args->next);
} }
static inline struct event_format *find_cache_event(int type) static inline
struct event_format *find_cache_event(struct pevent *pevent, int type)
{ {
static char ev_name[256]; static char ev_name[256];
struct event_format *event; struct event_format *event;
...@@ -198,7 +199,7 @@ static inline struct event_format *find_cache_event(int type) ...@@ -198,7 +199,7 @@ static inline struct event_format *find_cache_event(int type)
if (events[type]) if (events[type])
return events[type]; return events[type];
events[type] = event = trace_find_event(type); events[type] = event = pevent_find_event(pevent, type);
if (!event) if (!event)
return NULL; return NULL;
...@@ -209,7 +210,8 @@ static inline struct event_format *find_cache_event(int type) ...@@ -209,7 +210,8 @@ static inline struct event_format *find_cache_event(int type)
return event; return event;
} }
static void python_process_event(union perf_event *pevent __unused, static void python_process_event(union perf_event *perf_event __unused,
struct pevent *pevent,
struct perf_sample *sample, struct perf_sample *sample,
struct perf_evsel *evsel __unused, struct perf_evsel *evsel __unused,
struct machine *machine __unused, struct machine *machine __unused,
...@@ -233,13 +235,13 @@ static void python_process_event(union perf_event *pevent __unused, ...@@ -233,13 +235,13 @@ static void python_process_event(union perf_event *pevent __unused,
if (!t) if (!t)
Py_FatalError("couldn't create Python tuple"); Py_FatalError("couldn't create Python tuple");
type = trace_parse_common_type(data); type = trace_parse_common_type(pevent, data);
event = find_cache_event(type); event = find_cache_event(pevent, type);
if (!event) if (!event)
die("ug! no event found for type %d", type); die("ug! no event found for type %d", type);
pid = trace_parse_common_pid(data); pid = trace_parse_common_pid(pevent, data);
sprintf(handler_name, "%s__%s", event->system, event->name); sprintf(handler_name, "%s__%s", event->system, event->name);
...@@ -284,7 +286,8 @@ static void python_process_event(union perf_event *pevent __unused, ...@@ -284,7 +286,8 @@ static void python_process_event(union perf_event *pevent __unused,
offset = field->offset; offset = field->offset;
obj = PyString_FromString((char *)data + offset); obj = PyString_FromString((char *)data + offset);
} else { /* FIELD_IS_NUMERIC */ } else { /* FIELD_IS_NUMERIC */
val = read_size(data + field->offset, field->size); val = read_size(pevent, data + field->offset,
field->size);
if (field->flags & FIELD_IS_SIGNED) { if (field->flags & FIELD_IS_SIGNED) {
if ((long long)val >= LONG_MIN && if ((long long)val >= LONG_MIN &&
(long long)val <= LONG_MAX) (long long)val <= LONG_MAX)
...@@ -438,7 +441,7 @@ static int python_stop_script(void) ...@@ -438,7 +441,7 @@ static int python_stop_script(void)
return err; return err;
} }
static int python_generate_script(const char *outfile) static int python_generate_script(struct pevent *pevent, const char *outfile)
{ {
struct event_format *event = NULL; struct event_format *event = NULL;
struct format_field *f; struct format_field *f;
...@@ -487,7 +490,7 @@ static int python_generate_script(const char *outfile) ...@@ -487,7 +490,7 @@ static int python_generate_script(const char *outfile)
fprintf(ofp, "def trace_end():\n"); fprintf(ofp, "def trace_end():\n");
fprintf(ofp, "\tprint \"in trace_end\"\n\n"); fprintf(ofp, "\tprint \"in trace_end\"\n\n");
while ((event = trace_find_next_event(event))) { while ((event = trace_find_next_event(pevent, event))) {
fprintf(ofp, "def %s__%s(", event->system, event->name); fprintf(ofp, "def %s__%s(", event->system, event->name);
fprintf(ofp, "event_name, "); fprintf(ofp, "event_name, ");
fprintf(ofp, "context, "); fprintf(ofp, "context, ");
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "sort.h" #include "sort.h"
#include "util.h" #include "util.h"
#include "cpumap.h" #include "cpumap.h"
#include "event-parse.h"
static int perf_session__open(struct perf_session *self, bool force) static int perf_session__open(struct perf_session *self, bool force)
{ {
...@@ -1610,3 +1611,58 @@ void perf_session__fprintf_info(struct perf_session *session, FILE *fp, ...@@ -1610,3 +1611,58 @@ void perf_session__fprintf_info(struct perf_session *session, FILE *fp,
perf_header__fprintf_info(session, fp, full); perf_header__fprintf_info(session, fp, full);
fprintf(fp, "# ========\n#\n"); fprintf(fp, "# ========\n#\n");
} }
int __perf_session__set_tracepoints_handlers(struct perf_session *session,
const struct perf_evsel_str_handler *assocs,
size_t nr_assocs)
{
struct perf_evlist *evlist = session->evlist;
struct event_format *format;
struct perf_evsel *evsel;
char *tracepoint, *name;
size_t i;
int err;
for (i = 0; i < nr_assocs; i++) {
err = -ENOMEM;
tracepoint = strdup(assocs[i].name);
if (tracepoint == NULL)
goto out;
err = -ENOENT;
name = strchr(tracepoint, ':');
if (name == NULL)
goto out_free;
*name++ = '\0';
format = pevent_find_event_by_name(session->pevent,
tracepoint, name);
if (format == NULL) {
/*
* Adding a handler for an event not in the session,
* just ignore it.
*/
goto next;
}
evsel = perf_evlist__find_tracepoint_by_id(evlist, format->id);
if (evsel == NULL)
goto next;
err = -EEXIST;
if (evsel->handler.func != NULL)
goto out_free;
evsel->handler.func = assocs[i].handler;
next:
free(tracepoint);
}
err = 0;
out:
return err;
out_free:
free(tracepoint);
goto out;
}
...@@ -33,6 +33,7 @@ struct perf_session { ...@@ -33,6 +33,7 @@ struct perf_session {
struct machine host_machine; struct machine host_machine;
struct rb_root machines; struct rb_root machines;
struct perf_evlist *evlist; struct perf_evlist *evlist;
struct pevent *pevent;
/* /*
* FIXME: Need to split this up further, we need global * FIXME: Need to split this up further, we need global
* stats + per event stats. 'perf diff' also needs * stats + per event stats. 'perf diff' also needs
...@@ -158,4 +159,13 @@ int perf_session__cpu_bitmap(struct perf_session *session, ...@@ -158,4 +159,13 @@ int perf_session__cpu_bitmap(struct perf_session *session,
const char *cpu_list, unsigned long *cpu_bitmap); const char *cpu_list, unsigned long *cpu_bitmap);
void perf_session__fprintf_info(struct perf_session *s, FILE *fp, bool full); void perf_session__fprintf_info(struct perf_session *s, FILE *fp, bool full);
struct perf_evsel_str_handler;
int __perf_session__set_tracepoints_handlers(struct perf_session *session,
const struct perf_evsel_str_handler *assocs,
size_t nr_assocs);
#define perf_session__set_tracepoints_handlers(session, array) \
__perf_session__set_tracepoints_handlers(session, array, ARRAY_SIZE(array))
#endif /* __PERF_SESSION_H */ #endif /* __PERF_SESSION_H */
...@@ -32,29 +32,25 @@ int header_page_size_size; ...@@ -32,29 +32,25 @@ int header_page_size_size;
int header_page_ts_size; int header_page_ts_size;
int header_page_data_offset; int header_page_data_offset;
struct pevent *perf_pevent;
static struct pevent *pevent;
bool latency_format; bool latency_format;
int read_trace_init(int file_bigendian, int host_bigendian) struct pevent *read_trace_init(int file_bigendian, int host_bigendian)
{ {
if (pevent) struct pevent *pevent = pevent_alloc();
return 0;
perf_pevent = pevent_alloc();
pevent = perf_pevent;
pevent_set_flag(pevent, PEVENT_NSEC_OUTPUT); if (pevent != NULL) {
pevent_set_file_bigendian(pevent, file_bigendian); pevent_set_flag(pevent, PEVENT_NSEC_OUTPUT);
pevent_set_host_bigendian(pevent, host_bigendian); pevent_set_file_bigendian(pevent, file_bigendian);
pevent_set_host_bigendian(pevent, host_bigendian);
}
return 0; return pevent;
} }
static int get_common_field(struct scripting_context *context, static int get_common_field(struct scripting_context *context,
int *offset, int *size, const char *type) int *offset, int *size, const char *type)
{ {
struct pevent *pevent = context->pevent;
struct event_format *event; struct event_format *event;
struct format_field *field; struct format_field *field;
...@@ -150,7 +146,7 @@ void *raw_field_ptr(struct event_format *event, const char *name, void *data) ...@@ -150,7 +146,7 @@ void *raw_field_ptr(struct event_format *event, const char *name, void *data)
return data + field->offset; return data + field->offset;
} }
int trace_parse_common_type(void *data) int trace_parse_common_type(struct pevent *pevent, void *data)
{ {
struct pevent_record record; struct pevent_record record;
...@@ -158,7 +154,7 @@ int trace_parse_common_type(void *data) ...@@ -158,7 +154,7 @@ int trace_parse_common_type(void *data)
return pevent_data_type(pevent, &record); return pevent_data_type(pevent, &record);
} }
int trace_parse_common_pid(void *data) int trace_parse_common_pid(struct pevent *pevent, void *data)
{ {
struct pevent_record record; struct pevent_record record;
...@@ -166,27 +162,21 @@ int trace_parse_common_pid(void *data) ...@@ -166,27 +162,21 @@ int trace_parse_common_pid(void *data)
return pevent_data_pid(pevent, &record); return pevent_data_pid(pevent, &record);
} }
unsigned long long read_size(void *ptr, int size) unsigned long long read_size(struct pevent *pevent, void *ptr, int size)
{ {
return pevent_read_number(pevent, ptr, size); return pevent_read_number(pevent, ptr, size);
} }
struct event_format *trace_find_event(int type) void print_trace_event(struct pevent *pevent, int cpu, void *data, int size)
{
return pevent_find_event(pevent, type);
}
void print_trace_event(int cpu, void *data, int size)
{ {
struct event_format *event; struct event_format *event;
struct pevent_record record; struct pevent_record record;
struct trace_seq s; struct trace_seq s;
int type; int type;
type = trace_parse_common_type(data); type = trace_parse_common_type(pevent, data);
event = trace_find_event(type); event = pevent_find_event(pevent, type);
if (!event) { if (!event) {
warning("ug! no event found for type %d", type); warning("ug! no event found for type %d", type);
return; return;
...@@ -203,8 +193,8 @@ void print_trace_event(int cpu, void *data, int size) ...@@ -203,8 +193,8 @@ void print_trace_event(int cpu, void *data, int size)
printf("\n"); printf("\n");
} }
void print_event(int cpu, void *data, int size, unsigned long long nsecs, void print_event(struct pevent *pevent, int cpu, void *data, int size,
char *comm) unsigned long long nsecs, char *comm)
{ {
struct pevent_record record; struct pevent_record record;
struct trace_seq s; struct trace_seq s;
...@@ -227,7 +217,8 @@ void print_event(int cpu, void *data, int size, unsigned long long nsecs, ...@@ -227,7 +217,8 @@ void print_event(int cpu, void *data, int size, unsigned long long nsecs,
printf("\n"); printf("\n");
} }
void parse_proc_kallsyms(char *file, unsigned int size __unused) void parse_proc_kallsyms(struct pevent *pevent,
char *file, unsigned int size __unused)
{ {
unsigned long long addr; unsigned long long addr;
char *func; char *func;
...@@ -258,7 +249,8 @@ void parse_proc_kallsyms(char *file, unsigned int size __unused) ...@@ -258,7 +249,8 @@ void parse_proc_kallsyms(char *file, unsigned int size __unused)
} }
} }
void parse_ftrace_printk(char *file, unsigned int size __unused) void parse_ftrace_printk(struct pevent *pevent,
char *file, unsigned int size __unused)
{ {
unsigned long long addr; unsigned long long addr;
char *printk; char *printk;
...@@ -282,17 +274,19 @@ void parse_ftrace_printk(char *file, unsigned int size __unused) ...@@ -282,17 +274,19 @@ void parse_ftrace_printk(char *file, unsigned int size __unused)
} }
} }
int parse_ftrace_file(char *buf, unsigned long size) int parse_ftrace_file(struct pevent *pevent, char *buf, unsigned long size)
{ {
return pevent_parse_event(pevent, buf, size, "ftrace"); return pevent_parse_event(pevent, buf, size, "ftrace");
} }
int parse_event_file(char *buf, unsigned long size, char *sys) int parse_event_file(struct pevent *pevent,
char *buf, unsigned long size, char *sys)
{ {
return pevent_parse_event(pevent, buf, size, sys); return pevent_parse_event(pevent, buf, size, sys);
} }
struct event_format *trace_find_next_event(struct event_format *event) struct event_format *trace_find_next_event(struct pevent *pevent,
struct event_format *event)
{ {
static int idx; static int idx;
......
...@@ -114,20 +114,20 @@ static void skip(int size) ...@@ -114,20 +114,20 @@ static void skip(int size)
}; };
} }
static unsigned int read4(void) static unsigned int read4(struct pevent *pevent)
{ {
unsigned int data; unsigned int data;
read_or_die(&data, 4); read_or_die(&data, 4);
return __data2host4(perf_pevent, data); return __data2host4(pevent, data);
} }
static unsigned long long read8(void) static unsigned long long read8(struct pevent *pevent)
{ {
unsigned long long data; unsigned long long data;
read_or_die(&data, 8); read_or_die(&data, 8);
return __data2host8(perf_pevent, data); return __data2host8(pevent, data);
} }
static char *read_string(void) static char *read_string(void)
...@@ -168,12 +168,12 @@ static char *read_string(void) ...@@ -168,12 +168,12 @@ static char *read_string(void)
return str; return str;
} }
static void read_proc_kallsyms(void) static void read_proc_kallsyms(struct pevent *pevent)
{ {
unsigned int size; unsigned int size;
char *buf; char *buf;
size = read4(); size = read4(pevent);
if (!size) if (!size)
return; return;
...@@ -181,29 +181,29 @@ static void read_proc_kallsyms(void) ...@@ -181,29 +181,29 @@ static void read_proc_kallsyms(void)
read_or_die(buf, size); read_or_die(buf, size);
buf[size] = '\0'; buf[size] = '\0';
parse_proc_kallsyms(buf, size); parse_proc_kallsyms(pevent, buf, size);
free(buf); free(buf);
} }
static void read_ftrace_printk(void) static void read_ftrace_printk(struct pevent *pevent)
{ {
unsigned int size; unsigned int size;
char *buf; char *buf;
size = read4(); size = read4(pevent);
if (!size) if (!size)
return; return;
buf = malloc_or_die(size); buf = malloc_or_die(size);
read_or_die(buf, size); read_or_die(buf, size);
parse_ftrace_printk(buf, size); parse_ftrace_printk(pevent, buf, size);
free(buf); free(buf);
} }
static void read_header_files(void) static void read_header_files(struct pevent *pevent)
{ {
unsigned long long size; unsigned long long size;
char *header_event; char *header_event;
...@@ -214,7 +214,7 @@ static void read_header_files(void) ...@@ -214,7 +214,7 @@ static void read_header_files(void)
if (memcmp(buf, "header_page", 12) != 0) if (memcmp(buf, "header_page", 12) != 0)
die("did not read header page"); die("did not read header page");
size = read8(); size = read8(pevent);
skip(size); skip(size);
/* /*
...@@ -227,47 +227,48 @@ static void read_header_files(void) ...@@ -227,47 +227,48 @@ static void read_header_files(void)
if (memcmp(buf, "header_event", 13) != 0) if (memcmp(buf, "header_event", 13) != 0)
die("did not read header event"); die("did not read header event");
size = read8(); size = read8(pevent);
header_event = malloc_or_die(size); header_event = malloc_or_die(size);
read_or_die(header_event, size); read_or_die(header_event, size);
free(header_event); free(header_event);
} }
static void read_ftrace_file(unsigned long long size) static void read_ftrace_file(struct pevent *pevent, unsigned long long size)
{ {
char *buf; char *buf;
buf = malloc_or_die(size); buf = malloc_or_die(size);
read_or_die(buf, size); read_or_die(buf, size);
parse_ftrace_file(buf, size); parse_ftrace_file(pevent, buf, size);
free(buf); free(buf);
} }
static void read_event_file(char *sys, unsigned long long size) static void read_event_file(struct pevent *pevent, char *sys,
unsigned long long size)
{ {
char *buf; char *buf;
buf = malloc_or_die(size); buf = malloc_or_die(size);
read_or_die(buf, size); read_or_die(buf, size);
parse_event_file(buf, size, sys); parse_event_file(pevent, buf, size, sys);
free(buf); free(buf);
} }
static void read_ftrace_files(void) static void read_ftrace_files(struct pevent *pevent)
{ {
unsigned long long size; unsigned long long size;
int count; int count;
int i; int i;
count = read4(); count = read4(pevent);
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
size = read8(); size = read8(pevent);
read_ftrace_file(size); read_ftrace_file(pevent, size);
} }
} }
static void read_event_files(void) static void read_event_files(struct pevent *pevent)
{ {
unsigned long long size; unsigned long long size;
char *sys; char *sys;
...@@ -275,15 +276,15 @@ static void read_event_files(void) ...@@ -275,15 +276,15 @@ static void read_event_files(void)
int count; int count;
int i,x; int i,x;
systems = read4(); systems = read4(pevent);
for (i = 0; i < systems; i++) { for (i = 0; i < systems; i++) {
sys = read_string(); sys = read_string();
count = read4(); count = read4(pevent);
for (x=0; x < count; x++) { for (x=0; x < count; x++) {
size = read8(); size = read8(pevent);
read_event_file(sys, size); read_event_file(pevent, sys, size);
} }
} }
} }
...@@ -377,7 +378,7 @@ static int calc_index(void *ptr, int cpu) ...@@ -377,7 +378,7 @@ static int calc_index(void *ptr, int cpu)
return (unsigned long)ptr - (unsigned long)cpu_data[cpu].page; return (unsigned long)ptr - (unsigned long)cpu_data[cpu].page;
} }
struct pevent_record *trace_peek_data(int cpu) struct pevent_record *trace_peek_data(struct pevent *pevent, int cpu)
{ {
struct pevent_record *data; struct pevent_record *data;
void *page = cpu_data[cpu].page; void *page = cpu_data[cpu].page;
...@@ -399,15 +400,15 @@ struct pevent_record *trace_peek_data(int cpu) ...@@ -399,15 +400,15 @@ struct pevent_record *trace_peek_data(int cpu)
/* FIXME: handle header page */ /* FIXME: handle header page */
if (header_page_ts_size != 8) if (header_page_ts_size != 8)
die("expected a long long type for timestamp"); die("expected a long long type for timestamp");
cpu_data[cpu].timestamp = data2host8(perf_pevent, ptr); cpu_data[cpu].timestamp = data2host8(pevent, ptr);
ptr += 8; ptr += 8;
switch (header_page_size_size) { switch (header_page_size_size) {
case 4: case 4:
cpu_data[cpu].page_size = data2host4(perf_pevent, ptr); cpu_data[cpu].page_size = data2host4(pevent, ptr);
ptr += 4; ptr += 4;
break; break;
case 8: case 8:
cpu_data[cpu].page_size = data2host8(perf_pevent, ptr); cpu_data[cpu].page_size = data2host8(pevent, ptr);
ptr += 8; ptr += 8;
break; break;
default: default:
...@@ -421,10 +422,10 @@ struct pevent_record *trace_peek_data(int cpu) ...@@ -421,10 +422,10 @@ struct pevent_record *trace_peek_data(int cpu)
if (idx >= cpu_data[cpu].page_size) { if (idx >= cpu_data[cpu].page_size) {
get_next_page(cpu); get_next_page(cpu);
return trace_peek_data(cpu); return trace_peek_data(pevent, cpu);
} }
type_len_ts = data2host4(perf_pevent, ptr); type_len_ts = data2host4(pevent, ptr);
ptr += 4; ptr += 4;
type_len = type_len4host(type_len_ts); type_len = type_len4host(type_len_ts);
...@@ -434,14 +435,14 @@ struct pevent_record *trace_peek_data(int cpu) ...@@ -434,14 +435,14 @@ struct pevent_record *trace_peek_data(int cpu)
case RINGBUF_TYPE_PADDING: case RINGBUF_TYPE_PADDING:
if (!delta) if (!delta)
die("error, hit unexpected end of page"); die("error, hit unexpected end of page");
length = data2host4(perf_pevent, ptr); length = data2host4(pevent, ptr);
ptr += 4; ptr += 4;
length *= 4; length *= 4;
ptr += length; ptr += length;
goto read_again; goto read_again;
case RINGBUF_TYPE_TIME_EXTEND: case RINGBUF_TYPE_TIME_EXTEND:
extend = data2host4(perf_pevent, ptr); extend = data2host4(pevent, ptr);
ptr += 4; ptr += 4;
extend <<= TS_SHIFT; extend <<= TS_SHIFT;
extend += delta; extend += delta;
...@@ -452,7 +453,7 @@ struct pevent_record *trace_peek_data(int cpu) ...@@ -452,7 +453,7 @@ struct pevent_record *trace_peek_data(int cpu)
ptr += 12; ptr += 12;
break; break;
case 0: case 0:
length = data2host4(perf_pevent, ptr); length = data2host4(pevent, ptr);
ptr += 4; ptr += 4;
die("here! length=%d", length); die("here! length=%d", length);
break; break;
...@@ -477,17 +478,17 @@ struct pevent_record *trace_peek_data(int cpu) ...@@ -477,17 +478,17 @@ struct pevent_record *trace_peek_data(int cpu)
return data; return data;
} }
struct pevent_record *trace_read_data(int cpu) struct pevent_record *trace_read_data(struct pevent *pevent, int cpu)
{ {
struct pevent_record *data; struct pevent_record *data;
data = trace_peek_data(cpu); data = trace_peek_data(pevent, cpu);
cpu_data[cpu].next = NULL; cpu_data[cpu].next = NULL;
return data; return data;
} }
ssize_t trace_report(int fd, bool __repipe) ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe)
{ {
char buf[BUFSIZ]; char buf[BUFSIZ];
char test[] = { 23, 8, 68 }; char test[] = { 23, 8, 68 };
...@@ -519,30 +520,32 @@ ssize_t trace_report(int fd, bool __repipe) ...@@ -519,30 +520,32 @@ ssize_t trace_report(int fd, bool __repipe)
file_bigendian = buf[0]; file_bigendian = buf[0];
host_bigendian = bigendian(); host_bigendian = bigendian();
read_trace_init(file_bigendian, host_bigendian); *ppevent = read_trace_init(file_bigendian, host_bigendian);
if (*ppevent == NULL)
die("read_trace_init failed");
read_or_die(buf, 1); read_or_die(buf, 1);
long_size = buf[0]; long_size = buf[0];
page_size = read4(); page_size = read4(*ppevent);
read_header_files(); read_header_files(*ppevent);
read_ftrace_files(); read_ftrace_files(*ppevent);
read_event_files(); read_event_files(*ppevent);
read_proc_kallsyms(); read_proc_kallsyms(*ppevent);
read_ftrace_printk(); read_ftrace_printk(*ppevent);
size = calc_data_size - 1; size = calc_data_size - 1;
calc_data_size = 0; calc_data_size = 0;
repipe = false; repipe = false;
if (show_funcs) { if (show_funcs) {
pevent_print_funcs(perf_pevent); pevent_print_funcs(*ppevent);
return size; return size;
} }
if (show_printk) { if (show_printk) {
pevent_print_printk(perf_pevent); pevent_print_printk(*ppevent);
return size; return size;
} }
......
...@@ -36,6 +36,7 @@ static int stop_script_unsupported(void) ...@@ -36,6 +36,7 @@ static int stop_script_unsupported(void)
} }
static void process_event_unsupported(union perf_event *event __unused, static void process_event_unsupported(union perf_event *event __unused,
struct pevent *pevent __unused,
struct perf_sample *sample __unused, struct perf_sample *sample __unused,
struct perf_evsel *evsel __unused, struct perf_evsel *evsel __unused,
struct machine *machine __unused, struct machine *machine __unused,
...@@ -61,7 +62,8 @@ static int python_start_script_unsupported(const char *script __unused, ...@@ -61,7 +62,8 @@ static int python_start_script_unsupported(const char *script __unused,
return -1; return -1;
} }
static int python_generate_script_unsupported(const char *outfile __unused) static int python_generate_script_unsupported(struct pevent *pevent __unused,
const char *outfile __unused)
{ {
print_python_unsupported_msg(); print_python_unsupported_msg();
...@@ -122,7 +124,8 @@ static int perl_start_script_unsupported(const char *script __unused, ...@@ -122,7 +124,8 @@ static int perl_start_script_unsupported(const char *script __unused,
return -1; return -1;
} }
static int perl_generate_script_unsupported(const char *outfile __unused) static int perl_generate_script_unsupported(struct pevent *pevent __unused,
const char *outfile __unused)
{ {
print_perl_unsupported_msg(); print_perl_unsupported_msg();
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
struct machine; struct machine;
struct perf_sample; struct perf_sample;
union perf_event; union perf_event;
struct perf_tool;
struct thread; struct thread;
extern int header_page_size_size; extern int header_page_size_size;
...@@ -29,35 +30,36 @@ enum { ...@@ -29,35 +30,36 @@ enum {
int bigendian(void); int bigendian(void);
int read_trace_init(int file_bigendian, int host_bigendian); struct pevent *read_trace_init(int file_bigendian, int host_bigendian);
void print_trace_event(int cpu, void *data, int size); void print_trace_event(struct pevent *pevent, int cpu, void *data, int size);
void print_event(int cpu, void *data, int size, unsigned long long nsecs, void print_event(struct pevent *pevent, int cpu, void *data, int size,
char *comm); unsigned long long nsecs, char *comm);
int parse_ftrace_file(char *buf, unsigned long size); int parse_ftrace_file(struct pevent *pevent, char *buf, unsigned long size);
int parse_event_file(char *buf, unsigned long size, char *sys); int parse_event_file(struct pevent *pevent,
char *buf, unsigned long size, char *sys);
struct pevent_record *trace_peek_data(int cpu); struct pevent_record *trace_peek_data(struct pevent *pevent, int cpu);
struct event_format *trace_find_event(int type);
unsigned long long unsigned long long
raw_field_value(struct event_format *event, const char *name, void *data); raw_field_value(struct event_format *event, const char *name, void *data);
void *raw_field_ptr(struct event_format *event, const char *name, void *data); void *raw_field_ptr(struct event_format *event, const char *name, void *data);
void parse_proc_kallsyms(char *file, unsigned int size __unused); void parse_proc_kallsyms(struct pevent *pevent, char *file, unsigned int size);
void parse_ftrace_printk(char *file, unsigned int size __unused); void parse_ftrace_printk(struct pevent *pevent, char *file, unsigned int size);
ssize_t trace_report(int fd, bool repipe); ssize_t trace_report(int fd, struct pevent **pevent, bool repipe);
int trace_parse_common_type(void *data); int trace_parse_common_type(struct pevent *pevent, void *data);
int trace_parse_common_pid(void *data); int trace_parse_common_pid(struct pevent *pevent, void *data);
struct event_format *trace_find_next_event(struct event_format *event); struct event_format *trace_find_next_event(struct pevent *pevent,
unsigned long long read_size(void *ptr, int size); struct event_format *event);
unsigned long long read_size(struct pevent *pevent, void *ptr, int size);
unsigned long long eval_flag(const char *flag); unsigned long long eval_flag(const char *flag);
struct pevent_record *trace_read_data(int cpu); struct pevent_record *trace_read_data(struct pevent *pevent, int cpu);
int read_tracing_data(int fd, struct list_head *pattrs); int read_tracing_data(int fd, struct list_head *pattrs);
struct tracing_data { struct tracing_data {
...@@ -77,11 +79,12 @@ struct scripting_ops { ...@@ -77,11 +79,12 @@ struct scripting_ops {
int (*start_script) (const char *script, int argc, const char **argv); int (*start_script) (const char *script, int argc, const char **argv);
int (*stop_script) (void); int (*stop_script) (void);
void (*process_event) (union perf_event *event, void (*process_event) (union perf_event *event,
struct pevent *pevent,
struct perf_sample *sample, struct perf_sample *sample,
struct perf_evsel *evsel, struct perf_evsel *evsel,
struct machine *machine, struct machine *machine,
struct thread *thread); struct thread *thread);
int (*generate_script) (const char *outfile); int (*generate_script) (struct pevent *pevent, const char *outfile);
}; };
int script_spec_register(const char *spec, struct scripting_ops *ops); int script_spec_register(const char *spec, struct scripting_ops *ops);
...@@ -90,6 +93,7 @@ void setup_perl_scripting(void); ...@@ -90,6 +93,7 @@ void setup_perl_scripting(void);
void setup_python_scripting(void); void setup_python_scripting(void);
struct scripting_context { struct scripting_context {
struct pevent *pevent;
void *event_data; void *event_data;
}; };
......
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