Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1228155 > unrolled thread

[RFC PATCH 00/20] Coresight integration with perf

Started byMathieu Poirier <mathieu.poirier@linaro.org>
First post2015-09-18 18:40 +0200
Last post2015-09-18 18:40 +0200
Articles 8 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [RFC PATCH 00/20] Coresight integration with perf  Mathieu Poirier <mathieu.poirier@linaro.org> - 2015-09-18 18:40 +0200
    [RFC PATCH 10/20] coresight: etb10: adding snapshot mode feature Mathieu Poirier <mathieu.poirier@linaro.org> - 2015-09-18 18:40 +0200
    [RFC PATCH 12/20] coresight: keeping track of enabled sink buffers Mathieu Poirier <mathieu.poirier@linaro.org> - 2015-09-18 18:40 +0200
    [RFC PATCH 03/20] coresight: etm3x: implementing 'cpu_id()' API Mathieu Poirier <mathieu.poirier@linaro.org> - 2015-09-18 18:40 +0200
    [RFC PATCH 08/20] coresight: etb10: implementing buffer set and unset APIs Mathieu Poirier <mathieu.poirier@linaro.org> - 2015-09-18 18:40 +0200
    [RFC PATCH 09/20] coresight: etb10: implementing buffer update API Mathieu Poirier <mathieu.poirier@linaro.org> - 2015-09-18 18:40 +0200
    [RFC PATCH 07/20] coresight: etb10: implementing the setup_aux() API Mathieu Poirier <mathieu.poirier@linaro.org> - 2015-09-18 18:40 +0200
    [RFC PATCH 06/20] coresight: etm3x: unlocking tracer in default arch init Mathieu Poirier <mathieu.poirier@linaro.org> - 2015-09-18 18:40 +0200

#1228155 — [RFC PATCH 00/20] Coresight integration with perf

FromMathieu Poirier <mathieu.poirier@linaro.org>
Date2015-09-18 18:40 +0200
Subject[RFC PATCH 00/20] Coresight integration with perf
Message-ID<qa6HT-7Th-15@gated-at.bofh.it>
This patchset aims to integrate configuration and control of
the Coresight tracers with the perf sub-system.

The goal is to use PMUs to represent tracers and the auxiliary
buffer enhancement to collect processor traces.  As such a lot
of work is done to move the current Coresight sysFS oriented
configuration and control commands to perf's AUX API.

For the time being the work concentrates on ETMv3 and ETB1.0
sink buffers.  Work on ETMv4 and other type of sink buffers
will follow once a foundation has been established.

Enhancement to the perf command line tool can be found here [1].
It is based on v4.2 but a rebase to v4.3-rcX will be available
shortly.

Best regards,
Mathieu

[1]. https://git.linaro.org/people/mathieu.poirier/coresight.git/shortlog/refs/heads/perf-v4.2 

