[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1441691364-5612-3-git-send-email-indou.takao@jp.fujitsu.com>
Date: Tue, 8 Sep 2015 14:49:22 +0900
From: Takao Indoh <indou.takao@...fujitsu.com>
To: Thomas Gleixner <tglx@...utronix.de>,
Ingo Molnar <mingo@...hat.com>,
"H. Peter Anvin" <hpa@...or.com>,
Peter Zijlstra <a.p.zijlstra@...llo.nl>,
Arnaldo Carvalho de Melo <acme@...nel.org>,
Alexander Shishkin <alexander.shishkin@...ux.intel.com>,
Vivek Goyal <vgoyal@...hat.com>,
Steven Rostedt <rostedt@...dmis.org>
CC: <linux-kernel@...r.kernel.org>, <x86@...nel.org>
Subject: [PATCH v2 2/4] perf: Add function to enable perf events in kernel with ring buffer
perf_event_create_kernel_counter is used to enable perf events in kernel
without buffer for logging its events. This patch add new fucntion which
enable perf events with ring buffer. Intel PT logger uses this to enable
Intel PT and some associated events with its log buffer.
Signed-off-by: Takao Indoh <indou.takao@...fujitsu.com>
---
include/linux/perf_event.h | 10 ++++++
kernel/events/core.c | 70 ++++++++++++++++++++++++++++++++++++++++---
2 files changed, 75 insertions(+), 5 deletions(-)
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 2027809..34ada8c 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -657,6 +657,16 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr,
struct task_struct *task,
perf_overflow_handler_t callback,
void *context);
+extern struct perf_event *
+perf_event_create_kernel_counter_with_buffer(struct perf_event_attr *attr,
+ int cpu,
+ struct task_struct *task,
+ perf_overflow_handler_t callback,
+ void *context,
+ int flags,
+ int nr_pages,
+ int nr_pages_aux,
+ struct perf_event *output_event);
extern void perf_pmu_migrate_context(struct pmu *pmu,
int src_cpu, int dst_cpu);
extern u64 perf_event_read_value(struct perf_event *event,
diff --git a/kernel/events/core.c b/kernel/events/core.c
index ae16867..c9d8a59 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -8356,21 +8356,33 @@ err_fd:
}
/**
- * perf_event_create_kernel_counter
+ * perf_event_create_kernel_counter_with_buffer
*
* @attr: attributes of the counter to create
* @cpu: cpu in which the counter is bound
* @task: task to profile (NULL for percpu)
+ * @overflow_handler: handler for overflow event
+ * @context: target context
+ * @flags: flags of ring buffer
+ * @nr_pages: size (number of pages) of buffer
+ * @nr_pages_aux: size (number of pages) of aux buffer
+ * @output_event: event to be attached
*/
struct perf_event *
-perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
- struct task_struct *task,
- perf_overflow_handler_t overflow_handler,
- void *context)
+perf_event_create_kernel_counter_with_buffer(struct perf_event_attr *attr,
+ int cpu,
+ struct task_struct *task,
+ perf_overflow_handler_t overflow_handler,
+ void *context,
+ int flags,
+ int nr_pages,
+ int nr_pages_aux,
+ struct perf_event *output_event)
{
struct perf_event_context *ctx;
struct perf_event *event;
int err;
+ struct ring_buffer *rb = NULL;
/*
* Get the target context (task or percpu):
@@ -8383,6 +8395,31 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
goto err;
}
+ if (output_event) {
+ err = perf_event_set_output(event, output_event);
+ if (err)
+ goto err_free;
+ } else if (nr_pages) {
+ rb = rb_alloc(nr_pages,
+ event->attr.watermark ? event->attr.wakeup_watermark : 0,
+ event->cpu, flags);
+
+ if (!rb) {
+ err = -ENOMEM;
+ goto err_free;
+ }
+
+ ring_buffer_attach(event, rb);
+
+ if (nr_pages_aux) {
+ err = rb_alloc_aux(rb, event, 0, nr_pages_aux,
+ event->attr.aux_watermark, flags);
+
+ if (err)
+ goto err_free;
+ }
+ }
+
/* Mark owner so we could distinguish it from user events. */
event->owner = EVENT_OWNER_KERNEL;
@@ -8411,10 +8448,33 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
return event;
err_free:
+ if (rb && rb->aux_pages)
+ rb_free_aux(rb);
+ if (rb)
+ rb_free(rb);
free_event(event);
err:
return ERR_PTR(err);
}
+EXPORT_SYMBOL_GPL(perf_event_create_kernel_counter_with_buffer);
+
+/**
+ * perf_event_create_kernel_counter
+ *
+ * @attr: attributes of the counter to create
+ * @cpu: cpu in which the counter is bound
+ * @task: task to profile (NULL for percpu)
+ */
+struct perf_event *
+perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
+ struct task_struct *task,
+ perf_overflow_handler_t overflow_handler,
+ void *context)
+{
+ return perf_event_create_kernel_counter_with_buffer(attr, cpu, task,
+ overflow_handler,
+ context, 0, 0, 0, NULL);
+}
EXPORT_SYMBOL_GPL(perf_event_create_kernel_counter);
void perf_pmu_migrate_context(struct pmu *pmu, int src_cpu, int dst_cpu)
--
1.7.1
--
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