diff mbox

[RFC,v3,3/4] trace: Introduce trace log output function for STM

Message ID ad3eec9e2817e3bea49104a820337c0554e7db81.1436262902.git.zhang.chunyan@linaro.org
State New
Headers show

Commit Message

Chunyan Zhang July 7, 2015, 10:10 a.m. UTC
This patch introduced a few functions to print the event trace log to
STM buffer when the trace event happened and the event information
was committed to ring buffer.

Before outputting the trace log to STM, we have to get the human readable
trace log content and print it into a local buffer in the format of a
string, the function 'trace_event_buf_vprintf()' is just for this purpose.

Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
---
 kernel/trace/Makefile           |  1 +
 kernel/trace/trace_output_stm.c | 99 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 100 insertions(+)
 create mode 100644 kernel/trace/trace_output_stm.c
diff mbox

Patch

diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
index 9b1044e..002de34 100644
--- a/kernel/trace/Makefile
+++ b/kernel/trace/Makefile
@@ -67,4 +67,5 @@  obj-$(CONFIG_UPROBE_EVENT) += trace_uprobe.o
 
 obj-$(CONFIG_TRACEPOINT_BENCHMARK) += trace_benchmark.o
 
+obj-$(CONFIG_STM_TRACE_EVENT) += trace_output_stm.o
 libftrace-y := ftrace.o
diff --git a/kernel/trace/trace_output_stm.c b/kernel/trace/trace_output_stm.c
new file mode 100644
index 0000000..689c6d5
--- /dev/null
+++ b/kernel/trace/trace_output_stm.c
@@ -0,0 +1,99 @@ 
+#include <linux/trace_events.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include "trace.h"
+
+#define STM_OUTPUT_STRLEN 128
+
+/* store the event trace log for STM */
+struct trace_buffer_stm {
+	char buffer[STM_OUTPUT_STRLEN];
+	unsigned int used_len;
+	unsigned int size;
+};
+
+static struct trace_buffer_stm *trace_event_stm_buffer;
+static struct trace_seq *stm_tmp_seq;
+static int stm_buffers_allocated;
+
+void trace_event_buf_vprintf(struct trace_buffer_stm *tb, const char *fmt, ...)
+{
+	va_list ap;
+	char *buffer = tb->buffer + tb->used_len;
+	unsigned int size = tb->size - tb->used_len;
+
+	va_start(ap, fmt);
+	tb->used_len += vsnprintf(buffer, size, fmt, ap);
+	va_end(ap);
+}
+EXPORT_SYMBOL_GPL(trace_event_buf_vprintf);
+
+static inline void stm_buf_reset(struct trace_buffer_stm *tb)
+{
+	tb->used_len = 0;
+}
+
+void trace_event_stm_log(struct trace_event_buffer *buffer)
+{
+
+	struct trace_seq *p = stm_tmp_seq;
+	struct trace_buffer_stm *tb;
+	struct trace_event_call *event_call = buffer->trace_file->event_call;
+	struct trace_entry *entry = (struct trace_entry *)buffer->entry;
+
+	if (!stm_buffers_allocated)
+		return;
+
+	tb = trace_event_stm_buffer;
+
+	if (event_call->output_stm)
+		event_call->output_stm(p, entry, tb);
+
+	stm_trace_event_write(tb->buffer, tb->used_len);
+
+	stm_buf_reset(tb);
+}
+EXPORT_SYMBOL_GPL(trace_event_stm_log);
+
+static int alloc_stm_tmp_seq(void)
+{
+	struct trace_seq *seq;
+
+	seq = kzalloc(sizeof(struct trace_seq), GFP_KERNEL);
+	if (!seq)
+		return -ENOMEM;
+
+	stm_tmp_seq = seq;
+
+	return 0;
+}
+
+static int alloc_stm_trace_buffer(void)
+{
+	struct trace_buffer_stm *buffer;
+
+	buffer = kzalloc(sizeof(struct trace_buffer_stm), GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	buffer->used_len = 0;
+	buffer->size = ARRAY_SIZE(buffer->buffer);
+
+	trace_event_stm_buffer = buffer;
+
+	return 0;
+}
+
+static __init int trace_stm_init_buffers(void)
+{
+	if (alloc_stm_trace_buffer())
+		return -ENOMEM;
+
+	if (alloc_stm_tmp_seq())
+		return -ENOMEM;
+
+	stm_buffers_allocated = 1;
+
+	return 0;
+}
+fs_initcall(trace_stm_init_buffers);