Mathieu Poirier (20):
  coresight: etm3x: splitting 'etm_enable_hw()' operations
  coresight: etm3x: implementing 'is_enabled()' API
  coresight: etm3x: implementing 'cpu_id()' API
  coresight: etm3x: using chip logic to start/stop traces
  coresight: etm3x: adapting default tracer setting for perf
  coresight: etm3x: unlocking tracer in default arch init
  coresight: etb10: implementing the setup_aux() API
  coresight: etb10: implementing buffer set and unset APIs
  coresight: etb10: implementing buffer update API
  coresight: etb10: adding snapshot mode feature
  coresight: making coresight_build_paths() public
  coresight: keeping track of enabled sink buffers
  coresight: etm-perf: new PMU driver for ETM tracers
  coresight: etm-perf: implementing 'event_init()' API
  coresight: etm-perf: implementing 'setup_aux()' API
  coresight: etm-perf: implementing trace related APIs
  coresight: etm-perf: adding symbolic link for CPUs
  coresight: etm3x: pushing down perf configuration to tracer
  coresight: etm3x: implementing perf's user/kernel mode
  coresight: updating documentation to reflect integration with perf

 Documentation/trace/coresight.txt                | 116 ++++++-
 MAINTAINERS                                      |   1 +
 drivers/hwtracing/coresight/Makefile             |   2 +-
 drivers/hwtracing/coresight/coresight-etb10.c    | 232 ++++++++++++++
 drivers/hwtracing/coresight/coresight-etm-perf.c | 383 +++++++++++++++++++++++
 drivers/hwtracing/coresight/coresight-etm-perf.h |  27 ++
 drivers/hwtracing/coresight/coresight-etm.h      |   2 +
 drivers/hwtracing/coresight/coresight-etm3x.c    | 309 ++++++++++++++----
 drivers/hwtracing/coresight/coresight-priv.h     |   4 +
 drivers/hwtracing/coresight/coresight.c          |  14 +-
 include/linux/coresight-pmu.h                    |  18 ++
 include/linux/coresight.h                        |  32 +-
 12 files changed, 1075 insertions(+), 65 deletions(-)
 create mode 100644 drivers/hwtracing/coresight/coresight-etm-perf.c
 create mode 100644 drivers/hwtracing/coresight/coresight-etm-perf.h
 create mode 100644 include/linux/coresight-pmu.h

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1228157 — [RFC PATCH 10/20] coresight: etb10: adding snapshot mode feature

FromMathieu Poirier <mathieu.poirier@linaro.org>
Date2015-09-18 18:40 +0200
Subject[RFC PATCH 10/20] coresight: etb10: adding snapshot mode feature
Message-ID<qa6Rz-84j-13@gated-at.bofh.it>
In reply to#1228155
Snapshot mode works by accumulating traces in the ring buffer
until a user-space controlled event occurs.  Traces are allowed
to wrap around when the end of the ring buffer has been reached,
providing the latest and greatest information at all time.

