[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1435719455-91155-3-git-send-email-hekuang@huawei.com>
Date: Wed, 1 Jul 2015 02:57:32 +0000
From: He Kuang <hekuang@...wei.com>
To: <ast@...mgrid.com>, <rostedt@...dmis.org>,
<masami.hiramatsu.pt@...achi.com>, <mingo@...hat.com>,
<acme@...hat.com>, <a.p.zijlstra@...llo.nl>, <jolsa@...nel.org>,
<namhyung@...nel.org>
CC: <wangnan0@...wei.com>, <linux-kernel@...r.kernel.org>
Subject: [RFC PATCH 2/5] perf/trace: Add perf extra percpu trace buffer
Introduce another trace buffer besides perf_trace_buffer, so other
utilities like bpf can generate and fill perf event data to it
extraly and the data can be collected to the original buffer
afterwards. The life cycle of this extra buffer is the same as the
original one.
Signed-off-by: He Kuang <hekuang@...wei.com>
---
include/linux/ftrace_event.h | 5 ++++-
kernel/trace/trace_event_perf.c | 46 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index f9ecf63..b6cf5a3 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -411,7 +411,8 @@ struct ftrace_event_file {
} \
early_initcall(trace_init_perf_perm_##name);
-#define PERF_MAX_TRACE_SIZE 2048
+#define PERF_MAX_TRACE_SIZE 2048
+#define PERF_MAX_EXTRA_TRACE_SIZE 128
#define MAX_FILTER_STR_VAL 256 /* Should handle KSYM_SYMBOL_LEN */
@@ -614,6 +615,8 @@ extern int ftrace_profile_set_filter(struct perf_event *event, int event_id,
extern void ftrace_profile_free_filter(struct perf_event *event);
extern void *perf_trace_buf_prepare(int size, unsigned short type,
struct pt_regs **regs, int *rctxp);
+extern void *perf_extra_trace_buf_prepare(int size, int rctx);
+extern void *get_perf_extra_trace_buf(int rctx);
static inline void
perf_trace_buf_submit(void *raw_data, int size, int rctx, u64 addr,
diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c
index 6fa484d..603b3da 100644
--- a/kernel/trace/trace_event_perf.c
+++ b/kernel/trace/trace_event_perf.c
@@ -10,6 +10,7 @@
#include "trace.h"
static char __percpu *perf_trace_buf[PERF_NR_CONTEXTS];
+static char __percpu *perf_extra_trace_buf[PERF_NR_CONTEXTS];
/*
* Force it to be aligned to unsigned long to avoid misaligned accesses
@@ -18,6 +19,10 @@ static char __percpu *perf_trace_buf[PERF_NR_CONTEXTS];
typedef typeof(unsigned long [PERF_MAX_TRACE_SIZE / sizeof(unsigned long)])
perf_trace_t;
+typedef
+typeof(unsigned long [PERF_MAX_EXTRA_TRACE_SIZE / sizeof(unsigned long)])
+ perf_extra_trace_t;
+
/* Count the events in use (per event id, not per instance) */
static int total_ref_count;
@@ -113,6 +118,13 @@ static int perf_trace_event_reg(struct ftrace_event_call *tp_event,
goto fail;
perf_trace_buf[i] = buf;
+
+ buf = (char __percpu *)
+ alloc_percpu(perf_extra_trace_t);
+ if (!buf)
+ goto fail;
+
+ perf_extra_trace_buf[i] = buf;
}
}
@@ -130,6 +142,9 @@ fail:
for (i = 0; i < PERF_NR_CONTEXTS; i++) {
free_percpu(perf_trace_buf[i]);
perf_trace_buf[i] = NULL;
+
+ free_percpu(perf_extra_trace_buf[i]);
+ perf_extra_trace_buf[i] = NULL;
}
}
@@ -164,6 +179,9 @@ static void perf_trace_event_unreg(struct perf_event *p_event)
for (i = 0; i < PERF_NR_CONTEXTS; i++) {
free_percpu(perf_trace_buf[i]);
perf_trace_buf[i] = NULL;
+
+ free_percpu(perf_extra_trace_buf[i]);
+ perf_extra_trace_buf[i] = NULL;
}
}
out:
@@ -260,6 +278,34 @@ void perf_trace_del(struct perf_event *p_event, int flags)
tp_event->class->reg(tp_event, TRACE_REG_PERF_DEL, p_event);
}
+void *perf_extra_trace_buf_prepare(int size, int rctx)
+{
+ char *raw_data;
+
+ BUILD_BUG_ON(PERF_MAX_EXTRA_TRACE_SIZE % sizeof(unsigned long));
+
+ if (WARN_ONCE(size > PERF_MAX_EXTRA_TRACE_SIZE,
+ "perf extra buffer not large enough"))
+ return NULL;
+
+ raw_data = this_cpu_ptr(perf_extra_trace_buf[rctx]);
+
+ /* The first 4 bytes is raw_data size and it is used as a valid flag */
+ *(u32 *)raw_data = size;
+ raw_data += sizeof(u32);
+
+ return raw_data;
+}
+EXPORT_SYMBOL_GPL(perf_extra_trace_buf_prepare);
+NOKPROBE_SYMBOL(perf_extra_trace_buf_prepare);
+
+void *get_perf_extra_trace_buf(int rctx)
+{
+ return this_cpu_ptr(perf_extra_trace_buf[rctx]);
+}
+EXPORT_SYMBOL_GPL(get_perf_extra_trace_buf);
+NOKPROBE_SYMBOL(get_perf_extra_trace_buf);
+
void *perf_trace_buf_prepare(int size, unsigned short type,
struct pt_regs **regs, int *rctxp)
{
--
1.8.5.2
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists