summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Pihet <jean.pihet@linaro.org>2014-10-10 11:34:45 +0200
committerBorislav Petkov <bp@suse.de>2014-11-06 11:58:22 +0100
commitd6732065acbda5a2a9a2c23b3b47ab482cef7e94 (patch)
tree10ee523e6fdbb5184fcc66a83f95802e396b3c0d
parent004be0fda1743c894350a623c70e8c0517c67818 (diff)
downloadrasd-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.h10
-rw-r--r--src/Makefile2
-rw-r--r--src/evsel.c3
-rw-r--r--src/trace_event.c84
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);
+}