This patch implements this feature by not checking for the end
of the ring buffer and setting the 'head' of the buffer to
the next available address.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
 drivers/hwtracing/coresight/coresight-etb10.c | 30 +++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index 043e504837d3..b01861588243 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -341,9 +341,19 @@ static void etb_unset_buffer(struct coresight_device *csdev,
 {
 	struct cs_buffers *buf = perf_get_aux(handle);
 
-	if (buf)
+	if (buf) {
+		/*
+		 * In snapshot mode ->data_size holds the new address of the
+		 * ring buffer's head.  The size itself is the whole address
+		 * range since we want the latest information.
+		 */
+		if (buf->snapshot)
+			handle->head = local_xchg(&buf->data_size,
+						  buf->nr_pages << PAGE_SHIFT);
+
 		perf_aux_output_end(handle, local_xchg(&buf->data_size, 0),
 				    local_xchg(&buf->lost, 0));
+	}
 }
 
 static void etb_update_buffer(struct coresight_device *csdev,
@@ -406,10 +416,14 @@ static void etb_update_buffer(struct coresight_device *csdev,
 	 * ring buffer can currently handle.  If so adjust the start address
 	 * to take only the last traces.
 	 *
+	 * In snapshot mode we are looking to get the latest traces only and as
+	 * such, we don't care about not overwriting data that hasn't been
+	 * processed by user space.
+	 *
 	 * Since metrics related to ETBs is in words, multiply by the
 	 * amount of byte per word to have the right units.
 	 */
-	if (words * ETB_FRAME_SIZE_WORDS > handle->size) {
+	if (!buf->snapshot && words * ETB_FRAME_SIZE_WORDS > handle->size) {
 		unsigned int capacity = drvdata->buffer_depth;
 
 		/* make sure new sizes are still multiples the frame size */
@@ -449,8 +463,16 @@ static void etb_update_buffer(struct coresight_device *csdev,
 	writel_relaxed(0x0, drvdata->base + ETB_RAM_READ_POINTER);
 	writel_relaxed(0x0, drvdata->base + ETB_RAM_WRITE_POINTER);
 
-	/* update ring buffer information */
-	local_add(words * ETB_FRAME_SIZE_WORDS, &buf->data_size);
+	/*
+	 * In snapshot mode all we have to do is communicate to
+	 * perf_aux_output_end() the address of the current head.  In full
+	 * trace mode the same function expects a size to move rb->aux_head
+	 * forward.
+	 */
+	if (buf->snapshot)
+		local_set(&buf->data_size, (cur * PAGE_SIZE) + offset);
+	else
+		local_add(words * ETB_FRAME_SIZE_WORDS, &buf->data_size);
 
 	CS_LOCK(drvdata->base);
 	etb_enable_hw(drvdata);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1228158 — [RFC PATCH 12/20] coresight: keeping track of enabled sink buffers

FromMathieu Poirier <mathieu.poirier@linaro.org>
Date2015-09-18 18:40 +0200
Subject[RFC PATCH 12/20] coresight: keeping track of enabled sink buffers
Message-ID<qa6Rz-84j-15@gated-at.bofh.it>
In reply to#1228155
Keep track of enabled sink buffers as paths between source
and sinks are being built.  That way sinks associated to a
source can be accessed quickly.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
 drivers/hwtracing/coresight/coresight-priv.h |  3 ++-
 drivers/hwtracing/coresight/coresight.c      | 11 +++++++----
 include/linux/coresight.h                    |  2 ++
 3 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index 8a52fdcb4bd6..3d7467f315ed 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -53,7 +53,8 @@ static inline void CS_UNLOCK(void __iomem *addr)
 }
 
 int coresight_build_paths(struct coresight_device *csdev,
-			  struct list_head *path, bool enable);
+			  struct list_head *path,
+			  struct list_head *sinks, bool enable);
 
 #ifdef CONFIG_CORESIGHT_SOURCE_ETM3X
 extern int etm_readl_cp14(u32 off, unsigned int *val);
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c
index 7a54d8069670..2e9f6248fb7e 100644
--- a/drivers/hwtracing/coresight/coresight.c
+++ b/drivers/hwtracing/coresight/coresight.c
@@ -302,7 +302,8 @@ static int coresight_disable_path(struct list_head *path)
 }
 
 int coresight_build_paths(struct coresight_device *csdev,
-			  struct list_head *path, bool enable)
+			  struct list_head *path,
+			  struct list_head *sinks, bool enable)
 {
 	int i, ret = -EINVAL;
 	struct coresight_connection *conn;
@@ -314,13 +315,15 @@ int coresight_build_paths(struct coresight_device *csdev,
 	    csdev->activated) {
 		if (enable)
 			ret = coresight_enable_path(path);
+			if (!ret && sinks)
+				list_add(&csdev->sinks, sinks);
 		else
 			ret = coresight_disable_path(path);
 	} else {
 		for (i = 0; i < csdev->nr_outport; i++) {
 			conn = &csdev->conns[i];
 			if (coresight_build_paths(conn->child_dev,
-						    path, enable) == 0)
+						  path, sinks, enable) == 0)
 				ret = 0;
 		}
 	}
@@ -347,7 +350,7 @@ int coresight_enable(struct coresight_device *csdev)
 	if (csdev->enable)
 		goto out;
 
-	if (coresight_build_paths(csdev, &path, true)) {
+	if (coresight_build_paths(csdev, &path, NULL, true)) {
 		dev_err(&csdev->dev, "building path(s) failed\n");
 		goto out;
 	}
@@ -373,7 +376,7 @@ void coresight_disable(struct coresight_device *csdev)
 		goto out;
 
 	coresight_disable_source(csdev);
-	if (coresight_build_paths(csdev, &path, false))
+	if (coresight_build_paths(csdev, &path, NULL, false))
 		dev_err(&csdev->dev, "releasing path(s) failed\n");
 
 out:
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 48c3b9df0ae0..da76b2951f10 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -154,6 +154,7 @@ struct coresight_connection {
  * @dev:	The device entity associated to this component.
  * @refcnt:	keep track of what is in use.
  * @path_link:	link of current component into the path being enabled.
+ * @sinks:	list of currently enabled sinks for a source.
  * @orphan:	true if the component has connections that haven't been linked.
  * @enable:	'true' if component is currently part of an active path.
  * @activated:	'true' only if a _sink_ has been activated.  A sink can be
@@ -170,6 +171,7 @@ struct coresight_device {
 	struct device dev;
 	atomic_t *refcnt;
 	struct list_head path_link;
+	struct list_head sinks;
 	bool orphan;
 	bool enable;	/* true only if configured as part of a path */
 	bool activated;	/* true only if a sink is part of a path */
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1228159 — [RFC PATCH 03/20] coresight: etm3x: implementing 'cpu_id()' API

FromMathieu Poirier <mathieu.poirier@linaro.org>
Date2015-09-18 18:40 +0200
Subject[RFC PATCH 03/20] coresight: etm3x: implementing 'cpu_id()' API
Message-ID<qa6Rz-84j-17@gated-at.bofh.it>
In reply to#1228155
Adding an interface to lookup the CPU a tracer has been affined
to along with a source operation allowing external customers to
access it.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
 drivers/hwtracing/coresight/coresight-etm3x.c | 14 ++++++++++++++
 include/linux/coresight.h                     |  3 +++
 2 files changed, 17 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c
index a44bc3532585..4ce9cfc06e93 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x.c
@@ -441,6 +441,19 @@ static void etm_config_enable(void *info)
 	spin_unlock(&drvdata->spinlock);
 }
 
+static int etm_cpu_id(struct coresight_device *csdev)
+{
+	int cpu;
+	unsigned long flags;
+	struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+	spin_lock_irqsave(&drvdata->spinlock, flags);
+	cpu = drvdata->cpu;
+	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+
+	return cpu;
+}
+
 static int etm_trace_id(struct coresight_device *csdev)
 {
 	struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
@@ -536,6 +549,7 @@ static void etm_disable(struct coresight_device *csdev)
 }
 
 static const struct coresight_ops_source etm_source_ops = {
+	.cpu_id		= etm_cpu_id,
 	.trace_id	= etm_trace_id,
 	.is_enabled	= etm_is_enabled,
 	.configure	= etm_configure,
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index d16e874079b7..9fe2ccf1cc36 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -205,6 +205,8 @@ struct coresight_ops_link {
 /**
  * struct coresight_ops_source - basic operations for a source
  * Operations available for sources.
+ * @cpu_id:	returns the value of the CPU number this component
+ *		is associated to.
  * @trace_id:	returns the value of the component's trace ID as known
  *		to the HW.
  * @is_enabled:	returns whether a source has been enabled or not.
@@ -216,6 +218,7 @@ struct coresight_ops_link {
  * @poweroff:	switch off power to a source.
  */
 struct coresight_ops_source {
+	int (*cpu_id)(struct coresight_device *csdev);
 	int (*trace_id)(struct coresight_device *csdev);
 	bool (*is_enabled)(struct coresight_device *csdev);
 	int (*configure)(struct coresight_device *csdev);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1228160 — [RFC PATCH 08/20] coresight: etb10: implementing buffer set and unset APIs

FromMathieu Poirier <mathieu.poirier@linaro.org>
Date2015-09-18 18:40 +0200
Subject[RFC PATCH 08/20] coresight: etb10: implementing buffer set and unset APIs
Message-ID<qa6RA-84j-25@gated-at.bofh.it>
In reply to#1228155
Implementing perf related APIs to activate and terminate
a trace session.  More specifically dealing with the sink
buffer's internal mechanic along with perf's API to start
and stop interactions with the ring buffers.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
 drivers/hwtracing/coresight/coresight-etb10.c | 42 +++++++++++++++++++++++++++
 include/linux/coresight.h                     |  8 +++++
 2 files changed, 50 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index ca2fbf65a454..3239036f4609 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -28,6 +28,7 @@
 #include <linux/amba/bus.h>
 #include <linux/clk.h>
 #include <linux/mm.h>
+#include <linux/perf_event.h>
 
 #include <asm/local.h>
 
@@ -306,10 +307,51 @@ static void *etb_setup_aux(struct coresight_device *csdev, int cpu,
 	return buf;
 }
 
+static int etb_set_buffer(struct coresight_device *csdev,
+			  struct perf_event *event,
+			  struct perf_output_handle *handle)
+{
+	unsigned long head;
+	struct cs_buffers *buf;
+
+	buf = perf_aux_output_begin(handle, event);
+	if (!buf)
+		return -EINVAL;
+
+	/* how much space do we have in this session */
+	buf->size = handle->size;
+
+	/* wrap head around to the amount of space we have */
+	head = handle->head & ((buf->nr_pages << PAGE_SHIFT) - 1);
+
+	/* find the page to write to */
+	buf->cur = head / PAGE_SIZE;
+
+	/* and offset within that page */
+	buf->offset = head % PAGE_SIZE;
+
+	local_set(&buf->head, head);
+	local_set(&buf->data_size, 0);
+
+	return 0;
+}
+
+static void etb_unset_buffer(struct coresight_device *csdev,
+			     struct perf_output_handle *handle)
+{
+	struct cs_buffers *buf = perf_get_aux(handle);
+
+	if (buf)
+		perf_aux_output_end(handle, local_xchg(&buf->data_size, 0),
+				    local_xchg(&buf->lost, 0));
+}
+
 static const struct coresight_ops_sink etb_sink_ops = {
 	.enable		= etb_enable,
 	.disable	= etb_disable,
 	.setup_aux	= etb_setup_aux,
+	.set_buffer	= etb_set_buffer,
+	.unset_buffer	= etb_unset_buffer,
 };
 
 static const struct coresight_ops etb_cs_ops = {
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 71cc23709422..25bdce345ec3 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -15,6 +15,7 @@
 
 #include <linux/device.h>
 #include <linux/sched.h>
+#include <linux/perf_event.h>
 
 /* Peripheral id registers (0xFD0-0xFEC) */
 #define CORESIGHT_PERIPHIDR4	0xfd0
@@ -186,12 +187,19 @@ struct coresight_device {
  * @enable:	enables the sink.
  * @disable:	disables the sink.
  * @setup_aux:	initialises perf's ring buffer for trace collection.
+ * @set_buffer:	initialises buffer mechanic before a trace session.
+ * @unset_buffer: finalises buffer mechanic after a trace session.
  */
 struct coresight_ops_sink {
 	int (*enable)(struct coresight_device *csdev);
 	void (*disable)(struct coresight_device *csdev);
 	void *(*setup_aux)(struct coresight_device *csdev, int cpu,
 			   void **pages, int nr_pages, bool overwrite);
+	int (*set_buffer)(struct coresight_device *csdev,
+			  struct perf_event *event,
+			  struct perf_output_handle *handle);
+	void (*unset_buffer)(struct coresight_device *csdev,
+			     struct perf_output_handle *handle);
 };
 
 /**
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1228161 — [RFC PATCH 09/20] coresight: etb10: implementing buffer update API

FromMathieu Poirier <mathieu.poirier@linaro.org>
Date2015-09-18 18:40 +0200
Subject[RFC PATCH 09/20] coresight: etb10: implementing buffer update API
Message-ID<qa6RA-84j-27@gated-at.bofh.it>
In reply to#1228155
Implementing buffer API to update the location of the ETB
internal ring buffer once a trace session has ended.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
 drivers/hwtracing/coresight/coresight-etb10.c | 113 ++++++++++++++++++++++++++
 include/linux/coresight.h                     |   3 +
 2 files changed, 116 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index 3239036f4609..043e504837d3 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -346,12 +346,125 @@ static void etb_unset_buffer(struct coresight_device *csdev,
 				    local_xchg(&buf->lost, 0));
 }
 
+static void etb_update_buffer(struct coresight_device *csdev,
+			      struct perf_output_handle *handle)
+{
+	int i, cur;
+	u8 *buf_ptr;
+	u32 read_ptr, write_ptr, start;
+	u32 status, read_data, words;
+	unsigned long flags, offset;
+	struct cs_buffers *buf = perf_get_aux(handle);
+	struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+	if (!buf)
+		return;
+
+	spin_lock_irqsave(&drvdata->spinlock, flags);
+	if (!drvdata->enable)
+		goto out;
+
+	etb_disable_hw(drvdata);
+	CS_UNLOCK(drvdata->base);
+
+	read_ptr = readl_relaxed(drvdata->base + ETB_RAM_READ_POINTER);
+	write_ptr = readl_relaxed(drvdata->base + ETB_RAM_WRITE_POINTER);
+
+	/*
+	 * Entries should be aligned to the frame size.  If they are not
+	 * go back to the last alignement point to give decoding tools a
+	 * chance to fix things.
+	 */
+	if (write_ptr % ETB_FRAME_SIZE_WORDS) {
+		dev_err(drvdata->dev,
+			"write_ptr: %lu not aligned to formatter frame size\n",
+			(unsigned long)write_ptr);
+
+		write_ptr &= ~ETB_FRAME_SIZE_WORDS;
+		local_inc(&buf->lost);
+	}
+
+	/*
+	 * Get a hold of the status register and see if a wrap around
+	 * has occurred.  If so adjust things accordingly.  Otherwise
+	 * start at the beginning and go until the write pointer has
+	 * been reached.
+	 */
+	status = readl_relaxed(drvdata->base + ETB_STATUS_REG);
+	if (status & ETB_STATUS_RAM_FULL) {
+		local_inc(&buf->lost);
+		words = drvdata->buffer_depth;
+		start = write_ptr;
+	} else {
+		words = write_ptr - read_ptr;
+		start = 0;
+	}
+
+	/*
+	 * Make sure we don't overwrite data that hasn't been consumed yet.
+	 * It is entirely possible that the HW buffer has more data than the
+	 * ring buffer can currently handle.  If so adjust the start address
+	 * to take only the last traces.
+	 *
+	 * Since metrics related to ETBs is in words, multiply by the
+	 * amount of byte per word to have the right units.
+	 */
+	if (words * ETB_FRAME_SIZE_WORDS > handle->size) {
+		unsigned int capacity = drvdata->buffer_depth;
+
+		/* make sure new sizes are still multiples the frame size */
+		words = handle->size / ETB_FRAME_SIZE_WORDS;
+		/* advance the start pointer to get the latest trace data */
+		start += capacity - words;
+		/* wrap around if we've reach the end of the HW buffer */
+		start &= capacity - 1;
+		/* let the decoder know we've skipped ahead */
+		local_inc(&buf->lost);
+	}
+
+	/* finally tell HW where we want to start reading from */
+	writel_relaxed(start, drvdata->base + ETB_RAM_READ_POINTER);
+
+	cur = buf->cur;
+	offset = buf->offset;
+	for (i = 0; i < words; i++) {
+		buf_ptr = buf->addr[cur] + offset;
+		read_data = readl_relaxed(drvdata->base +
+					  ETB_RAM_READ_DATA_REG);
+		*buf_ptr++ = read_data >> 0;
+		*buf_ptr++ = read_data >> 8;
+		*buf_ptr++ = read_data >> 16;
+		*buf_ptr++ = read_data >> 24;
+
+		offset += 4;
+		if (offset >= PAGE_SIZE) {
+			offset = 0;
+			cur++;
+			/* wrap around at the end of the buffer */
+			cur &= buf->nr_pages - 1;
+		}
+	}
+
+	/* reset ETB buffer for next run */
+	writel_relaxed(0x0, drvdata->base + ETB_RAM_READ_POINTER);
+	writel_relaxed(0x0, drvdata->base + ETB_RAM_WRITE_POINTER);
+
+	/* update ring buffer information */
+	local_add(words * ETB_FRAME_SIZE_WORDS, &buf->data_size);
+
+	CS_LOCK(drvdata->base);
+	etb_enable_hw(drvdata);
+out:
+	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+}
+
 static const struct coresight_ops_sink etb_sink_ops = {
 	.enable		= etb_enable,
 	.disable	= etb_disable,
 	.setup_aux	= etb_setup_aux,
 	.set_buffer	= etb_set_buffer,
 	.unset_buffer	= etb_unset_buffer,
+	.update_buffer	= etb_update_buffer,
 };
 
 static const struct coresight_ops etb_cs_ops = {
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 25bdce345ec3..48c3b9df0ae0 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -187,6 +187,7 @@ struct coresight_device {
  * @enable:	enables the sink.
  * @disable:	disables the sink.
  * @setup_aux:	initialises perf's ring buffer for trace collection.
+ * @update_buffer: update buffer pointers after a trace session.
  * @set_buffer:	initialises buffer mechanic before a trace session.
  * @unset_buffer: finalises buffer mechanic after a trace session.
  */
@@ -195,6 +196,8 @@ struct coresight_ops_sink {
 	void (*disable)(struct coresight_device *csdev);
 	void *(*setup_aux)(struct coresight_device *csdev, int cpu,
 			   void **pages, int nr_pages, bool overwrite);
+	void (*update_buffer)(struct coresight_device *csdev,
+			      struct perf_output_handle *handle);
 	int (*set_buffer)(struct coresight_device *csdev,
 			  struct perf_event *event,
 			  struct perf_output_handle *handle);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1228162 — [RFC PATCH 07/20] coresight: etb10: implementing the setup_aux() API

FromMathieu Poirier <mathieu.poirier@linaro.org>
Date2015-09-18 18:40 +0200
Subject[RFC PATCH 07/20] coresight: etb10: implementing the setup_aux() API
Message-ID<qa6Rz-84j-19@gated-at.bofh.it>
In reply to#1228155
Adding an ETB10 specific auxiliary area setup operation to be
used by the perf framework when events are initialised.

Part of this operation involves modeling the mmap'ed area based
on the specific ways a sink buffer gathers information.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
 drivers/hwtracing/coresight/coresight-etb10.c | 55 +++++++++++++++++++++++++++
 include/linux/coresight.h                     |  3 ++
 2 files changed, 58 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index 77d0f9c1118d..ca2fbf65a454 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -27,6 +27,9 @@
 #include <linux/coresight.h>
 #include <linux/amba/bus.h>
 #include <linux/clk.h>
+#include <linux/mm.h>
+
+#include <asm/local.h>
 
 #include "coresight-priv.h"
 
@@ -64,6 +67,32 @@
 #define ETB_FRAME_SIZE_WORDS	4
 
 /**
+ * struct cs_buffer - keep track of a recording session' specifics
+ * @cur:	index of the current buffer
+ * @nr_pages:	max number of pages granted to us
+ * @nr_bufs:	number of clustered pages
+ * @offset:	offset within the current buffer
+ * @size:	how much space we have for this run
+ * @data_size:	how much we collected in this run
+ * @head:	head of the ring buffer
+ * @lost:	other than zero if we had a HW buffer wrap around
+ * @snapshot:	is this run in snapshot mode
+ * @addr:	virtual address this buffer starts at
+ */
+struct cs_buffers {
+	unsigned int		cur;
+	unsigned int		nr_pages;
+	unsigned int		nr_bufs;
+	unsigned long		offset;
+	unsigned long		size;
+	local_t			data_size;
+	local_t			head;
+	local_t			lost;
+	bool			snapshot;
+	void			*addr[0];
+};
+
+/**
  * struct etb_drvdata - specifics associated to an ETB component
  * @base:	memory mapped base address for this component.
  * @dev:	the device entity associated to this component.
@@ -252,9 +281,35 @@ static void etb_disable(struct coresight_device *csdev)
 	dev_info(drvdata->dev, "ETB disabled\n");
 }
 
+static void *etb_setup_aux(struct coresight_device *csdev, int cpu,
+			   void **pages, int nr_pages, bool overwrite)
+{
+	int node, pg;
+	struct cs_buffers *buf;
+
+	if (cpu == -1)
+		cpu = smp_processor_id();
+	node = cpu_to_node(cpu);
+
+	buf = kzalloc_node(offsetof(struct cs_buffers, addr[nr_pages]),
+			   GFP_KERNEL, node);
+	if (!buf)
+		return NULL;
+
+	buf->snapshot = overwrite;
+	buf->nr_pages = nr_pages;
+
+	/* Record information about buffers */
+	for (pg = 0; pg < buf->nr_pages; pg++)
+		buf->addr[pg] = pages[pg];
+
+	return buf;
+}
+
 static const struct coresight_ops_sink etb_sink_ops = {
 	.enable		= etb_enable,
 	.disable	= etb_disable,
+	.setup_aux	= etb_setup_aux,
 };
 
 static const struct coresight_ops etb_cs_ops = {
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 9fe2ccf1cc36..71cc23709422 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -185,10 +185,13 @@ struct coresight_device {
  * Operations available for sinks
  * @enable:	enables the sink.
  * @disable:	disables the sink.
+ * @setup_aux:	initialises perf's ring buffer for trace collection.
  */
 struct coresight_ops_sink {
 	int (*enable)(struct coresight_device *csdev);
 	void (*disable)(struct coresight_device *csdev);
+	void *(*setup_aux)(struct coresight_device *csdev, int cpu,
+			   void **pages, int nr_pages, bool overwrite);
 };
 
 /**
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1228163 — [RFC PATCH 06/20] coresight: etm3x: unlocking tracer in default arch init

FromMathieu Poirier <mathieu.poirier@linaro.org>
Date2015-09-18 18:40 +0200
Subject[RFC PATCH 06/20] coresight: etm3x: unlocking tracer in default arch init
Message-ID<qa6RA-84j-23@gated-at.bofh.it>
In reply to#1228155
Calling function 'smp_call_function_single()' to unlock the
tracer and calling it right after to perform the default
initialisation doesn't make sense.

Moving 'etm_os_unlock()' just before making the default
initialisation results in the same outcome while saving
one call to 'smp_call_function_single()'.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
 drivers/hwtracing/coresight/coresight-etm3x.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c
index c6880c1ade55..a4c158df0fef 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x.c
@@ -1867,6 +1867,11 @@ static void etm_init_arch_data(void *info)
 	 * certain registers might be ignored.
 	 */
 	etm_clr_pwrdwn(drvdata);
+
+	/* Make sure all registers are accessible */
+	etm_os_unlock(drvdata);
+	drvdata->os_unlock = true;
+
 	/*
 	 * Set prog bit. It will be set from reset but this is included to
 	 * ensure it is set
@@ -1961,9 +1966,6 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id)
 	get_online_cpus();
 	etmdrvdata[drvdata->cpu] = drvdata;
 
-	if (!smp_call_function_single(drvdata->cpu, etm_os_unlock, drvdata, 1))
-		drvdata->os_unlock = true;
-
 	if (smp_call_function_single(drvdata->cpu,
 				     etm_init_arch_data,  drvdata, 1))
 		dev_err(dev, "ETM arch init failed\n");
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web