diff options
author | Jean Pihet <jean.pihet@linaro.org> | 2014-10-10 11:34:45 +0200 |
---|---|---|
committer | Borislav Petkov <bp@suse.de> | 2014-11-06 11:58:22 +0100 |
commit | d6732065acbda5a2a9a2c23b3b47ab482cef7e94 (patch) | |
tree | 10ee523e6fdbb5184fcc66a83f95802e396b3c0d | |
parent | 004be0fda1743c894350a623c70e8c0517c67818 (diff) | |
download | rasd-d6732065acbda5a2a9a2c23b3b47ab482cef7e94.tar.gz |
rasd: Add event format parsing
Parse the events format from debugfs entry, i.e.
(debugfs)/tracing/events/<sys>/<name>/format.
Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
Link: http://lkml.kernel.org/r/1412933690-25576-9-git-send-email-jean.pihet@linaro.org
Signed-off-by: Borislav Petkov <bp@suse.de>
-rw-r--r-- | include/trace_event.h | 10 | ||||
-rw-r--r-- | src/Makefile | 2 | ||||
-rw-r--r-- | src/evsel.c | 3 | ||||
-rw-r--r-- | src/trace_event.c | 84 |
4 files changed, 97 insertions, 2 deletions
diff --git a/include/trace_event.h b/include/trace_event.h new file mode 100644 index 0000000..83cefdb --- /dev/null +++ b/include/trace_event.h @@ -0,0 +1,10 @@ +#include <linux/perf_event.h> + +#include "ras.h" + +struct trace_event { + struct pevent *pevent; + struct plugin_list *plugin_list; +}; + +struct event_format *trace_event__tp_format(const char *sys, const char *name); diff --git a/src/Makefile b/src/Makefile index 523e8ef..fa0aee6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -34,6 +34,7 @@ HEADERS += $(HPFX)/strlist.h HEADERS += $(HPFX)/symbol.h HEADERS += $(HPFX)/target.h HEADERS += $(HPFX)/thread_map.h +HEADERS += $(HPFX)/trace_event.h HEADERS += $(HPFX)/trace_seq.h HEADERS += $(HPFX)/xyarray.h @@ -51,6 +52,7 @@ OBJS += rblist.o OBJS += rbtree.o OBJS += strlist.o OBJS += thread_map.o +OBJS += trace_event.o OBJS += trace-seq.o OBJS += util.o OBJS += xyarray.o diff --git a/src/evsel.c b/src/evsel.c index ef4e888..8e46e8f 100644 --- a/src/evsel.c +++ b/src/evsel.c @@ -2,6 +2,7 @@ #include "cpumap.h" #include "debug.h" #include "evsel.h" +#include "trace_event.h" #include "xyarray.h" int __perf_evsel__sample_size(u64 sample_type) @@ -176,11 +177,9 @@ struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int if (asprintf(&evsel->name, "%s:%s", sys, name) < 0) goto out_free; - /* evsel->tp_format = trace_event__tp_format(sys, name); if (evsel->tp_format == NULL) goto out_free; - */ event_attr_init(&attr); /* diff --git a/src/trace_event.c b/src/trace_event.c new file mode 100644 index 0000000..5ea2556 --- /dev/null +++ b/src/trace_event.c @@ -0,0 +1,84 @@ +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/types.h> +#include <fcntl.h> +#include <linux/kernel.h> + +#include "event-parse.h" +#include "trace_event.h" + +#define PATH_MAX 4096 + +char tracing_events_path[PATH_MAX + 1] = "/sys/kernel/debug/tracing/events"; + +/* + * global trace_event object used by trace_event__tp_format + * + * TODO There's no cleanup call for this. Add some sort of + * __exit function support and call trace_event__cleanup + * there. + */ +static struct trace_event tevent; + +int trace_event__init(struct trace_event *t) +{ + struct pevent *pevent = pevent_alloc(); + + if (pevent) { + /*t->plugin_list = traceevent_load_plugins(pevent);*/ + t->pevent = pevent; + } + + return pevent ? 0 : -1; +} + +void trace_event__cleanup(struct trace_event *t) +{ + /*traceevent_unload_plugins(t->plugin_list, t->pevent);*/ + pevent_free(t->pevent); +} + +static struct event_format* +tp_format(const char *sys, const char *name) +{ + struct pevent *pevent = tevent.pevent; + struct event_format *event = NULL; + char path[PATH_MAX]; + size_t size; + char *data; + + scnprintf(path, PATH_MAX, "%s/%s/%s/format", + tracing_events_path, sys, name); + + if (filename__read_str(path, &data, &size)) + return NULL; + + pevent_parse_format(pevent, &event, data, size, sys); + + free(data); + return event; +} + +struct event_format* +trace_event__tp_format(const char *sys, const char *name) +{ + static bool initialized; + + if (!initialized) { + int be = traceevent_host_bigendian(); + struct pevent *pevent; + + if (trace_event__init(&tevent)) + return NULL; + + pevent = tevent.pevent; + pevent_set_flag(pevent, PEVENT_NSEC_OUTPUT); + pevent_set_file_bigendian(pevent, be); + pevent_set_host_bigendian(pevent, be); + initialized = true; + } + + return tp_format(sys, name); +} |