lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
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

Powered by Openwall GNU/*/Linux Powered by OpenVZ