linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 00/20] Coresight integration with perf
@ 2015-09-18 16:26 Mathieu Poirier
  2015-09-18 16:26 ` [RFC PATCH 01/20] coresight: etm3x: splitting 'etm_enable_hw()' operations Mathieu Poirier
                   ` (22 more replies)
  0 siblings, 23 replies; 48+ messages in thread
From: Mathieu Poirier @ 2015-09-18 16:26 UTC (permalink / raw)
  To: gregkh, a.p.zijlstra, alexander.shishkin, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

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


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [RFC PATCH 01/20] coresight: etm3x: splitting 'etm_enable_hw()' operations
  2015-09-18 16:26 [RFC PATCH 00/20] Coresight integration with perf Mathieu Poirier
@ 2015-09-18 16:26 ` Mathieu Poirier
  2015-09-30  9:58   ` Alexander Shishkin
  2015-09-18 16:26 ` [RFC PATCH 02/20] coresight: etm3x: implementing 'is_enabled()' API Mathieu Poirier
                   ` (21 subsequent siblings)
  22 siblings, 1 reply; 48+ messages in thread
From: Mathieu Poirier @ 2015-09-18 16:26 UTC (permalink / raw)
  To: gregkh, a.p.zijlstra, alexander.shishkin, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

When dealing with other kernel subsystems or automated tools it
is desirable to split the current etm_enable_hw() operation
in three: power up, configuration and enabling of the tracer.

That way it is possible to have more control on the operations
done by a tracer.

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

diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c
index d630b7ece735..999c62a59c70 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x.c
@@ -247,11 +247,12 @@ static void etm_set_default(struct etm_drvdata *drvdata)
 	drvdata->ctxid_mask = 0x0;
 }
 
-static void etm_enable_hw(void *info)
+static void etm_power_up_cpu(void *info)
 {
-	int i;
-	u32 etmcr;
-	struct etm_drvdata *drvdata = info;
+	struct coresight_device *csdev = info;
+	struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+	WARN_ON(drvdata->cpu != smp_processor_id());
 
 	CS_UNLOCK(drvdata->base);
 
@@ -262,10 +263,65 @@ static void etm_enable_hw(void *info)
 	/* Make sure all registers are accessible */
 	etm_os_unlock(drvdata);
 
+	CS_LOCK(drvdata->base);
+}
+
+static int etm_power_up(struct coresight_device *csdev)
+{
+	struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+	/* tell the core we need this tracer */
+	pm_runtime_get_sync(csdev->dev.parent);
+
+	return smp_call_function_single(drvdata->cpu,
+					etm_power_up_cpu, csdev, 1);
+}
+
+static void etm_power_down_cpu(void *info)
+{
+	struct coresight_device *csdev = info;
+	struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+	WARN_ON(drvdata->cpu != smp_processor_id());
+
+	CS_UNLOCK(drvdata->base);
+	etm_clr_pwrup(drvdata);
+	etm_set_pwrdwn(drvdata);
+	CS_LOCK(drvdata->base);
+}
+
+static void etm_power_down(struct coresight_device *csdev)
+{
+	struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+	smp_call_function_single(drvdata->cpu,
+				 etm_power_down_cpu, csdev, 1);
+
+	/* tell the core this tracer is no longer needed */
+	pm_runtime_put(csdev->dev.parent);
+}
+
+/**
+ * etm_configure_cpu - configure ETM registers
+ * @csdev - the etm that needs to be configure.
+ *
+ * Applies a configuration set to the ETM registers _without_ enabling the
+ * tracer.  This function needs to be executed on the CPU who's tracer is
+ * being configured.
+ */
+static void etm_configure_cpu(void *info)
+{
+	int i;
+	u32 etmcr;
+	struct coresight_device *csdev = info;
+	struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+	WARN_ON(drvdata->cpu != smp_processor_id());
+
+	CS_UNLOCK(drvdata->base);
 	etm_set_prog(drvdata);
 
 	etmcr = etm_readl(drvdata, ETMCR);
-	etmcr &= (ETMCR_PWD_DWN | ETMCR_ETM_PRG);
 	etmcr |= drvdata->port_size;
 	etm_writel(drvdata, drvdata->ctrl | etmcr, ETMCR);
 	etm_writel(drvdata, drvdata->trigger_event, ETMTRIGGER);
@@ -306,13 +362,71 @@ static void etm_enable_hw(void *info)
 	/* No VMID comparator value selected */
 	etm_writel(drvdata, 0x0, ETMVMIDCVR);
 
-	/* Ensures trace output is enabled from this ETM */
-	etm_writel(drvdata, drvdata->ctrl | ETMCR_ETM_EN | etmcr, ETMCR);
+	etm_clr_prog(drvdata);
+	CS_LOCK(drvdata->base);
+}
+
+static int etm_configure(struct coresight_device *csdev)
+{
+	struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+	return smp_call_function_single(drvdata->cpu,
+					etm_configure_cpu, csdev, 1);
+}
+
+/**
+ * etm_trace_enable - enable ETM tracer
+ * @csdev	- the etm that needs to be enabled/disabled.
+ * @enable	- whether to enable or disable the tracer.
+ *
+ * Only enables the tracer - register configuration should have been made
+ * prior to calling this function.  This should be executed on the CPU who's
+ * tracer is being enabled.
+ */
+static int etm_trace_enable(struct coresight_device *csdev, bool enable)
+{
+	u32 etmcr;
+	struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+	WARN_ON(drvdata->cpu != smp_processor_id());
+
+	/*
+	 * It is assumed that etm_configure_cpu() has been called.  As such
+	 * the ETM should be turned on, power applied to the trace registers
+	 * and all registers accessible.
+	 */
+	CS_UNLOCK(drvdata->base);
+	etm_set_prog(drvdata);
+
+	etmcr = etm_readl(drvdata, ETMCR);
+
+	enable ? (etmcr |= ETMCR_ETM_EN) :
+		 (etmcr &= ~ETMCR_ETM_EN);
+
+	etm_writel(drvdata, ETMCR_ETM_EN | etmcr, ETMCR);
 
 	etm_clr_prog(drvdata);
 	CS_LOCK(drvdata->base);
 
+	return 0;
+}
+
+static void etm_config_enable(void *info)
+{
+	struct coresight_device *csdev = info;
+	struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+	spin_lock(&drvdata->spinlock);
+
+	etm_power_up_cpu(csdev);
+	etm_configure_cpu(csdev);
+	etm_trace_enable(csdev, true);
 	dev_dbg(drvdata->dev, "cpu: %d enable smp call done\n", drvdata->cpu);
+
+	drvdata->enable = true;
+	drvdata->sticky_enable = true;
+
+	spin_unlock(&drvdata->spinlock);
 }
 
 static int etm_trace_id(struct coresight_device *csdev)
@@ -339,11 +453,8 @@ static int etm_trace_id(struct coresight_device *csdev)
 
 static int etm_enable(struct coresight_device *csdev)
 {
-	struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 	int ret;
-
-	pm_runtime_get_sync(csdev->dev.parent);
-	spin_lock(&drvdata->spinlock);
+	struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
 	/*
 	 * Configure the ETM only if the CPU is online.  If it isn't online
@@ -352,34 +463,28 @@ static int etm_enable(struct coresight_device *csdev)
 	 */
 	if (cpu_online(drvdata->cpu)) {
 		ret = smp_call_function_single(drvdata->cpu,
-					       etm_enable_hw, drvdata, 1);
+					       etm_config_enable, csdev, 1);
 		if (ret)
 			goto err;
 	}
 
-	drvdata->enable = true;
-	drvdata->sticky_enable = true;
-
-	spin_unlock(&drvdata->spinlock);
-
 	dev_info(drvdata->dev, "ETM tracing enabled\n");
 	return 0;
 err:
-	spin_unlock(&drvdata->spinlock);
-	pm_runtime_put(csdev->dev.parent);
 	return ret;
 }
 
-static void etm_disable_hw(void *info)
+static void etm_disable_powerdown(void *info)
 {
 	int i;
 	struct etm_drvdata *drvdata = info;
 
+	spin_lock(&drvdata->spinlock);
 	CS_UNLOCK(drvdata->base);
 	etm_set_prog(drvdata);
 
-	/* Program trace enable to low by using always false event */
-	etm_writel(drvdata, ETM_HARD_WIRE_RES_A | ETM_EVENT_NOT_A, ETMTEEVR);
+	etm_trace_enable(drvdata->csdev, false);
+	drvdata->enable = false;
 
 	/* Read back sequencer and counters for post trace analysis */
 	drvdata->seq_curr_state = (etm_readl(drvdata, ETMSQR) & ETM_SQR_MASK);
@@ -387,8 +492,9 @@ static void etm_disable_hw(void *info)
 	for (i = 0; i < drvdata->nr_cntr; i++)
 		drvdata->cntr_val[i] = etm_readl(drvdata, ETMCNTVRn(i));
 
-	etm_set_pwrdwn(drvdata);
+	etm_power_down(drvdata->csdev);
 	CS_LOCK(drvdata->base);
+	spin_unlock(&drvdata->spinlock);
 
 	dev_dbg(drvdata->dev, "cpu: %d disable smp call done\n", drvdata->cpu);
 }
@@ -404,26 +510,27 @@ static void etm_disable(struct coresight_device *csdev)
 	 * DYING hotplug callback is serviced by the ETM driver.
 	 */
 	get_online_cpus();
-	spin_lock(&drvdata->spinlock);
 
 	/*
 	 * Executing etm_disable_hw on the cpu whose ETM is being disabled
 	 * ensures that register writes occur when cpu is powered.
 	 */
-	smp_call_function_single(drvdata->cpu, etm_disable_hw, drvdata, 1);
-	drvdata->enable = false;
+	smp_call_function_single(drvdata->cpu,
+				 etm_disable_powerdown, drvdata, 1);
 
-	spin_unlock(&drvdata->spinlock);
 	put_online_cpus();
-	pm_runtime_put(csdev->dev.parent);
 
 	dev_info(drvdata->dev, "ETM tracing disabled\n");
 }
 
 static const struct coresight_ops_source etm_source_ops = {
 	.trace_id	= etm_trace_id,
+	.configure	= etm_configure,
+	.trace_enable	= etm_trace_enable,
 	.enable		= etm_enable,
 	.disable	= etm_disable,
+	.poweron	= etm_power_up,
+	.poweroff	= etm_power_down,
 };
 
 static const struct coresight_ops etm_cs_ops = {
@@ -1659,7 +1766,7 @@ static int etm_cpu_callback(struct notifier_block *nfb, unsigned long action,
 		}
 
 		if (etmdrvdata[cpu]->enable)
-			etm_enable_hw(etmdrvdata[cpu]);
+			etm_config_enable(etmdrvdata[cpu]->csdev);
 		spin_unlock(&etmdrvdata[cpu]->spinlock);
 		break;
 
@@ -1672,7 +1779,7 @@ static int etm_cpu_callback(struct notifier_block *nfb, unsigned long action,
 	case CPU_DYING:
 		spin_lock(&etmdrvdata[cpu]->spinlock);
 		if (etmdrvdata[cpu]->enable)
-			etm_disable_hw(etmdrvdata[cpu]);
+			etm_disable_powerdown(etmdrvdata[cpu]->csdev);
 		spin_unlock(&etmdrvdata[cpu]->spinlock);
 		break;
 	}
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index a7cabfa23b55..70f3dafa5194 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -206,14 +206,22 @@ struct coresight_ops_link {
  * struct coresight_ops_source - basic operations for a source
  * Operations available for sources.
  * @trace_id:	returns the value of the component's trace ID as known
-		to the HW.
+ *		to the HW.
+ * @configure:	performs configuration for a source but doesn't enable it.
+ * @trace_enable: enable/disable tracing on a source.
  * @enable:	enables tracing for a source.
  * @disable:	disables tracing for a source.
+ * @poweron:	switch on power to a source.
+ * @poweroff:	switch off power to a source.
  */
 struct coresight_ops_source {
 	int (*trace_id)(struct coresight_device *csdev);
+	int (*configure)(struct coresight_device *csdev);
+	int (*trace_enable)(struct coresight_device *csdev, bool enable);
 	int (*enable)(struct coresight_device *csdev);
 	void (*disable)(struct coresight_device *csdev);
+	int (*poweron)(struct coresight_device *csdev);
+	void (*poweroff)(struct coresight_device *csdev);
 };
 
 struct coresight_ops {
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 02/20] coresight: etm3x: implementing 'is_enabled()' API
  2015-09-18 16:26 [RFC PATCH 00/20] Coresight integration with perf Mathieu Poirier
  2015-09-18 16:26 ` [RFC PATCH 01/20] coresight: etm3x: splitting 'etm_enable_hw()' operations Mathieu Poirier
@ 2015-09-18 16:26 ` Mathieu Poirier
  2015-09-18 16:26 ` [RFC PATCH 03/20] coresight: etm3x: implementing 'cpu_id()' API Mathieu Poirier
                   ` (20 subsequent siblings)
  22 siblings, 0 replies; 48+ messages in thread
From: Mathieu Poirier @ 2015-09-18 16:26 UTC (permalink / raw)
  To: gregkh, a.p.zijlstra, alexander.shishkin, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

Adding an interface to lookup the status of a tracer 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 | 13 +++++++++++++
 include/linux/coresight.h                     |  2 ++
 2 files changed, 15 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c
index 999c62a59c70..a44bc3532585 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x.c
@@ -374,6 +374,18 @@ static int etm_configure(struct coresight_device *csdev)
 					etm_configure_cpu, csdev, 1);
 }
 
+static bool etm_is_enabled(struct coresight_device *csdev)
+{
+	bool enabled;
+	struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+	spin_lock(&drvdata->spinlock);
+	enabled = drvdata->enable;
+	spin_unlock(&drvdata->spinlock);
+
+	return enabled;
+}
+
 /**
  * etm_trace_enable - enable ETM tracer
  * @csdev	- the etm that needs to be enabled/disabled.
@@ -525,6 +537,7 @@ static void etm_disable(struct coresight_device *csdev)
 
 static const struct coresight_ops_source etm_source_ops = {
 	.trace_id	= etm_trace_id,
+	.is_enabled	= etm_is_enabled,
 	.configure	= etm_configure,
 	.trace_enable	= etm_trace_enable,
 	.enable		= etm_enable,
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 70f3dafa5194..d16e874079b7 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -207,6 +207,7 @@ struct coresight_ops_link {
  * Operations available for sources.
  * @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.
  * @configure:	performs configuration for a source but doesn't enable it.
  * @trace_enable: enable/disable tracing on a source.
  * @enable:	enables tracing for a source.
@@ -216,6 +217,7 @@ struct coresight_ops_link {
  */
 struct coresight_ops_source {
 	int (*trace_id)(struct coresight_device *csdev);
+	bool (*is_enabled)(struct coresight_device *csdev);
 	int (*configure)(struct coresight_device *csdev);
 	int (*trace_enable)(struct coresight_device *csdev, bool enable);
 	int (*enable)(struct coresight_device *csdev);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 03/20] coresight: etm3x: implementing 'cpu_id()' API
  2015-09-18 16:26 [RFC PATCH 00/20] Coresight integration with perf Mathieu Poirier
  2015-09-18 16:26 ` [RFC PATCH 01/20] coresight: etm3x: splitting 'etm_enable_hw()' operations Mathieu Poirier
  2015-09-18 16:26 ` [RFC PATCH 02/20] coresight: etm3x: implementing 'is_enabled()' API Mathieu Poirier
@ 2015-09-18 16:26 ` Mathieu Poirier
  2015-09-30 11:16   ` Alexander Shishkin
  2015-09-18 16:26 ` [RFC PATCH 04/20] coresight: etm3x: using chip logic to start/stop traces Mathieu Poirier
                   ` (19 subsequent siblings)
  22 siblings, 1 reply; 48+ messages in thread
From: Mathieu Poirier @ 2015-09-18 16:26 UTC (permalink / raw)
  To: gregkh, a.p.zijlstra, alexander.shishkin, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

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


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 04/20] coresight: etm3x: using chip logic to start/stop traces
  2015-09-18 16:26 [RFC PATCH 00/20] Coresight integration with perf Mathieu Poirier
                   ` (2 preceding siblings ...)
  2015-09-18 16:26 ` [RFC PATCH 03/20] coresight: etm3x: implementing 'cpu_id()' API Mathieu Poirier
@ 2015-09-18 16:26 ` Mathieu Poirier
  2015-09-18 16:26 ` [RFC PATCH 05/20] coresight: etm3x: adapting default tracer setting for perf Mathieu Poirier
                   ` (18 subsequent siblings)
  22 siblings, 0 replies; 48+ messages in thread
From: Mathieu Poirier @ 2015-09-18 16:26 UTC (permalink / raw)
  To: gregkh, a.p.zijlstra, alexander.shishkin, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

Driving the external ETMEN pins to start and stop trace
collection isn't reliable when doing rapid, successive
trace collection runs.

Using the internal event enable register logic to control
tracing is much more dependable.

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

diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c
index 4ce9cfc06e93..3cdf0bcddb41 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x.c
@@ -323,6 +323,7 @@ static void etm_configure_cpu(void *info)
 
 	etmcr = etm_readl(drvdata, ETMCR);
 	etmcr |= drvdata->port_size;
+	etmcr |= ETMCR_ETM_EN;
 	etm_writel(drvdata, drvdata->ctrl | etmcr, ETMCR);
 	etm_writel(drvdata, drvdata->trigger_event, ETMTRIGGER);
 	etm_writel(drvdata, drvdata->startstop_ctrl, ETMTSSCR);
@@ -397,7 +398,7 @@ static bool etm_is_enabled(struct coresight_device *csdev)
  */
 static int etm_trace_enable(struct coresight_device *csdev, bool enable)
 {
-	u32 etmcr;
+	u32 etmteevr;
 	struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
 	WARN_ON(drvdata->cpu != smp_processor_id());
@@ -410,13 +411,16 @@ static int etm_trace_enable(struct coresight_device *csdev, bool enable)
 	CS_UNLOCK(drvdata->base);
 	etm_set_prog(drvdata);
 
-	etmcr = etm_readl(drvdata, ETMCR);
-
-	enable ? (etmcr |= ETMCR_ETM_EN) :
-		 (etmcr &= ~ETMCR_ETM_EN);
-
-	etm_writel(drvdata, ETMCR_ETM_EN | etmcr, ETMCR);
+	etmteevr = etm_readl(drvdata, ETMTEEVR);
+	if (enable) {
+		/* boolean function bits all set to '0' selects resource A */
+		etmteevr &= ~(BIT(16) | BIT(15) | BIT(14));
+	} else {
+		/* boolean function bit 14 negate resource selection A */
+		etmteevr |= BIT(14);
+	}
 
+	etm_writel(drvdata, etmteevr, ETMTEEVR);
 	etm_clr_prog(drvdata);
 	CS_LOCK(drvdata->base);
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 05/20] coresight: etm3x: adapting default tracer setting for perf
  2015-09-18 16:26 [RFC PATCH 00/20] Coresight integration with perf Mathieu Poirier
                   ` (3 preceding siblings ...)
  2015-09-18 16:26 ` [RFC PATCH 04/20] coresight: etm3x: using chip logic to start/stop traces Mathieu Poirier
@ 2015-09-18 16:26 ` Mathieu Poirier
  2015-09-18 16:26 ` [RFC PATCH 06/20] coresight: etm3x: unlocking tracer in default arch init Mathieu Poirier
                   ` (17 subsequent siblings)
  22 siblings, 0 replies; 48+ messages in thread
From: Mathieu Poirier @ 2015-09-18 16:26 UTC (permalink / raw)
  To: gregkh, a.p.zijlstra, alexander.shishkin, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

The perf command line tool has options to trace in kernel or
user space mode.  As such configuring tracers to trace the
entire address range, leaving to the perf mechanic the task
of collecting traces in accordance with the requested mode.

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

diff --git a/drivers/hwtracing/coresight/coresight-etm.h b/drivers/hwtracing/coresight/coresight-etm.h
index b4481eb29304..b149a565bc32 100644
--- a/drivers/hwtracing/coresight/coresight-etm.h
+++ b/drivers/hwtracing/coresight/coresight-etm.h
@@ -165,6 +165,7 @@
  * @startstop_ctrl: setting for register ETMTSSCR.
  * @enable_event: setting for register ETMTEEVR.
  * @enable_ctrl1: setting for register ETMTECR1.
+ * @enable_ctrl2: setting for register ETMTECR2.
  * @fifofull_level: setting for register ETMFFLR.
  * @addr_idx:	index for the address comparator selection.
  * @addr_val:	value for address comparator register.
@@ -219,6 +220,7 @@ struct etm_drvdata {
 	u32				startstop_ctrl;
 	u32				enable_event;
 	u32				enable_ctrl1;
+	u32				enable_ctrl2;
 	u32				fifofull_level;
 	u8				addr_idx;
 	u32				addr_val[ETM_MAX_ADDR_CMP];
diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c
index 3cdf0bcddb41..c6880c1ade55 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x.c
@@ -220,6 +220,17 @@ static void etm_set_default(struct etm_drvdata *drvdata)
 	int i;
 
 	drvdata->trigger_event = ETM_DEFAULT_EVENT_VAL;
+	/*
+	 * Taken verbatim from the TRM:
+	 *
+	 * To trace all memory:
+	 *  set bit [24] in register 0x009, the ETMTECR1, to 1
+	 *  set all other bits in register 0x009, the ETMTECR1, to 0
+	 *  set all bits in register 0x007, the ETMTECR2, to 0
+	 *  set register 0x008, the ETMTEEVR, to 0x6F (TRUE).
+	 */
+	drvdata->enable_ctrl1 = BIT(24);
+	drvdata->enable_ctrl2 = 0x0;
 	drvdata->enable_event = ETM_HARD_WIRE_RES_A;
 
 	drvdata->seq_12_event = ETM_DEFAULT_EVENT_VAL;
@@ -1881,7 +1892,7 @@ static void etm_init_arch_data(void *info)
 	CS_LOCK(drvdata->base);
 }
 
-static void etm_init_default_data(struct etm_drvdata *drvdata)
+static void etm_init_trace_id(struct etm_drvdata *drvdata)
 {
 	/*
 	 * A trace ID of value 0 is invalid, so let's start at some
@@ -1889,13 +1900,6 @@ static void etm_init_default_data(struct etm_drvdata *drvdata)
 	 */
 	static int etm3x_traceid = 0x10;
 
-	u32 flags = (1 << 0 | /* instruction execute*/
-		     3 << 3 | /* ARM instruction */
-		     0 << 5 | /* No data value comparison */
-		     0 << 7 | /* No exact mach */
-		     0 << 8 | /* Ignore context ID */
-		     0 << 10); /* Security ignored */
-
 	/*
 	 * Initial configuration only - guarantees sources handled by
 	 * this driver have a unique ID at startup time but not between
@@ -1903,18 +1907,6 @@ static void etm_init_default_data(struct etm_drvdata *drvdata)
 	 * framework.
 	 */
 	drvdata->traceid = etm3x_traceid++;
-	drvdata->ctrl = (ETMCR_CYC_ACC | ETMCR_TIMESTAMP_EN);
-	drvdata->enable_ctrl1 = ETMTECR1_ADDR_COMP_1;
-	if (drvdata->nr_addr_cmp >= 2) {
-		drvdata->addr_val[0] = (u32) _stext;
-		drvdata->addr_val[1] = (u32) _etext;
-		drvdata->addr_acctype[0] = flags;
-		drvdata->addr_acctype[1] = flags;
-		drvdata->addr_type[0] = ETM_ADDR_TYPE_RANGE;
-		drvdata->addr_type[1] = ETM_ADDR_TYPE_RANGE;
-	}
-
-	etm_set_default(drvdata);
 }
 
 static int etm_probe(struct amba_device *adev, const struct amba_id *id)
@@ -1985,7 +1977,9 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id)
 		ret = -EINVAL;
 		goto err_arch_supported;
 	}
-	etm_init_default_data(drvdata);
+
+	etm_init_trace_id(drvdata);
+	etm_set_default(drvdata);
 
 	desc->type = CORESIGHT_DEV_TYPE_SOURCE;
 	desc->subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_PROC;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 06/20] coresight: etm3x: unlocking tracer in default arch init
  2015-09-18 16:26 [RFC PATCH 00/20] Coresight integration with perf Mathieu Poirier
                   ` (4 preceding siblings ...)
  2015-09-18 16:26 ` [RFC PATCH 05/20] coresight: etm3x: adapting default tracer setting for perf Mathieu Poirier
@ 2015-09-18 16:26 ` Mathieu Poirier
  2015-09-30 11:33   ` Alexander Shishkin
  2015-09-18 16:26 ` [RFC PATCH 07/20] coresight: etb10: implementing the setup_aux() API Mathieu Poirier
                   ` (16 subsequent siblings)
  22 siblings, 1 reply; 48+ messages in thread
From: Mathieu Poirier @ 2015-09-18 16:26 UTC (permalink / raw)
  To: gregkh, a.p.zijlstra, alexander.shishkin, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

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


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 07/20] coresight: etb10: implementing the setup_aux() API
  2015-09-18 16:26 [RFC PATCH 00/20] Coresight integration with perf Mathieu Poirier
                   ` (5 preceding siblings ...)
  2015-09-18 16:26 ` [RFC PATCH 06/20] coresight: etm3x: unlocking tracer in default arch init Mathieu Poirier
@ 2015-09-18 16:26 ` Mathieu Poirier
  2015-09-18 16:26 ` [RFC PATCH 08/20] coresight: etb10: implementing buffer set and unset APIs Mathieu Poirier
                   ` (15 subsequent siblings)
  22 siblings, 0 replies; 48+ messages in thread
From: Mathieu Poirier @ 2015-09-18 16:26 UTC (permalink / raw)
  To: gregkh, a.p.zijlstra, alexander.shishkin, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

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


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 08/20] coresight: etb10: implementing buffer set and unset APIs
  2015-09-18 16:26 [RFC PATCH 00/20] Coresight integration with perf Mathieu Poirier
                   ` (6 preceding siblings ...)
  2015-09-18 16:26 ` [RFC PATCH 07/20] coresight: etb10: implementing the setup_aux() API Mathieu Poirier
@ 2015-09-18 16:26 ` Mathieu Poirier
  2015-09-18 16:26 ` [RFC PATCH 09/20] coresight: etb10: implementing buffer update API Mathieu Poirier
                   ` (14 subsequent siblings)
  22 siblings, 0 replies; 48+ messages in thread
From: Mathieu Poirier @ 2015-09-18 16:26 UTC (permalink / raw)
  To: gregkh, a.p.zijlstra, alexander.shishkin, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

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


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 09/20] coresight: etb10: implementing buffer update API
  2015-09-18 16:26 [RFC PATCH 00/20] Coresight integration with perf Mathieu Poirier
                   ` (7 preceding siblings ...)
  2015-09-18 16:26 ` [RFC PATCH 08/20] coresight: etb10: implementing buffer set and unset APIs Mathieu Poirier
@ 2015-09-18 16:26 ` Mathieu Poirier
  2015-09-18 16:26 ` [RFC PATCH 10/20] coresight: etb10: adding snapshot mode feature Mathieu Poirier
                   ` (13 subsequent siblings)
  22 siblings, 0 replies; 48+ messages in thread
From: Mathieu Poirier @ 2015-09-18 16:26 UTC (permalink / raw)
  To: gregkh, a.p.zijlstra, alexander.shishkin, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

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


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 10/20] coresight: etb10: adding snapshot mode feature
  2015-09-18 16:26 [RFC PATCH 00/20] Coresight integration with perf Mathieu Poirier
                   ` (8 preceding siblings ...)
  2015-09-18 16:26 ` [RFC PATCH 09/20] coresight: etb10: implementing buffer update API Mathieu Poirier
@ 2015-09-18 16:26 ` Mathieu Poirier
  2015-09-18 16:26 ` [RFC PATCH 11/20] coresight: making coresight_build_paths() public Mathieu Poirier
                   ` (12 subsequent siblings)
  22 siblings, 0 replies; 48+ messages in thread
From: Mathieu Poirier @ 2015-09-18 16:26 UTC (permalink / raw)
  To: gregkh, a.p.zijlstra, alexander.shishkin, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

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


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 11/20] coresight: making coresight_build_paths() public
  2015-09-18 16:26 [RFC PATCH 00/20] Coresight integration with perf Mathieu Poirier
                   ` (9 preceding siblings ...)
  2015-09-18 16:26 ` [RFC PATCH 10/20] coresight: etb10: adding snapshot mode feature Mathieu Poirier
@ 2015-09-18 16:26 ` Mathieu Poirier
  2015-09-18 16:26 ` [RFC PATCH 12/20] coresight: keeping track of enabled sink buffers Mathieu Poirier
                   ` (11 subsequent siblings)
  22 siblings, 0 replies; 48+ messages in thread
From: Mathieu Poirier @ 2015-09-18 16:26 UTC (permalink / raw)
  To: gregkh, a.p.zijlstra, alexander.shishkin, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

That way a path can be built outside of the core framework,
something useful when a PMU is initialised from the perf sub
system.

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

diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index 62fcd98cc7cf..8a52fdcb4bd6 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -52,6 +52,9 @@ static inline void CS_UNLOCK(void __iomem *addr)
 	} while (0);
 }
 
+int coresight_build_paths(struct coresight_device *csdev,
+			  struct list_head *path, bool enable);
+
 #ifdef CONFIG_CORESIGHT_SOURCE_ETM3X
 extern int etm_readl_cp14(u32 off, unsigned int *val);
 extern int etm_writel_cp14(u32 off, u32 val);
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c
index a3dcafb81700..7a54d8069670 100644
--- a/drivers/hwtracing/coresight/coresight.c
+++ b/drivers/hwtracing/coresight/coresight.c
@@ -301,9 +301,8 @@ static int coresight_disable_path(struct list_head *path)
 	return 0;
 }
 
-static int coresight_build_paths(struct coresight_device *csdev,
-				 struct list_head *path,
-				 bool enable)
+int coresight_build_paths(struct coresight_device *csdev,
+			  struct list_head *path, bool enable)
 {
 	int i, ret = -EINVAL;
 	struct coresight_connection *conn;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 12/20] coresight: keeping track of enabled sink buffers
  2015-09-18 16:26 [RFC PATCH 00/20] Coresight integration with perf Mathieu Poirier
                   ` (10 preceding siblings ...)
  2015-09-18 16:26 ` [RFC PATCH 11/20] coresight: making coresight_build_paths() public Mathieu Poirier
@ 2015-09-18 16:26 ` Mathieu Poirier
  2015-09-18 16:26 ` [RFC PATCH 13/20] coresight: etm-perf: new PMU driver for ETM tracers Mathieu Poirier
                   ` (10 subsequent siblings)
  22 siblings, 0 replies; 48+ messages in thread
From: Mathieu Poirier @ 2015-09-18 16:26 UTC (permalink / raw)
  To: gregkh, a.p.zijlstra, alexander.shishkin, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

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


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 13/20] coresight: etm-perf: new PMU driver for ETM tracers
  2015-09-18 16:26 [RFC PATCH 00/20] Coresight integration with perf Mathieu Poirier
                   ` (11 preceding siblings ...)
  2015-09-18 16:26 ` [RFC PATCH 12/20] coresight: keeping track of enabled sink buffers Mathieu Poirier
@ 2015-09-18 16:26 ` Mathieu Poirier
  2015-09-18 16:26 ` [RFC PATCH 14/20] coresight: etm-perf: implementing 'event_init()' API Mathieu Poirier
                   ` (9 subsequent siblings)
  22 siblings, 0 replies; 48+ messages in thread
From: Mathieu Poirier @ 2015-09-18 16:26 UTC (permalink / raw)
  To: gregkh, a.p.zijlstra, alexander.shishkin, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

Perf is a well known and used tool for performance monitoring
and much more. A such it is an ideal condaditate for integration
with coresight based HW tracing.

This patch introduce a minimal PMU that represent a coresight
tracer to the Perf core.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
 MAINTAINERS                                      |  1 +
 drivers/hwtracing/coresight/Makefile             |  2 +-
 drivers/hwtracing/coresight/coresight-etm-perf.c | 65 ++++++++++++++++++++++++
 include/linux/coresight-pmu.h                    | 18 +++++++
 4 files changed, 85 insertions(+), 1 deletion(-)
 create mode 100644 drivers/hwtracing/coresight/coresight-etm-perf.c
 create mode 100644 include/linux/coresight-pmu.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 7ba7ab749c85..b462a90a256d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -989,6 +989,7 @@ ARM/CORESIGHT FRAMEWORK AND DRIVERS
 M:	Mathieu Poirier <mathieu.poirier@linaro.org>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
+F:	include/linux/coresight*
 F:	drivers/hwtracing/coresight/*
 F:	Documentation/trace/coresight.txt
 F:	Documentation/devicetree/bindings/arm/coresight.txt
diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
index 99f8e5f6256e..2ab2627060a4 100644
--- a/drivers/hwtracing/coresight/Makefile
+++ b/drivers/hwtracing/coresight/Makefile
@@ -1,7 +1,7 @@
 #
 # Makefile for CoreSight drivers.
 #
-obj-$(CONFIG_CORESIGHT) += coresight.o
+obj-$(CONFIG_CORESIGHT) += coresight.o coresight-etm-perf.o
 obj-$(CONFIG_OF) += of_coresight.o
 obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o
 obj-$(CONFIG_CORESIGHT_SINK_TPIU) += coresight-tpiu.o
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
new file mode 100644
index 000000000000..759b8d69b4e6
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright(C) 2015 Linaro Limited. All rights reserved.
+ * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/perf_event.h>
+#include <linux/mm.h>
+#include <linux/list.h>
+
+#include <linux/coresight.h>
+#include <linux/coresight-pmu.h>
+
+#include "coresight-priv.h"
+
+static struct pmu etm_pmu;
+
+/* ETMCR is 'config' */
+PMU_FORMAT_ATTR(cycacc,		"config:12");
+PMU_FORMAT_ATTR(timestamp,	"config:28");
+
+static struct attribute *etm_config_formats_attr[] = {
+	&format_attr_cycacc.attr,
+	&format_attr_timestamp.attr,
+	NULL,
+};
+
+static struct attribute_group etm_pmu_format_group = {
+	.name   = "format",
+	.attrs  = etm_config_formats_attr,
+};
+
+static const struct attribute_group *etm_pmu_attr_groups[] = {
+	&etm_pmu_format_group,
+	NULL,
+};
+
+static void etm_event_read(struct perf_event *event) {}
+
+static int __init etm_perf_init(void)
+{
+	etm_pmu.capabilities	= PERF_PMU_CAP_EXCLUSIVE;
+
+	etm_pmu.attr_groups	= etm_pmu_attr_groups;
+	etm_pmu.task_ctx_nr	= perf_sw_context;
+	etm_pmu.read		= etm_event_read;
+
+	return perf_pmu_register(&etm_pmu, CORESIGHT_ETM_PMU_NAME, -1);
+}
+module_init(etm_perf_init);
diff --git a/include/linux/coresight-pmu.h b/include/linux/coresight-pmu.h
new file mode 100644
index 000000000000..261361060f0b
--- /dev/null
+++ b/include/linux/coresight-pmu.h
@@ -0,0 +1,18 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _LINUX_CORESIGHT_PMU_H
+#define _LINUX_CORESIGHT_PMU_H
+
+#define CORESIGHT_ETM_PMU_NAME	"cs_etm"
+
+#endif
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 14/20] coresight: etm-perf: implementing 'event_init()' API
  2015-09-18 16:26 [RFC PATCH 00/20] Coresight integration with perf Mathieu Poirier
                   ` (12 preceding siblings ...)
  2015-09-18 16:26 ` [RFC PATCH 13/20] coresight: etm-perf: new PMU driver for ETM tracers Mathieu Poirier
@ 2015-09-18 16:26 ` Mathieu Poirier
  2015-09-22 14:29   ` Alexander Shishkin
  2015-09-18 16:26 ` [RFC PATCH 15/20] coresight: etm-perf: implementing 'setup_aux()' API Mathieu Poirier
                   ` (8 subsequent siblings)
  22 siblings, 1 reply; 48+ messages in thread
From: Mathieu Poirier @ 2015-09-18 16:26 UTC (permalink / raw)
  To: gregkh, a.p.zijlstra, alexander.shishkin, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

Enhancing skeleton PMU with event initialisation.

The function makes sure tracers aren't already enabled
before going through with the powe up and configuration
sequences.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
 drivers/hwtracing/coresight/coresight-etm-perf.c | 176 +++++++++++++++++++++++
 1 file changed, 176 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index 759b8d69b4e6..a21171a3e929 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -30,6 +30,9 @@
 
 static struct pmu etm_pmu;
 
+static DEFINE_PER_CPU(struct coresight_device *, csdev_src);
+static DEFINE_PER_CPU(struct coresight_device *, csdev_sink);
+
 /* ETMCR is 'config' */
 PMU_FORMAT_ATTR(cycacc,		"config:12");
 PMU_FORMAT_ATTR(timestamp,	"config:28");
@@ -52,6 +55,178 @@ static const struct attribute_group *etm_pmu_attr_groups[] = {
 
 static void etm_event_read(struct perf_event *event) {}
 
+static int etm_event_power_single_source(int source, bool power)
+{
+	int ret = 0;
+	LIST_HEAD(path);
+	LIST_HEAD(sinks);
+	struct coresight_device *csdev;
+
+	csdev = per_cpu(csdev_src, source);
+
+	if (!csdev)
+		return -EINVAL;
+
+	if (csdev->type != CORESIGHT_DEV_TYPE_SOURCE)
+		return -EINVAL;
+
+	if (power) {
+		ret = source_ops(csdev)->poweron(csdev);
+		if (ret)
+			goto out;
+
+		ret = coresight_build_paths(csdev, &path, &sinks, true);
+		if (ret) {
+			dev_dbg(&csdev->dev, "creating path(s) failed\n");
+			source_ops(csdev)->poweroff(csdev);
+		}
+
+		/* Everything is good, record first enabled sink buffer */
+		per_cpu(csdev_sink, source) =
+			list_first_entry(&sinks,
+					 struct coresight_device, sinks);
+	} else {
+		source_ops(csdev)->poweroff(csdev);
+		ret = coresight_build_paths(csdev, &path, NULL, false);
+		if (ret)
+			dev_dbg(&csdev->dev, "releasing path(s) failed\n");
+	}
+
+out:
+	return ret;
+}
+
+static int etm_event_power_sources(int source, bool power)
+{
+	int cpu, ret;
+
+	if (source < -1 || source >= nr_cpu_ids)
+		return -EINVAL;
+
+	/* source == -1 is for all CPUs. */
+	if (source != -1) {
+		/* power up/down one source */
+		ret = etm_event_power_single_source(source, power);
+		goto out;
+	}
+
+	/* same process as above, but for all CPUs */
+	for_each_online_cpu(cpu) {
+		ret = etm_event_power_single_source(cpu, power);
+		if (ret)
+			break;
+	}
+
+out:
+	return ret;
+}
+
+static int etm_event_config_single_source(int source)
+{
+	struct coresight_device *csdev;
+
+	csdev = per_cpu(csdev_src, source);
+
+	if (!csdev)
+		return -EINVAL;
+
+	if (csdev->type != CORESIGHT_DEV_TYPE_SOURCE)
+		return -EINVAL;
+
+	return source_ops(csdev)->configure(csdev);
+}
+
+static int etm_event_config_sources(int source)
+{
+	int cpu, ret;
+
+	if (source < -1 || source >= nr_cpu_ids)
+		return -EINVAL;
+
+	/* source == -1 is for all CPUs. */
+	if (source != -1) {
+		/* configure one source */
+		ret = etm_event_config_single_source(source);
+		goto out;
+	}
+
+	/* same process as above, but for all CPUs */
+	for_each_online_cpu(cpu) {
+		ret = etm_event_config_single_source(cpu);
+		if (ret)
+			goto reset;
+	}
+
+out:
+	return ret;
+reset:
+	for_each_online_cpu(cpu)
+		etm_event_power_sources(cpu, false);
+	goto out;
+}
+
+static bool etm_event_source_single_enabled(int source)
+{
+	struct coresight_device *csdev = per_cpu(csdev_src, source);
+
+	if (!csdev)
+		return true;
+
+	return source_ops(csdev)->is_enabled(csdev);
+}
+
+static bool etm_event_source_enabled(int source)
+{
+	int cpu;
+
+	if (source != -1)
+		return etm_event_source_single_enabled(source);
+
+	for_each_online_cpu(cpu) {
+		if (etm_event_source_single_enabled(cpu))
+			return true;
+	}
+
+	return false;
+}
+
+static void etm_event_destroy(struct perf_event *event)
+{
+	/* switching off the source will also tear down the path */
+	etm_event_power_sources(event->cpu, false);
+}
+
+static int etm_event_init(struct perf_event *event)
+{
+	int ret;
+
+	if (event->attr.type != etm_pmu.type)
+		return -ENOENT;
+
+	if (event->cpu >= nr_cpu_ids)
+		return -EINVAL;
+
+	/* only one session at a time */
+	if (etm_event_source_enabled(event->cpu))
+		return -EBUSY;
+
+	/*
+	 * Make sure CPUs don't disappear between the
+	 * power up sequence and configuration.
+	 */
+	get_online_cpus();
+	ret = etm_event_power_sources(event->cpu, true);
+	if (ret)
+		goto out;
+
+	ret = etm_event_config_sources(event->cpu);
+
+	event->destroy = etm_event_destroy;
+out:
+	put_online_cpus();
+	return ret;
+}
+
 static int __init etm_perf_init(void)
 {
 	etm_pmu.capabilities	= PERF_PMU_CAP_EXCLUSIVE;
@@ -59,6 +234,7 @@ static int __init etm_perf_init(void)
 	etm_pmu.attr_groups	= etm_pmu_attr_groups;
 	etm_pmu.task_ctx_nr	= perf_sw_context;
 	etm_pmu.read		= etm_event_read;
+	etm_pmu.event_init	= etm_event_init;
 
 	return perf_pmu_register(&etm_pmu, CORESIGHT_ETM_PMU_NAME, -1);
 }
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 15/20] coresight: etm-perf: implementing 'setup_aux()' API
  2015-09-18 16:26 [RFC PATCH 00/20] Coresight integration with perf Mathieu Poirier
                   ` (13 preceding siblings ...)
  2015-09-18 16:26 ` [RFC PATCH 14/20] coresight: etm-perf: implementing 'event_init()' API Mathieu Poirier
@ 2015-09-18 16:26 ` Mathieu Poirier
  2015-09-30 11:50   ` Alexander Shishkin
  2015-09-18 16:26 ` [RFC PATCH 16/20] coresight: etm-perf: implementing trace related APIs Mathieu Poirier
                   ` (7 subsequent siblings)
  22 siblings, 1 reply; 48+ messages in thread
From: Mathieu Poirier @ 2015-09-18 16:26 UTC (permalink / raw)
  To: gregkh, a.p.zijlstra, alexander.shishkin, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

Before trace can be collected the PMU needs to get a handle
on the mmpap'ed memory that was granted.  Since the collection
of traces can be done by sink buffers of various types,
representation of the memory layout is done at the sink level
rather than the tracer PMU driver.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
 drivers/hwtracing/coresight/coresight-etm-perf.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index a21171a3e929..3aeb4215bb22 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -227,6 +227,27 @@ out:
 	return ret;
 }
 
+static void *etm_setup_aux(int cpu, void **pages,
+			      int nr_pages, bool overwrite)
+{
+	struct coresight_device *csdev;
+
+	if (cpu == -1)
+		cpu = smp_processor_id();
+
+	csdev = per_cpu(csdev_sink, cpu);
+	if (!csdev)
+		return NULL;
+
+	return sink_ops(csdev)->setup_aux(csdev, cpu, pages,
+					  nr_pages, overwrite);
+}
+
+static void etm_free_aux(void *data)
+{
+	kfree(data);
+}
+
 static int __init etm_perf_init(void)
 {
 	etm_pmu.capabilities	= PERF_PMU_CAP_EXCLUSIVE;
@@ -235,6 +256,8 @@ static int __init etm_perf_init(void)
 	etm_pmu.task_ctx_nr	= perf_sw_context;
 	etm_pmu.read		= etm_event_read;
 	etm_pmu.event_init	= etm_event_init;
+	etm_pmu.setup_aux	= etm_setup_aux;
+	etm_pmu.free_aux	= etm_free_aux;
 
 	return perf_pmu_register(&etm_pmu, CORESIGHT_ETM_PMU_NAME, -1);
 }
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 16/20] coresight: etm-perf: implementing trace related APIs
  2015-09-18 16:26 [RFC PATCH 00/20] Coresight integration with perf Mathieu Poirier
                   ` (14 preceding siblings ...)
  2015-09-18 16:26 ` [RFC PATCH 15/20] coresight: etm-perf: implementing 'setup_aux()' API Mathieu Poirier
@ 2015-09-18 16:26 ` Mathieu Poirier
  2015-09-18 16:26 ` [RFC PATCH 17/20] coresight: etm-perf: adding symbolic link for CPUs Mathieu Poirier
                   ` (6 subsequent siblings)
  22 siblings, 0 replies; 48+ messages in thread
From: Mathieu Poirier @ 2015-09-18 16:26 UTC (permalink / raw)
  To: gregkh, a.p.zijlstra, alexander.shishkin, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

Implementing the API that connect trace control, i.e initiation
and termination, to the Perf core.  That way trace collection can
be started when the process it is associated to is executed by
a CPU, and stopped when yanked away.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
 drivers/hwtracing/coresight/coresight-etm-perf.c | 97 ++++++++++++++++++++++++
 1 file changed, 97 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index 3aeb4215bb22..edacf4b1d0bc 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -30,6 +30,7 @@
 
 static struct pmu etm_pmu;
 
+static DEFINE_PER_CPU(struct perf_output_handle, ctx_handle);
 static DEFINE_PER_CPU(struct coresight_device *, csdev_src);
 static DEFINE_PER_CPU(struct coresight_device *, csdev_sink);
 
@@ -248,6 +249,98 @@ static void etm_free_aux(void *data)
 	kfree(data);
 }
 
+static void etm_event_stop(struct perf_event *event, int mode)
+{
+	int cpu = smp_processor_id();
+	struct coresight_device *src = per_cpu(csdev_src, cpu);
+	struct coresight_device *sink = per_cpu(csdev_sink, cpu);
+
+	if (event->hw.state == PERF_HES_STOPPED)
+		return;
+
+	if (!src || !sink)
+		return;
+
+	/* stop tracer */
+	if (source_ops(src)->trace_enable(src, false))
+		return;
+
+	/* tell the core */
+	event->hw.state = PERF_HES_STOPPED;
+
+
+	if (mode & PERF_EF_UPDATE) {
+		struct perf_output_handle *handle = this_cpu_ptr(&ctx_handle);
+
+		if (WARN_ON_ONCE(handle->event != event))
+			return;
+
+		/* update trace information */
+		sink_ops(sink)->update_buffer(sink, handle);
+	}
+}
+
+static void etm_event_start(struct perf_event *event, int flags)
+{
+	int cpu = smp_processor_id();
+	struct coresight_device *csdev = per_cpu(csdev_src, cpu);
+
+	if (!csdev)
+		goto fail;
+
+	/* tell the perf core the event is alive */
+	event->hw.state = 0;
+
+	if (source_ops(csdev)->trace_enable(csdev, true))
+		goto fail;
+
+	return;
+
+fail:
+	event->hw.state = PERF_HES_STOPPED;
+}
+
+static void etm_event_del(struct perf_event *event, int mode)
+{
+	int cpu = smp_processor_id();
+	struct perf_output_handle *handle = this_cpu_ptr(&ctx_handle);
+	struct coresight_device *csdev = per_cpu(csdev_sink, cpu);
+
+	if (!csdev)
+		return;
+
+	etm_event_stop(event, PERF_EF_UPDATE);
+	sink_ops(csdev)->unset_buffer(csdev, handle);
+}
+
+static int etm_event_add(struct perf_event *event, int mode)
+{
+	int ret, cpu = smp_processor_id();
+	struct perf_output_handle *handle = this_cpu_ptr(&ctx_handle);
+	struct hw_perf_event *hwc = &event->hw;
+	struct coresight_device *csdev = per_cpu(csdev_sink, cpu);
+
+	if (!csdev)
+		return -EINVAL;
+
+	if (handle->event)
+		return -EBUSY;
+
+	ret = sink_ops(csdev)->set_buffer(csdev, event, handle);
+	if (ret)
+		return ret;
+
+	if (mode & PERF_EF_START) {
+		etm_event_start(event, 0);
+		if (hwc->state & PERF_HES_STOPPED) {
+			etm_event_del(event, 0);
+			return -EBUSY;
+		}
+	}
+
+	return 0;
+}
+
 static int __init etm_perf_init(void)
 {
 	etm_pmu.capabilities	= PERF_PMU_CAP_EXCLUSIVE;
@@ -258,6 +351,10 @@ static int __init etm_perf_init(void)
 	etm_pmu.event_init	= etm_event_init;
 	etm_pmu.setup_aux	= etm_setup_aux;
 	etm_pmu.free_aux	= etm_free_aux;
+	etm_pmu.stop		= etm_event_stop;
+	etm_pmu.start		= etm_event_start;
+	etm_pmu.del		= etm_event_del;
+	etm_pmu.add		= etm_event_add;
 
 	return perf_pmu_register(&etm_pmu, CORESIGHT_ETM_PMU_NAME, -1);
 }
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 17/20] coresight: etm-perf: adding symbolic link for CPUs
  2015-09-18 16:26 [RFC PATCH 00/20] Coresight integration with perf Mathieu Poirier
                   ` (15 preceding siblings ...)
  2015-09-18 16:26 ` [RFC PATCH 16/20] coresight: etm-perf: implementing trace related APIs Mathieu Poirier
@ 2015-09-18 16:26 ` Mathieu Poirier
  2015-09-18 16:26 ` [RFC PATCH 18/20] coresight: etm3x: pushing down perf configuration to tracer Mathieu Poirier
                   ` (5 subsequent siblings)
  22 siblings, 0 replies; 48+ messages in thread
From: Mathieu Poirier @ 2015-09-18 16:26 UTC (permalink / raw)
  To: gregkh, a.p.zijlstra, alexander.shishkin, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

Other than probing each device entry under /sys/bus/coresight/devices/,
there is no way for user space to know which CPU is associated to which
tracer.  But knowing those association is important to discover tracer
specifics and configuration options.

As such introducing a symbolic link under
/sys/bus/event_source/devices/cs_etm/cpuX that reference the coresight
device a CPU is associated with.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
 drivers/hwtracing/coresight/coresight-etm-perf.c | 22 +++++++++++++++++++
 drivers/hwtracing/coresight/coresight-etm-perf.h | 27 ++++++++++++++++++++++++
 drivers/hwtracing/coresight/coresight-etm3x.c    |  6 ++++++
 3 files changed, 55 insertions(+)
 create mode 100644 drivers/hwtracing/coresight/coresight-etm-perf.h

diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index edacf4b1d0bc..de0198e72603 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -341,6 +341,28 @@ static int etm_event_add(struct perf_event *event, int mode)
 	return 0;
 }
 
+int etm_perf_symlink(struct coresight_device *csdev, bool link)
+{
+	char entry[sizeof("cpu9999999")];
+	int ret = 0, cpu = source_ops(csdev)->cpu_id(csdev);
+	struct device *pmu_dev = etm_pmu.dev;
+	struct device *cs_dev = &csdev->dev;
+
+	sprintf(entry, "cpu%d", cpu);
+
+	if (link) {
+		ret = sysfs_create_link(&pmu_dev->kobj, &cs_dev->kobj, entry);
+		if (ret)
+			return ret;
+		per_cpu(csdev_src, cpu) = csdev;
+	} else {
+		sysfs_remove_link(&pmu_dev->kobj, entry);
+		per_cpu(csdev_src, cpu) = NULL;
+	}
+
+	return 0;
+}
+
 static int __init etm_perf_init(void)
 {
 	etm_pmu.capabilities	= PERF_PMU_CAP_EXCLUSIVE;
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.h b/drivers/hwtracing/coresight/coresight-etm-perf.h
new file mode 100644
index 000000000000..4dd900f2362a
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.h
@@ -0,0 +1,27 @@
+/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CORESIGHT_ETM_PERF_H
+#define _CORESIGHT_ETM_PERF_H
+
+struct coresight_device;
+
+#ifdef CONFIG_CORESIGHT
+int etm_perf_symlink(struct coresight_device *csdev, bool link);
+
+#else
+static inline int etm_perf_symlink(struct coresight_device *csdev, bool link)
+{ return -EINVAL; }
+
+#endif /* CONFIG_CORESIGHT */
+
+#endif
diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c
index a4c158df0fef..6a44ea330a4a 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x.c
@@ -34,6 +34,7 @@
 #include <asm/sections.h>
 
 #include "coresight-etm.h"
+#include "coresight-etm-perf.h"
 
 static int boot_enable;
 module_param_named(boot_enable, boot_enable, int, S_IRUGO);
@@ -1995,6 +1996,11 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id)
 		goto err_arch_supported;
 	}
 
+	if (etm_perf_symlink(drvdata->csdev, true)) {
+		ret = -EPROBE_DEFER;
+		goto err_arch_supported;
+	}
+
 	pm_runtime_put(&adev->dev);
 	dev_info(dev, "%s initialized\n", (char *)id->data);
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 18/20] coresight: etm3x: pushing down perf configuration to tracer
  2015-09-18 16:26 [RFC PATCH 00/20] Coresight integration with perf Mathieu Poirier
                   ` (16 preceding siblings ...)
  2015-09-18 16:26 ` [RFC PATCH 17/20] coresight: etm-perf: adding symbolic link for CPUs Mathieu Poirier
@ 2015-09-18 16:26 ` Mathieu Poirier
  2015-09-30 12:45   ` Alexander Shishkin
  2015-09-18 16:26 ` [RFC PATCH 19/20] coresight: etm3x: implementing perf's user/kernel mode Mathieu Poirier
                   ` (4 subsequent siblings)
  22 siblings, 1 reply; 48+ messages in thread
From: Mathieu Poirier @ 2015-09-18 16:26 UTC (permalink / raw)
  To: gregkh, a.p.zijlstra, alexander.shishkin, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

The perf command line tool supports configuration for cycle
accurate and timestamps.  Configuration for those field is
found in the 'config' field of the event configuration
attributes.

Since the bit fields were organised to match,
the only thing that is needed is to make sure no extra
fields were set.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
 drivers/hwtracing/coresight/coresight-etm-perf.c | 12 +++++------
 drivers/hwtracing/coresight/coresight-etm3x.c    | 27 +++++++++++++++++++++++-
 include/linux/coresight.h                        |  3 ++-
 3 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index de0198e72603..a662842f3327 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -122,7 +122,7 @@ out:
 	return ret;
 }
 
-static int etm_event_config_single_source(int source)
+static int etm_event_config_single_source(int source, struct perf_event *event)
 {
 	struct coresight_device *csdev;
 
@@ -134,10 +134,10 @@ static int etm_event_config_single_source(int source)
 	if (csdev->type != CORESIGHT_DEV_TYPE_SOURCE)
 		return -EINVAL;
 
-	return source_ops(csdev)->configure(csdev);
+	return source_ops(csdev)->configure(csdev, event);
 }
 
-static int etm_event_config_sources(int source)
+static int etm_event_config_sources(int source, struct perf_event *event)
 {
 	int cpu, ret;
 
@@ -147,13 +147,13 @@ static int etm_event_config_sources(int source)
 	/* source == -1 is for all CPUs. */
 	if (source != -1) {
 		/* configure one source */
-		ret = etm_event_config_single_source(source);
+		ret = etm_event_config_single_source(source, event);
 		goto out;
 	}
 
 	/* same process as above, but for all CPUs */
 	for_each_online_cpu(cpu) {
-		ret = etm_event_config_single_source(cpu);
+		ret = etm_event_config_single_source(cpu, event);
 		if (ret)
 			goto reset;
 	}
@@ -220,7 +220,7 @@ static int etm_event_init(struct perf_event *event)
 	if (ret)
 		goto out;
 
-	ret = etm_event_config_sources(event->cpu);
+	ret = etm_event_config_sources(event->cpu, event);
 
 	event->destroy = etm_event_destroy;
 out:
diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c
index 6a44ea330a4a..077b49714259 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x.c
@@ -313,6 +313,25 @@ static void etm_power_down(struct coresight_device *csdev)
 	pm_runtime_put(csdev->dev.parent);
 }
 
+#define ETM3X_SUPPORTED_OPTIONS (ETMCR_CYC_ACC | ETMCR_TIMESTAMP_EN)
+
+static int etm_parse_event_config(struct etm_drvdata *drvdata,
+				  struct perf_event *event)
+{
+	u64 config = event->attr.config;
+
+	/*
+	 * At this time only cycle accurate and timestamp options are
+	 * available.  As such clear everything else that may have been
+	 * configured and set the ETM control register based on what was
+	 * requested.
+	 */
+	config &= ETM3X_SUPPORTED_OPTIONS;
+	drvdata->ctrl = config;
+
+	return 0;
+}
+
 /**
  * etm_configure_cpu - configure ETM registers
  * @csdev - the etm that needs to be configure.
@@ -334,6 +353,8 @@ static void etm_configure_cpu(void *info)
 	etm_set_prog(drvdata);
 
 	etmcr = etm_readl(drvdata, ETMCR);
+	/* Clear setting from a previous run if need be */
+	etmcr &= ~ETM3X_SUPPORTED_OPTIONS;
 	etmcr |= drvdata->port_size;
 	etmcr |= ETMCR_ETM_EN;
 	etm_writel(drvdata, drvdata->ctrl | etmcr, ETMCR);
@@ -379,10 +400,14 @@ static void etm_configure_cpu(void *info)
 	CS_LOCK(drvdata->base);
 }
 
-static int etm_configure(struct coresight_device *csdev)
+static int etm_configure(struct coresight_device *csdev,
+			 struct perf_event *event)
 {
 	struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
+	if (etm_parse_event_config(drvdata, event))
+		return -EINVAL;
+
 	return smp_call_function_single(drvdata->cpu,
 					etm_configure_cpu, csdev, 1);
 }
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index da76b2951f10..e1a14c84082f 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -237,7 +237,8 @@ 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);
+	int (*configure)(struct coresight_device *csdev,
+			 struct perf_event *event);
 	int (*trace_enable)(struct coresight_device *csdev, bool enable);
 	int (*enable)(struct coresight_device *csdev);
 	void (*disable)(struct coresight_device *csdev);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 19/20] coresight: etm3x: implementing perf's user/kernel mode
  2015-09-18 16:26 [RFC PATCH 00/20] Coresight integration with perf Mathieu Poirier
                   ` (17 preceding siblings ...)
  2015-09-18 16:26 ` [RFC PATCH 18/20] coresight: etm3x: pushing down perf configuration to tracer Mathieu Poirier
@ 2015-09-18 16:26 ` Mathieu Poirier
  2015-09-30 10:16   ` Alexander Shishkin
  2015-09-18 16:26 ` [RFC PATCH 20/20] coresight: updating documentation to reflect integration with perf Mathieu Poirier
                   ` (3 subsequent siblings)
  22 siblings, 1 reply; 48+ messages in thread
From: Mathieu Poirier @ 2015-09-18 16:26 UTC (permalink / raw)
  To: gregkh, a.p.zijlstra, alexander.shishkin, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

Configure tracers in accordance with the specification conveyed
by the perf cmd line tool.  For example if only user space is
requested, configure the address range comparator with the kerne's
address range and set the 'exclude' bit, which will result in
tracing everything except the kernel.

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

diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c
index 077b49714259..2f818dbde099 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x.c
@@ -320,6 +320,41 @@ static int etm_parse_event_config(struct etm_drvdata *drvdata,
 {
 	u64 config = event->attr.config;
 
+	if (event->attr.exclude_kernel || event->attr.exclude_user) {
+		u32 event_encoding;
+		u32 flags = (1 << 0 | /* instruction execute*/
+			     3 << 3 | /* ARM instruction */
+			     0 << 5 | /* No data value comparison */
+			     0 << 7 | /* No exact mach */
+			     0 << 8 | /* Ignore context ID */
+			     0 << 10); /* Security ignored */
+
+		/* Bit 0 is address range comparator 1 */
+		drvdata->enable_ctrl1 = ETMTECR1_ADDR_COMP_1;
+
+		/* Bit 24 controls whether the address range should be
+		 * included or excluded.
+		 */
+		if (event->attr.exclude_kernel)
+			drvdata->enable_ctrl1 |= BIT(24);
+
+		/* No need to worry about single address comparators */
+		drvdata->enable_ctrl2 = 0x0;
+
+		drvdata->addr_val[0] = (u32) _stext;
+		drvdata->addr_val[1] = (u32) _etext;
+		drvdata->addr_acctype[0] = flags;
+		drvdata->addr_acctype[1] = flags;
+		drvdata->addr_type[0] = ETM_ADDR_TYPE_RANGE;
+		drvdata->addr_type[1] = ETM_ADDR_TYPE_RANGE;
+
+		event_encoding = 0x00 << 14 | /* Boolean function select A */
+				 0x01 << 4  | /* Addr range comparator 0-7 */
+				 0x00 << 0;   /* Addr range comparator 1 */
+
+		drvdata->enable_event = event_encoding;
+	}
+
 	/*
 	 * At this time only cycle accurate and timestamp options are
 	 * available.  As such clear everything else that may have been
@@ -362,6 +397,7 @@ static void etm_configure_cpu(void *info)
 	etm_writel(drvdata, drvdata->startstop_ctrl, ETMTSSCR);
 	etm_writel(drvdata, drvdata->enable_event, ETMTEEVR);
 	etm_writel(drvdata, drvdata->enable_ctrl1, ETMTECR1);
+	etm_writel(drvdata, drvdata->enable_ctrl2, ETMTECR2);
 	etm_writel(drvdata, drvdata->fifofull_level, ETMFFLR);
 	for (i = 0; i < drvdata->nr_addr_cmp; i++) {
 		etm_writel(drvdata, drvdata->addr_val[i], ETMACVRn(i));
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [RFC PATCH 20/20] coresight: updating documentation to reflect integration with perf
  2015-09-18 16:26 [RFC PATCH 00/20] Coresight integration with perf Mathieu Poirier
                   ` (18 preceding siblings ...)
  2015-09-18 16:26 ` [RFC PATCH 19/20] coresight: etm3x: implementing perf's user/kernel mode Mathieu Poirier
@ 2015-09-18 16:26 ` Mathieu Poirier
  2015-09-19 10:09   ` Ingo Molnar
  2015-09-30  8:52 ` [RFC PATCH 00/20] Coresight " Alexander Shishkin
                   ` (2 subsequent siblings)
  22 siblings, 1 reply; 48+ messages in thread
From: Mathieu Poirier @ 2015-09-18 16:26 UTC (permalink / raw)
  To: gregkh, a.p.zijlstra, alexander.shishkin, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

Adding a new section giving information on how coresight has been
integrated with the perf subsystem along with a general idea of how
to control tracing from the perf tool cmd line.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
 Documentation/trace/coresight.txt | 116 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 113 insertions(+), 3 deletions(-)

diff --git a/Documentation/trace/coresight.txt b/Documentation/trace/coresight.txt
index 0a5c3290e732..330020082b02 100644
--- a/Documentation/trace/coresight.txt
+++ b/Documentation/trace/coresight.txt
@@ -193,10 +193,120 @@ the information carried in "THIS_MODULE".
 How to use
 ----------
 
-Before trace collection can start, a coresight sink needs to be identify.
-There is no limit on the amount of sinks (nor sources) that can be enabled at
+There is two ways to use the coresight framework: 1) using the perf cmd line
+tool and 2) interacting directly with the coresight devices using the sysFS
+interface.  The latter will slowly be faded out as more functionality become
+available from the perf cmd line tool but for the time being both are still
+supported.  The following sections provide details on using both methods.
+
+1) Using perf framework:
+
+Coresight tracers like ETM and PTM are represented using the Perf framework's
+Performance Monitoring Unit (PMU).  As such the perf framework takes charge of
+controlling when tracing happens based on when the process(es) of interest are
+scheduled.  When configure in a system, Coresight PMUs will be listed when
+queried by the perf command line tool:
+
+linaro@linaro-nano:~$ ./perf list pmu
+
+List of pre-defined events (to be used in -e):
+
+  cs_etm//                                           [Kernel PMU event]
+
+linaro@linaro-nano:~$
+
+Regardless of the amnout ETM/PTM IP block in a system (usually equal to the
+amount of processor core), the "cs_etm" PMU will be listed only once.
+
+Before a trace can be configured and started a Coresight sink needs to be
+selected using the sysFS method (see below).  This is only temporary until
+sink selection can be made from the command line tool.
+
+linaro@linaro-nano:~$ ls /sys/bus/coresight/devices
+20010000.etb  20030000.tpiu  20040000.funnel  2201c000.ptm
+2201d000.ptm  2203c000.etm  2203d000.etm  2203e000.etm  replicator
+
+linaro@linaro-nano:~$ echo 1 > /sys/bus/coresight/devices/20010000.etb/enable_sink
+
+Once a sink has been selected configuring a Coresight PMU works the same way as
+any other PMU.  As such tracing can happen for a single CPU, a group of CPU, per
+thread or a combination of those:
+
+linaro@linaro-nano:~$ perf record -e cs_etm// --per-thread <command>
+
+linaro@linaro-nano:~$ perf record -C 0,2-3 -e cs_etm// <command>
+
+Tracing limited to user and kernel space can also be used to narrow the amount
+of collected tracers:
+
+linaro@linaro-nano:~$ perf record -e cs_etm//u --per-thread <command>
+
+linaro@linaro-nano:~$ perf record -C 0,2-3 -e cs_etm//k <command>
+
+As of this writing two ETM/PTM specific options have are available: cycle
+accurate and timestamp (please refer to the Embedded Trace Macrocell reference
+manual for details on these options).  By default both are disabled but using
+the "cycacc" and "timestamp" mnemonic within the double '/' will see those
+options configure for the upcoming trace run:
+
+linaro@linaro-nano:~$ perf record -e cs_etm/cycacc/ --per-thread <command>
+
+linaro@linaro-nano:~$ perf record -C 0,2-3 -e cs_etm/cycacc,timestamp/ <command>
+
+The Coresight PMUs can be configured to work in "full trace" or "snapshot" mode.
+In full trace mode trade acquisition is enable from beginning to end with trace
+data being recorded continuously:
+
+linaro@linaro-nano:~$ perf record -e cs_etm// dd if=/dev/random of=./test.txt bs=1k count=1000
+
+Since this can lead to a significant amount of data and that some device are
+limited in disk space snapshot mode can be used instead.  In snapshot mode
+traces are still collected in the ring buffer but not communicated to user
+space.  The ring buffer is allowed to wrap around, providing the latest
+information before an event of interest happens.  Significant events are
+communicated by sending a USR2 signal to the user space command line tool.
+From there the tool will stop trace collection and harvest data from the ring
+buffer before re-enabling traces.  Snapshot mode can be invoked using '-S' when
+launching a trace collection:
+
+linaro@linaro-nano:~$ perf record -S -e cs_etm// dd if=/dev/random of=./test.txt bs=1k count=1000
+
+Trace data collected during trace runs end up in the centennial "perf.data"
+file. Trace configuration information necessary for trace decoding are also
+embedded in the "perf.data" file.  Two new headers, 'PERF_RECORD_AUXTRACE_INFO'
+and 'PERF_RECORD_AUXTRACE' have been added to list of event types in order to
+find out where the different sections start.
+
+It is worth nothing that a set of metadata information exists for each tracer
+that participated in a trace run.  As such if 5 processors have been engaged,
+5 set of metadata will be found in the perf.data file.  This is to ensure that
+tracer decompression tools have all the information they need in order to
+process the trace data.
+
+Metadata information is collected directly from the ETM/PTM management registers
+using the sysFS interface.  Since there is not way for the perf command line
+tool to associate a CPU with a tracer, a symbolic link has been created between
+the cs_etm sysFS event directory and each Coresight tracer:
+
+linaro@linaro-nano:~$ ls /sys/bus/event_source/devices/cs_etm
+cpu0  cpu1  cpu2  cpu3  cpu4  format  perf_event_mux_interval_ms
+power  subsystem  type  uevent
+
+linaro@linaro-nano:~$ ls /sys/bus/event_source/devices/cs_etm/cpu0/mgmt/
+etmccer  etmccr  etmcr  etmidr  etmscr  etmtecr1  etmtecr2
+etmteevr  etmtraceidr  etmtssvr
+
+2) Using the sysFS interface:
+
+Most, if not all, configuration registers are made available to users via the
+sysFS interface.  Until all coresight ETM drivers have been converted to perf,
+it will also be possible to start and stop traces from sysFS.
+
+As with the perf method described above, a coresight sink needs to be identify
+before trace collection can commence.  Using the sysFS method _only_, there is
+no limit on the amount of sinks (nor sources) that can be enabled at
 any given moment.  As a generic operation, all device pertaining to the sink
-class will have an "active" entry in sysfs:
+class will have an "enable_sink" entry in sysfs:
 
 root:/sys/bus/coresight/devices# ls
 replicator  20030000.tpiu    2201c000.ptm  2203c000.etm  2203e000.etm
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 20/20] coresight: updating documentation to reflect integration with perf
  2015-09-18 16:26 ` [RFC PATCH 20/20] coresight: updating documentation to reflect integration with perf Mathieu Poirier
@ 2015-09-19 10:09   ` Ingo Molnar
  0 siblings, 0 replies; 48+ messages in thread
From: Ingo Molnar @ 2015-09-19 10:09 UTC (permalink / raw)
  To: Mathieu Poirier
  Cc: gregkh, a.p.zijlstra, alexander.shishkin, acme, mingo, corbet,
	adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel


Looks like a pretty useful feature all around. While reading the description I 
noticed a few typos:

* Mathieu Poirier <mathieu.poirier@linaro.org> wrote:

> +Regardless of the amnout ETM/PTM IP block in a system (usually equal to the
> +amount of processor core), the "cs_etm" PMU will be listed only once.

s/amnout/amount

> +Tracing limited to user and kernel space can also be used to narrow the amount
> +of collected tracers:

s/tracers/traces

> +The Coresight PMUs can be configured to work in "full trace" or "snapshot" mode.
> +In full trace mode trade acquisition is enable from beginning to end with trace
> +data being recorded continuously:

s/trade acquisition/trace acquisition
s/is enable from/is enabled from

> +Since this can lead to a significant amount of data and that some device are
> +limited in disk space snapshot mode can be used instead.

s/and that some device are limited in disk space/
  and because some devices are limited in disk space

> +Trace data collected during trace runs end up in the centennial "perf.data"
> +file.

hey, perf isn't 100 years old! :-)

s/centennial/central ?

Also, 'data' is singular in this context, so I think:

s/data collected during trace runs end up in the
 /data collected during trace runs ends up in the


> [...] Trace configuration information necessary for trace decoding are also
> +embedded in the "perf.data" file.

s/are/is

>  Two new headers, 'PERF_RECORD_AUXTRACE_INFO'
> +and 'PERF_RECORD_AUXTRACE' have been added to list of event types in order to
> +find out where the different sections start.

s/to list of event types
 /to the list of event types

> +
> +It is worth nothing that a set of metadata information exists for each tracer
> +that participated in a trace run. [...]

s/nothing
 /noting

  As such if 5 processors have been engaged,
> +5 set of metadata will be found in the perf.data file.

s/5 set of metadata
 /5 sets of metadata

> +Metadata information is collected directly from the ETM/PTM management registers
> +using the sysFS interface.  Since there is not way for the perf command line
> +tool to associate a CPU with a tracer, a symbolic link has been created between
> +the cs_etm sysFS event directory and each Coresight tracer:

s/there is not way
 /there is no way

> +As with the perf method described above, a coresight sink needs to be identify
> +before trace collection can commence.

Btw., 'Coresight' is spelled in two different ways throughout this document: 
capitalized and non-capitalized. Please pick one variant and use it consistently.

>  any given moment.  As a generic operation, all device pertaining to the sink
> -class will have an "active" entry in sysfs:

s/all device pertaining to
 /all devices pertaining to

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 14/20] coresight: etm-perf: implementing 'event_init()' API
  2015-09-18 16:26 ` [RFC PATCH 14/20] coresight: etm-perf: implementing 'event_init()' API Mathieu Poirier
@ 2015-09-22 14:29   ` Alexander Shishkin
  2015-09-28 21:22     ` Mathieu Poirier
  0 siblings, 1 reply; 48+ messages in thread
From: Alexander Shishkin @ 2015-09-22 14:29 UTC (permalink / raw)
  To: Mathieu Poirier, gregkh, a.p.zijlstra, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

Mathieu Poirier <mathieu.poirier@linaro.org> writes:

> +static void etm_event_destroy(struct perf_event *event)
> +{
> +	/* switching off the source will also tear down the path */
> +	etm_event_power_sources(event->cpu, false);
> +}
> +
> +static int etm_event_init(struct perf_event *event)
> +{
> +	int ret;
> +
> +	if (event->attr.type != etm_pmu.type)
> +		return -ENOENT;
> +
> +	if (event->cpu >= nr_cpu_ids)
> +		return -EINVAL;
> +
> +	/* only one session at a time */
> +	if (etm_event_source_enabled(event->cpu))
> +		return -EBUSY;

Why is this the case? If you were to configure the event in pmu::add()
and deconfigure it in pmu::del(), like you already do with the buffer
part, you could handle as many sessions as you want.

> +
> +	/*
> +	 * Make sure CPUs don't disappear between the
> +	 * power up sequence and configuration.
> +	 */
> +	get_online_cpus();
> +	ret = etm_event_power_sources(event->cpu, true);
> +	if (ret)
> +		goto out;
> +
> +	ret = etm_event_config_sources(event->cpu);

This can be done in pmu::add(), if you can call directly into
etm_configure_cpu() or etm_config_enable() so that there's no cross-cpu
calling in between.

> +
> +	event->destroy = etm_event_destroy;
> +out:
> +	put_online_cpus();
> +	return ret;
> +}
> +
>  static int __init etm_perf_init(void)
>  {
>  	etm_pmu.capabilities	= PERF_PMU_CAP_EXCLUSIVE;
> @@ -59,6 +234,7 @@ static int __init etm_perf_init(void)
>  	etm_pmu.attr_groups	= etm_pmu_attr_groups;
>  	etm_pmu.task_ctx_nr	= perf_sw_context;
>  	etm_pmu.read		= etm_event_read;
> +	etm_pmu.event_init	= etm_event_init;
>  
>  	return perf_pmu_register(&etm_pmu, CORESIGHT_ETM_PMU_NAME, -1);
>  }

One general comment -- it would be slightly easier at least for me if
all the pmu related bits were in one patch.

Thanks,
--
Alex

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 14/20] coresight: etm-perf: implementing 'event_init()' API
  2015-09-22 14:29   ` Alexander Shishkin
@ 2015-09-28 21:22     ` Mathieu Poirier
  2015-09-30  9:43       ` Alexander Shishkin
  0 siblings, 1 reply; 48+ messages in thread
From: Mathieu Poirier @ 2015-09-28 21:22 UTC (permalink / raw)
  To: Alexander Shishkin
  Cc: Greg KH, a.p.zijlstra, Arnaldo Carvalho de Melo, Ingo Molnar,
	Jon Corbet, Adrian Hunter, Chunyan Zhang, Mike Leach,
	Tor Jeremiassen, Al Grant, Paweł Moll, linux-arm-kernel,
	linux-doc, linux-kernel

On 22 September 2015 at 08:29, Alexander Shishkin
<alexander.shishkin@linux.intel.com> wrote:
> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>
>> +static void etm_event_destroy(struct perf_event *event)
>> +{
>> +     /* switching off the source will also tear down the path */
>> +     etm_event_power_sources(event->cpu, false);
>> +}
>> +
>> +static int etm_event_init(struct perf_event *event)
>> +{
>> +     int ret;
>> +
>> +     if (event->attr.type != etm_pmu.type)
>> +             return -ENOENT;
>> +
>> +     if (event->cpu >= nr_cpu_ids)
>> +             return -EINVAL;
>> +
>> +     /* only one session at a time */
>> +     if (etm_event_source_enabled(event->cpu))
>> +             return -EBUSY;
>
> Why is this the case? If you were to configure the event in pmu::add()
> and deconfigure it in pmu::del(), like you already do with the buffer
> part, you could handle as many sessions as you want.

Apologies for the late reply, I was travelling.

We certainly don't want to have more than once trace session going on
at any given time, especially if the sessions have different
configuration parameters.  Moreover doing the tracer configuration as
part of pmu::add() is highly redundant.

>
>> +
>> +     /*
>> +      * Make sure CPUs don't disappear between the
>> +      * power up sequence and configuration.
>> +      */
>> +     get_online_cpus();
>> +     ret = etm_event_power_sources(event->cpu, true);
>> +     if (ret)
>> +             goto out;
>> +
>> +     ret = etm_event_config_sources(event->cpu);
>
> This can be done in pmu::add(), if you can call directly into
> etm_configure_cpu() or etm_config_enable() so that there's no cross-cpu
> calling in between.

As per my comment above, reconfiguring the tracers every time it is
about to run is redundant and extensive (etm_configure_cpu() isn't
exactly short),  incurring a cost that is likely to be higher than
calling get_online_cpus().

>
>> +
>> +     event->destroy = etm_event_destroy;
>> +out:
>> +     put_online_cpus();
>> +     return ret;
>> +}
>> +
>>  static int __init etm_perf_init(void)
>>  {
>>       etm_pmu.capabilities    = PERF_PMU_CAP_EXCLUSIVE;
>> @@ -59,6 +234,7 @@ static int __init etm_perf_init(void)
>>       etm_pmu.attr_groups     = etm_pmu_attr_groups;
>>       etm_pmu.task_ctx_nr     = perf_sw_context;
>>       etm_pmu.read            = etm_event_read;
>> +     etm_pmu.event_init      = etm_event_init;
>>
>>       return perf_pmu_register(&etm_pmu, CORESIGHT_ETM_PMU_NAME, -1);
>>  }
>
> One general comment -- it would be slightly easier at least for me if
> all the pmu related bits were in one patch.

Ah!  I went to great length to split them up to make the patches
smaller  - I will refactor...

Thanks for the review,
Mathieu

>
> Thanks,
> --
> Alex

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 00/20] Coresight integration with perf
  2015-09-18 16:26 [RFC PATCH 00/20] Coresight integration with perf Mathieu Poirier
                   ` (19 preceding siblings ...)
  2015-09-18 16:26 ` [RFC PATCH 20/20] coresight: updating documentation to reflect integration with perf Mathieu Poirier
@ 2015-09-30  8:52 ` Alexander Shishkin
  2015-10-01 22:07   ` Mathieu Poirier
  2015-09-30  9:01 ` Alexander Shishkin
  2015-09-30 10:18 ` Alexander Shishkin
  22 siblings, 1 reply; 48+ messages in thread
From: Alexander Shishkin @ 2015-09-30  8:52 UTC (permalink / raw)
  To: Mathieu Poirier, gregkh, a.p.zijlstra, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

Mathieu Poirier <mathieu.poirier@linaro.org> writes:

> 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 

I had a peek there -- didn't see an actual decoder for the ETM/PTM
binary stream or did I miss it somehow?

Thanks,
--
Alex

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 00/20] Coresight integration with perf
  2015-09-18 16:26 [RFC PATCH 00/20] Coresight integration with perf Mathieu Poirier
                   ` (20 preceding siblings ...)
  2015-09-30  8:52 ` [RFC PATCH 00/20] Coresight " Alexander Shishkin
@ 2015-09-30  9:01 ` Alexander Shishkin
  2015-10-01 22:12   ` Mathieu Poirier
  2015-09-30 10:18 ` Alexander Shishkin
  22 siblings, 1 reply; 48+ messages in thread
From: Alexander Shishkin @ 2015-09-30  9:01 UTC (permalink / raw)
  To: Mathieu Poirier, gregkh, a.p.zijlstra, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

Mathieu Poirier <mathieu.poirier@linaro.org> writes:

> 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.

Also this patchset doesn't seem to apply to tip/perf/core, v4.3-rc3,
v4.2. What is it based on? Do you have a git branch with these patches
as well?

Regards,
--
Alex

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 14/20] coresight: etm-perf: implementing 'event_init()' API
  2015-09-28 21:22     ` Mathieu Poirier
@ 2015-09-30  9:43       ` Alexander Shishkin
  2015-10-02 16:52         ` Mathieu Poirier
  0 siblings, 1 reply; 48+ messages in thread
From: Alexander Shishkin @ 2015-09-30  9:43 UTC (permalink / raw)
  To: Mathieu Poirier
  Cc: Greg KH, a.p.zijlstra, Arnaldo Carvalho de Melo, Ingo Molnar,
	Jon Corbet, Adrian Hunter, Chunyan Zhang, Mike Leach,
	Tor Jeremiassen, Al Grant, Paweł Moll, linux-arm-kernel,
	linux-doc, linux-kernel

Mathieu Poirier <mathieu.poirier@linaro.org> writes:

> On 22 September 2015 at 08:29, Alexander Shishkin
> <alexander.shishkin@linux.intel.com> wrote:
>> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>>
>>> +static void etm_event_destroy(struct perf_event *event)
>>> +{
>>> +     /* switching off the source will also tear down the path */
>>> +     etm_event_power_sources(event->cpu, false);
>>> +}
>>> +
>>> +static int etm_event_init(struct perf_event *event)
>>> +{
>>> +     int ret;
>>> +
>>> +     if (event->attr.type != etm_pmu.type)
>>> +             return -ENOENT;
>>> +
>>> +     if (event->cpu >= nr_cpu_ids)
>>> +             return -EINVAL;
>>> +
>>> +     /* only one session at a time */
>>> +     if (etm_event_source_enabled(event->cpu))
>>> +             return -EBUSY;
>>
>> Why is this the case? If you were to configure the event in pmu::add()
>> and deconfigure it in pmu::del(), like you already do with the buffer
>> part, you could handle as many sessions as you want.
>
> Apologies for the late reply, I was travelling.
>
> We certainly don't want to have more than once trace session going on
> at any given time, especially if the sessions have different
> configuration parameters.  Moreover doing the tracer configuration as
> part of pmu::add() is highly redundant.

But why?

The whole point of using perf for this is that it does all the tricky
context switching for us, all the cross-cpu calling to enable/disable
the events etc so that we can run multiple sessions in parallel without
having to worry (much) about scheduling. (Aside, of course, from other
useful things like sideband events, but that's another topic).

>> This can be done in pmu::add(), if you can call directly into
>> etm_configure_cpu() or etm_config_enable() so that there's no cross-cpu
>> calling in between.
>
> As per my comment above, reconfiguring the tracers every time it is
> about to run is redundant and extensive (etm_configure_cpu() isn't
> exactly short),  incurring a cost that is likely to be higher than
> calling get_online_cpus().

I was actually referring to synchronous smp_function_call*()s that
obviously won't work here. But the good news is that they are also
redundant.

But I don't see anything expensive in configuring etm and etb in
pmu::add(), as far as I can tell, it's just a bunch of register
writes. If you want to optimize those, you could compare the new context
against the previous one and only update registers that need to be
updated. The spinlock you also could get rid of, because there won't be
any local racing (again, afaict neither ETM nor ETB generate
interrupts).

That said, one expensive thing is reading out the ETB buffer on every
sched out, and that is the real problem, because it slows down the fast
path by a loop of arbitrary length reading out hw registers. Iirc, ETBs
could be up to 64K?

But a TMC-enabled coresight should do much better in this regard.

Thanks,
--
Alex

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 01/20] coresight: etm3x: splitting 'etm_enable_hw()' operations
  2015-09-18 16:26 ` [RFC PATCH 01/20] coresight: etm3x: splitting 'etm_enable_hw()' operations Mathieu Poirier
@ 2015-09-30  9:58   ` Alexander Shishkin
  2015-10-01 22:26     ` Mathieu Poirier
  0 siblings, 1 reply; 48+ messages in thread
From: Alexander Shishkin @ 2015-09-30  9:58 UTC (permalink / raw)
  To: Mathieu Poirier, gregkh, a.p.zijlstra, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

Mathieu Poirier <mathieu.poirier@linaro.org> writes:

> -static void etm_enable_hw(void *info)
> +static void etm_power_up_cpu(void *info)
>  {
> -	int i;
> -	u32 etmcr;
> -	struct etm_drvdata *drvdata = info;
> +	struct coresight_device *csdev = info;
> +	struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> +
> +	WARN_ON(drvdata->cpu != smp_processor_id());

Maybe WARN_ON_ONCE() is sufficient here (and other similar places).

> +static void etm_power_down_cpu(void *info)
> +{
> +	struct coresight_device *csdev = info;
> +	struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> +
> +	WARN_ON(drvdata->cpu != smp_processor_id());

Likewise.

> +/**
> + * etm_configure_cpu - configure ETM registers
> + * @csdev - the etm that needs to be configure.
> + *
> + * Applies a configuration set to the ETM registers _without_ enabling the
> + * tracer.  This function needs to be executed on the CPU who's tracer is
> + * being configured.
> + */
> +static void etm_configure_cpu(void *info)
> +{
> +	int i;
> +	u32 etmcr;
> +	struct coresight_device *csdev = info;
> +	struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> +
> +	WARN_ON(drvdata->cpu != smp_processor_id());

Likewise.

> +
> +	CS_UNLOCK(drvdata->base);
>  	etm_set_prog(drvdata);
>  
>  	etmcr = etm_readl(drvdata, ETMCR);
> -	etmcr &= (ETMCR_PWD_DWN | ETMCR_ETM_PRG);
>  	etmcr |= drvdata->port_size;
>  	etm_writel(drvdata, drvdata->ctrl | etmcr, ETMCR);
>  	etm_writel(drvdata, drvdata->trigger_event, ETMTRIGGER);

Most of these things can also be bypassed, as at least initially perf
events won't be using trigger/sequencer configurations, so we could
simply clear all these things out when a first perf event is created
(which would also disallow any sysfs poking around the etm/etb) and not
worry about them in the pmu callbacks.

Regards,
--
Alex

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 19/20] coresight: etm3x: implementing perf's user/kernel mode
  2015-09-18 16:26 ` [RFC PATCH 19/20] coresight: etm3x: implementing perf's user/kernel mode Mathieu Poirier
@ 2015-09-30 10:16   ` Alexander Shishkin
  2015-10-01 23:16     ` Mathieu Poirier
  0 siblings, 1 reply; 48+ messages in thread
From: Alexander Shishkin @ 2015-09-30 10:16 UTC (permalink / raw)
  To: Mathieu Poirier, gregkh, a.p.zijlstra, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

Mathieu Poirier <mathieu.poirier@linaro.org> writes:

> Configure tracers in accordance with the specification conveyed
> by the perf cmd line tool.  For example if only user space is
> requested, configure the address range comparator with the kerne's
> address range and set the 'exclude' bit, which will result in
> tracing everything except the kernel.
>
> Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
> ---
>  drivers/hwtracing/coresight/coresight-etm3x.c | 36 +++++++++++++++++++++++++++
>  1 file changed, 36 insertions(+)
>
> diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c
> index 077b49714259..2f818dbde099 100644
> --- a/drivers/hwtracing/coresight/coresight-etm3x.c
> +++ b/drivers/hwtracing/coresight/coresight-etm3x.c
> @@ -320,6 +320,41 @@ static int etm_parse_event_config(struct etm_drvdata *drvdata,
>  {
>  	u64 config = event->attr.config;
>  
> +	if (event->attr.exclude_kernel || event->attr.exclude_user) {
> +		u32 event_encoding;
> +		u32 flags = (1 << 0 | /* instruction execute*/
> +			     3 << 3 | /* ARM instruction */
> +			     0 << 5 | /* No data value comparison */
> +			     0 << 7 | /* No exact mach */
> +			     0 << 8 | /* Ignore context ID */
> +			     0 << 10); /* Security ignored */
> +
> +		/* Bit 0 is address range comparator 1 */
> +		drvdata->enable_ctrl1 = ETMTECR1_ADDR_COMP_1;
> +
> +		/* Bit 24 controls whether the address range should be
> +		 * included or excluded.
> +		 */
> +		if (event->attr.exclude_kernel)
> +			drvdata->enable_ctrl1 |= BIT(24);

Isn't there a privilege level based filtering (OS/USR) in ETM? Shouldn't
ETMACTRn[10:12] have a setting for that?

> +
> +		/* No need to worry about single address comparators */
> +		drvdata->enable_ctrl2 = 0x0;
> +
> +		drvdata->addr_val[0] = (u32) _stext;
> +		drvdata->addr_val[1] = (u32) _etext;

This doesn't cover kernel modules, afaict.

> +		drvdata->addr_acctype[0] = flags;
> +		drvdata->addr_acctype[1] = flags;
> +		drvdata->addr_type[0] = ETM_ADDR_TYPE_RANGE;
> +		drvdata->addr_type[1] = ETM_ADDR_TYPE_RANGE;
> +
> +		event_encoding = 0x00 << 14 | /* Boolean function select A */
> +				 0x01 << 4  | /* Addr range comparator 0-7 */
> +				 0x00 << 0;   /* Addr range comparator 1 */
> +
> +		drvdata->enable_event = event_encoding;
> +	}
> +
>  	/*
>  	 * At this time only cycle accurate and timestamp options are
>  	 * available.  As such clear everything else that may have been
> @@ -362,6 +397,7 @@ static void etm_configure_cpu(void *info)
>  	etm_writel(drvdata, drvdata->startstop_ctrl, ETMTSSCR);
>  	etm_writel(drvdata, drvdata->enable_event, ETMTEEVR);
>  	etm_writel(drvdata, drvdata->enable_ctrl1, ETMTECR1);
> +	etm_writel(drvdata, drvdata->enable_ctrl2, ETMTECR2);
>  	etm_writel(drvdata, drvdata->fifofull_level, ETMFFLR);
>  	for (i = 0; i < drvdata->nr_addr_cmp; i++) {
>  		etm_writel(drvdata, drvdata->addr_val[i], ETMACVRn(i));
> -- 
> 1.9.1

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 00/20] Coresight integration with perf
  2015-09-18 16:26 [RFC PATCH 00/20] Coresight integration with perf Mathieu Poirier
                   ` (21 preceding siblings ...)
  2015-09-30  9:01 ` Alexander Shishkin
@ 2015-09-30 10:18 ` Alexander Shishkin
  22 siblings, 0 replies; 48+ messages in thread
From: Alexander Shishkin @ 2015-09-30 10:18 UTC (permalink / raw)
  To: Mathieu Poirier, gregkh, a.p.zijlstra, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

Mathieu Poirier <mathieu.poirier@linaro.org> writes:

> 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.

Another general question: is there anything that prevents a sysfs user
from changing ETM/ETB configuration while it's used by a perf event? I
couldn't find any code in this patchset that would implement such
exclusivity.

Thanks,
--
Alex

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 03/20] coresight: etm3x: implementing 'cpu_id()' API
  2015-09-18 16:26 ` [RFC PATCH 03/20] coresight: etm3x: implementing 'cpu_id()' API Mathieu Poirier
@ 2015-09-30 11:16   ` Alexander Shishkin
  2015-10-01 22:43     ` Mathieu Poirier
  0 siblings, 1 reply; 48+ messages in thread
From: Alexander Shishkin @ 2015-09-30 11:16 UTC (permalink / raw)
  To: Mathieu Poirier, gregkh, a.p.zijlstra, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

Mathieu Poirier <mathieu.poirier@linaro.org> writes:

> 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);

Why do you need a spinlock here? Afaict, it never changes and if it
would, things would go really bad really fast.

Regards,
--
Alex

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 06/20] coresight: etm3x: unlocking tracer in default arch init
  2015-09-18 16:26 ` [RFC PATCH 06/20] coresight: etm3x: unlocking tracer in default arch init Mathieu Poirier
@ 2015-09-30 11:33   ` Alexander Shishkin
  2015-10-01 22:42     ` Mathieu Poirier
  0 siblings, 1 reply; 48+ messages in thread
From: Alexander Shishkin @ 2015-09-30 11:33 UTC (permalink / raw)
  To: Mathieu Poirier, gregkh, a.p.zijlstra, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

Mathieu Poirier <mathieu.poirier@linaro.org> writes:

> 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);

In case of co-processor register access, this will end up unlocking the
local ETM instead of the one on target cpu, by the looks of it. That's
why smp_function_call() was needed there. Or you might want a
etm_read_on_cpu() variant if it's really worth it.

> +	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

Regards,
--
Alex

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 15/20] coresight: etm-perf: implementing 'setup_aux()' API
  2015-09-18 16:26 ` [RFC PATCH 15/20] coresight: etm-perf: implementing 'setup_aux()' API Mathieu Poirier
@ 2015-09-30 11:50   ` Alexander Shishkin
  2015-10-01 22:49     ` Mathieu Poirier
  0 siblings, 1 reply; 48+ messages in thread
From: Alexander Shishkin @ 2015-09-30 11:50 UTC (permalink / raw)
  To: Mathieu Poirier, gregkh, a.p.zijlstra, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

Mathieu Poirier <mathieu.poirier@linaro.org> writes:

> +static void *etm_setup_aux(int cpu, void **pages,
> +			      int nr_pages, bool overwrite)
> +{
> +	struct coresight_device *csdev;
> +
> +	if (cpu == -1)
> +		cpu = smp_processor_id();
> +
> +	csdev = per_cpu(csdev_sink, cpu);
> +	if (!csdev)
> +		return NULL;
> +
> +	return sink_ops(csdev)->setup_aux(csdev, cpu, pages,
> +					  nr_pages, overwrite);

Is it guaranteed that this sink would always have .setup_aux()?

Regards,
--
Alex

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 18/20] coresight: etm3x: pushing down perf configuration to tracer
  2015-09-18 16:26 ` [RFC PATCH 18/20] coresight: etm3x: pushing down perf configuration to tracer Mathieu Poirier
@ 2015-09-30 12:45   ` Alexander Shishkin
  0 siblings, 0 replies; 48+ messages in thread
From: Alexander Shishkin @ 2015-09-30 12:45 UTC (permalink / raw)
  To: Mathieu Poirier, gregkh, a.p.zijlstra, acme, mingo, corbet
  Cc: adrian.hunter, zhang.chunyan, mike.leach, tor, al.grant,
	pawel.moll, linux-arm-kernel, linux-doc, linux-kernel

Mathieu Poirier <mathieu.poirier@linaro.org> writes:

> +#define ETM3X_SUPPORTED_OPTIONS (ETMCR_CYC_ACC | ETMCR_TIMESTAMP_EN)
> +
> +static int etm_parse_event_config(struct etm_drvdata *drvdata,
> +				  struct perf_event *event)
> +{
> +	u64 config = event->attr.config;
> +
> +	/*
> +	 * At this time only cycle accurate and timestamp options are
> +	 * available.  As such clear everything else that may have been
> +	 * configured and set the ETM control register based on what was
> +	 * requested.
> +	 */
> +	config &= ETM3X_SUPPORTED_OPTIONS;

You want to make sure no bits outside of this mask are set in config,
though, and return -EINVAL. Below you're even checking for it:

> +	if (etm_parse_event_config(drvdata, event))
> +		return -EINVAL;

Regards,
--
Alex

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 00/20] Coresight integration with perf
  2015-09-30  8:52 ` [RFC PATCH 00/20] Coresight " Alexander Shishkin
@ 2015-10-01 22:07   ` Mathieu Poirier
  2015-10-02  4:53     ` Alexander Shishkin
  0 siblings, 1 reply; 48+ messages in thread
From: Mathieu Poirier @ 2015-10-01 22:07 UTC (permalink / raw)
  To: Alexander Shishkin
  Cc: Greg KH, a.p.zijlstra, Arnaldo Carvalho de Melo, Ingo Molnar,
	Jon Corbet, Adrian Hunter, Chunyan Zhang, Mike Leach,
	Tor Jeremiassen, Al Grant, Paweł Moll, linux-arm-kernel,
	linux-doc, linux-kernel

On 30 September 2015 at 02:52, Alexander Shishkin
<alexander.shishkin@linux.intel.com> wrote:
> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>
>> 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
>
> I had a peek there -- didn't see an actual decoder for the ETM/PTM
> binary stream or did I miss it somehow?

A stream decoder is not included in this patch set but a couple of
people are currently working on it.

>
> Thanks,
> --
> Alex

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 00/20] Coresight integration with perf
  2015-09-30  9:01 ` Alexander Shishkin
@ 2015-10-01 22:12   ` Mathieu Poirier
  0 siblings, 0 replies; 48+ messages in thread
From: Mathieu Poirier @ 2015-10-01 22:12 UTC (permalink / raw)
  To: Alexander Shishkin
  Cc: Greg KH, a.p.zijlstra, Arnaldo Carvalho de Melo, Ingo Molnar,
	Jon Corbet, Adrian Hunter, Chunyan Zhang, Mike Leach,
	Tor Jeremiassen, Al Grant, Paweł Moll, linux-arm-kernel,
	linux-doc, linux-kernel

On 30 September 2015 at 03:01, Alexander Shishkin
<alexander.shishkin@linux.intel.com> wrote:
> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>
>> 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.
>
> Also this patchset doesn't seem to apply to tip/perf/core, v4.3-rc3,
> v4.2. What is it based on? Do you have a git branch with these patches
> as well?

The kernel space portion applied to v4.3-rc1.  I had to keep the user
space side on a private branch based on v4.2 since v4.3-rc1 didn't
have a few fix from Adrian.  V2 will be based on v4.3-rc4 and have all
the patches (user and kernel space) on the same tree.


>
> Regards,
> --
> Alex

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 01/20] coresight: etm3x: splitting 'etm_enable_hw()' operations
  2015-09-30  9:58   ` Alexander Shishkin
@ 2015-10-01 22:26     ` Mathieu Poirier
  2015-10-02  4:40       ` Alexander Shishkin
  0 siblings, 1 reply; 48+ messages in thread
From: Mathieu Poirier @ 2015-10-01 22:26 UTC (permalink / raw)
  To: Alexander Shishkin
  Cc: Greg KH, a.p.zijlstra, Arnaldo Carvalho de Melo, Ingo Molnar,
	Jon Corbet, Adrian Hunter, Chunyan Zhang, Mike Leach,
	Tor Jeremiassen, Al Grant, Paweł Moll, linux-arm-kernel,
	linux-doc, linux-kernel

On 30 September 2015 at 03:58, Alexander Shishkin
<alexander.shishkin@linux.intel.com> wrote:
> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>
>> -static void etm_enable_hw(void *info)
>> +static void etm_power_up_cpu(void *info)
>>  {
>> -     int i;
>> -     u32 etmcr;
>> -     struct etm_drvdata *drvdata = info;
>> +     struct coresight_device *csdev = info;
>> +     struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>> +
>> +     WARN_ON(drvdata->cpu != smp_processor_id());
>
> Maybe WARN_ON_ONCE() is sufficient here (and other similar places).

Yes, let's go with that.

>
>> +static void etm_power_down_cpu(void *info)
>> +{
>> +     struct coresight_device *csdev = info;
>> +     struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>> +
>> +     WARN_ON(drvdata->cpu != smp_processor_id());
>
> Likewise.
>
>> +/**
>> + * etm_configure_cpu - configure ETM registers
>> + * @csdev - the etm that needs to be configure.
>> + *
>> + * Applies a configuration set to the ETM registers _without_ enabling the
>> + * tracer.  This function needs to be executed on the CPU who's tracer is
>> + * being configured.
>> + */
>> +static void etm_configure_cpu(void *info)
>> +{
>> +     int i;
>> +     u32 etmcr;
>> +     struct coresight_device *csdev = info;
>> +     struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>> +
>> +     WARN_ON(drvdata->cpu != smp_processor_id());
>
> Likewise.
>
>> +
>> +     CS_UNLOCK(drvdata->base);
>>       etm_set_prog(drvdata);
>>
>>       etmcr = etm_readl(drvdata, ETMCR);
>> -     etmcr &= (ETMCR_PWD_DWN | ETMCR_ETM_PRG);
>>       etmcr |= drvdata->port_size;
>>       etm_writel(drvdata, drvdata->ctrl | etmcr, ETMCR);
>>       etm_writel(drvdata, drvdata->trigger_event, ETMTRIGGER);
>
> Most of these things can also be bypassed, as at least initially perf
> events won't be using trigger/sequencer configurations, so we could
> simply clear all these things out when a first perf event is created
> (which would also disallow any sysfs poking around the etm/etb) and not
> worry about them in the pmu callbacks.

I don't want to restrain configuration options to what is available
through Perf's cmd line.  The sysFS interface is there to complement
what is currently not available.  Poking around in the sysFS registers
is allowed for a long as a tracer hasn't been commissioned by Perf.  I
do agree though that a mechanism need to be set in place to prevent
changing configuration values once Perf has taken control of a tracer.


>
> Regards,
> --
> Alex

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 06/20] coresight: etm3x: unlocking tracer in default arch init
  2015-09-30 11:33   ` Alexander Shishkin
@ 2015-10-01 22:42     ` Mathieu Poirier
  2015-10-02  4:47       ` Alexander Shishkin
  0 siblings, 1 reply; 48+ messages in thread
From: Mathieu Poirier @ 2015-10-01 22:42 UTC (permalink / raw)
  To: Alexander Shishkin
  Cc: Greg KH, a.p.zijlstra, Arnaldo Carvalho de Melo, Ingo Molnar,
	Jon Corbet, Adrian Hunter, Chunyan Zhang, Mike Leach,
	Tor Jeremiassen, Al Grant, Paweł Moll, linux-arm-kernel,
	linux-doc, linux-kernel

On 30 September 2015 at 05:33, Alexander Shishkin
<alexander.shishkin@linux.intel.com> wrote:
> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>
>> 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);
>
> In case of co-processor register access, this will end up unlocking the
> local ETM instead of the one on target cpu, by the looks of it.

"etm_init_arch_data()" is also called from "smp_function_calls()" and
as such, will end up executing the correct CPU.

> That's
> why smp_function_call() was needed there. Or you might want a
> etm_read_on_cpu() variant if it's really worth it.
>
>> +     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
>
> Regards,
> --
> Alex

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 03/20] coresight: etm3x: implementing 'cpu_id()' API
  2015-09-30 11:16   ` Alexander Shishkin
@ 2015-10-01 22:43     ` Mathieu Poirier
  0 siblings, 0 replies; 48+ messages in thread
From: Mathieu Poirier @ 2015-10-01 22:43 UTC (permalink / raw)
  To: Alexander Shishkin
  Cc: Greg KH, a.p.zijlstra, Arnaldo Carvalho de Melo, Ingo Molnar,
	Jon Corbet, Adrian Hunter, Chunyan Zhang, Mike Leach,
	Tor Jeremiassen, Al Grant, Paweł Moll, linux-arm-kernel,
	linux-doc, linux-kernel

On 30 September 2015 at 05:16, Alexander Shishkin
<alexander.shishkin@linux.intel.com> wrote:
> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>
>> 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);
>
> Why do you need a spinlock here? Afaict, it never changes and if it
> would, things would go really bad really fast.

You are correct.

>
> Regards,
> --
> Alex

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 15/20] coresight: etm-perf: implementing 'setup_aux()' API
  2015-09-30 11:50   ` Alexander Shishkin
@ 2015-10-01 22:49     ` Mathieu Poirier
  2015-10-02  4:50       ` Alexander Shishkin
  0 siblings, 1 reply; 48+ messages in thread
From: Mathieu Poirier @ 2015-10-01 22:49 UTC (permalink / raw)
  To: Alexander Shishkin
  Cc: Greg KH, a.p.zijlstra, Arnaldo Carvalho de Melo, Ingo Molnar,
	Jon Corbet, Adrian Hunter, Chunyan Zhang, Mike Leach,
	Tor Jeremiassen, Al Grant, Paweł Moll, linux-arm-kernel,
	linux-doc, linux-kernel

On 30 September 2015 at 05:50, Alexander Shishkin
<alexander.shishkin@linux.intel.com> wrote:
> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>
>> +static void *etm_setup_aux(int cpu, void **pages,
>> +                           int nr_pages, bool overwrite)
>> +{
>> +     struct coresight_device *csdev;
>> +
>> +     if (cpu == -1)
>> +             cpu = smp_processor_id();
>> +
>> +     csdev = per_cpu(csdev_sink, cpu);
>> +     if (!csdev)
>> +             return NULL;
>> +
>> +     return sink_ops(csdev)->setup_aux(csdev, cpu, pages,
>> +                                       nr_pages, overwrite);
>
> Is it guaranteed that this sink would always have .setup_aux()?

A setup_aux() is vital to the design, both on Intel and ARM.  I really
don't see how one could go without it.  I can return NULL if it hasn't
been provided - that way the setup will fail without triggering a core
dump.

>
> Regards,
> --
> Alex

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 19/20] coresight: etm3x: implementing perf's user/kernel mode
  2015-09-30 10:16   ` Alexander Shishkin
@ 2015-10-01 23:16     ` Mathieu Poirier
  0 siblings, 0 replies; 48+ messages in thread
From: Mathieu Poirier @ 2015-10-01 23:16 UTC (permalink / raw)
  To: Alexander Shishkin
  Cc: Greg KH, a.p.zijlstra, Arnaldo Carvalho de Melo, Ingo Molnar,
	Jon Corbet, Adrian Hunter, Chunyan Zhang, Mike Leach,
	Tor Jeremiassen, Al Grant, Paweł Moll, linux-arm-kernel,
	linux-doc, linux-kernel

On 30 September 2015 at 04:16, Alexander Shishkin
<alexander.shishkin@linux.intel.com> wrote:
> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>
>> Configure tracers in accordance with the specification conveyed
>> by the perf cmd line tool.  For example if only user space is
>> requested, configure the address range comparator with the kerne's
>> address range and set the 'exclude' bit, which will result in
>> tracing everything except the kernel.
>>
>> Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
>> ---
>>  drivers/hwtracing/coresight/coresight-etm3x.c | 36 +++++++++++++++++++++++++++
>>  1 file changed, 36 insertions(+)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c
>> index 077b49714259..2f818dbde099 100644
>> --- a/drivers/hwtracing/coresight/coresight-etm3x.c
>> +++ b/drivers/hwtracing/coresight/coresight-etm3x.c
>> @@ -320,6 +320,41 @@ static int etm_parse_event_config(struct etm_drvdata *drvdata,
>>  {
>>       u64 config = event->attr.config;
>>
>> +     if (event->attr.exclude_kernel || event->attr.exclude_user) {
>> +             u32 event_encoding;
>> +             u32 flags = (1 << 0 | /* instruction execute*/
>> +                          3 << 3 | /* ARM instruction */
>> +                          0 << 5 | /* No data value comparison */
>> +                          0 << 7 | /* No exact mach */
>> +                          0 << 8 | /* Ignore context ID */
>> +                          0 << 10); /* Security ignored */
>> +
>> +             /* Bit 0 is address range comparator 1 */
>> +             drvdata->enable_ctrl1 = ETMTECR1_ADDR_COMP_1;
>> +
>> +             /* Bit 24 controls whether the address range should be
>> +              * included or excluded.
>> +              */
>> +             if (event->attr.exclude_kernel)
>> +                     drvdata->enable_ctrl1 |= BIT(24);
>
> Isn't there a privilege level based filtering (OS/USR) in ETM? Shouldn't
> ETMACTRn[10:12] have a setting for that?

Indeed - I'm working with people at ARM on a better solution.

>
>> +
>> +             /* No need to worry about single address comparators */
>> +             drvdata->enable_ctrl2 = 0x0;
>> +
>> +             drvdata->addr_val[0] = (u32) _stext;
>> +             drvdata->addr_val[1] = (u32) _etext;
>
> This doesn't cover kernel modules, afaict.
>
>> +             drvdata->addr_acctype[0] = flags;
>> +             drvdata->addr_acctype[1] = flags;
>> +             drvdata->addr_type[0] = ETM_ADDR_TYPE_RANGE;
>> +             drvdata->addr_type[1] = ETM_ADDR_TYPE_RANGE;
>> +
>> +             event_encoding = 0x00 << 14 | /* Boolean function select A */
>> +                              0x01 << 4  | /* Addr range comparator 0-7 */
>> +                              0x00 << 0;   /* Addr range comparator 1 */
>> +
>> +             drvdata->enable_event = event_encoding;
>> +     }
>> +
>>       /*
>>        * At this time only cycle accurate and timestamp options are
>>        * available.  As such clear everything else that may have been
>> @@ -362,6 +397,7 @@ static void etm_configure_cpu(void *info)
>>       etm_writel(drvdata, drvdata->startstop_ctrl, ETMTSSCR);
>>       etm_writel(drvdata, drvdata->enable_event, ETMTEEVR);
>>       etm_writel(drvdata, drvdata->enable_ctrl1, ETMTECR1);
>> +     etm_writel(drvdata, drvdata->enable_ctrl2, ETMTECR2);
>>       etm_writel(drvdata, drvdata->fifofull_level, ETMFFLR);
>>       for (i = 0; i < drvdata->nr_addr_cmp; i++) {
>>               etm_writel(drvdata, drvdata->addr_val[i], ETMACVRn(i));
>> --
>> 1.9.1

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 01/20] coresight: etm3x: splitting 'etm_enable_hw()' operations
  2015-10-01 22:26     ` Mathieu Poirier
@ 2015-10-02  4:40       ` Alexander Shishkin
  0 siblings, 0 replies; 48+ messages in thread
From: Alexander Shishkin @ 2015-10-02  4:40 UTC (permalink / raw)
  To: Mathieu Poirier
  Cc: Greg KH, a.p.zijlstra, Arnaldo Carvalho de Melo, Ingo Molnar,
	Jon Corbet, Adrian Hunter, Chunyan Zhang, Mike Leach,
	Tor Jeremiassen, Al Grant, Paweł Moll, linux-arm-kernel,
	linux-doc, linux-kernel

Mathieu Poirier <mathieu.poirier@linaro.org> writes:

> On 30 September 2015 at 03:58, Alexander Shishkin
> <alexander.shishkin@linux.intel.com> wrote:
>> Most of these things can also be bypassed, as at least initially perf
>> events won't be using trigger/sequencer configurations, so we could
>> simply clear all these things out when a first perf event is created
>> (which would also disallow any sysfs poking around the etm/etb) and not
>> worry about them in the pmu callbacks.
>
> I don't want to restrain configuration options to what is available
> through Perf's cmd line.  The sysFS interface is there to complement
> what is currently not available.

In practice this means that part of your trace configuration will be
global and part -- per event, which can indeed work if you only have one
event at a time, but again, makes using perf infrastructure redundant
for this driver. For multiple events this doesn't make much sense.

Regards,
--
Alex

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 06/20] coresight: etm3x: unlocking tracer in default arch init
  2015-10-01 22:42     ` Mathieu Poirier
@ 2015-10-02  4:47       ` Alexander Shishkin
  2015-10-02 17:17         ` Mathieu Poirier
  0 siblings, 1 reply; 48+ messages in thread
From: Alexander Shishkin @ 2015-10-02  4:47 UTC (permalink / raw)
  To: Mathieu Poirier
  Cc: Greg KH, a.p.zijlstra, Arnaldo Carvalho de Melo, Ingo Molnar,
	Jon Corbet, Adrian Hunter, Chunyan Zhang, Mike Leach,
	Tor Jeremiassen, Al Grant, Paweł Moll, linux-arm-kernel,
	linux-doc, linux-kernel

Mathieu Poirier <mathieu.poirier@linaro.org> writes:

> On 30 September 2015 at 05:33, Alexander Shishkin
> <alexander.shishkin@linux.intel.com> wrote:
>> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>>
>>> 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);
>>
>> In case of co-processor register access, this will end up unlocking the
>> local ETM instead of the one on target cpu, by the looks of it.
>
> "etm_init_arch_data()" is also called from "smp_function_calls()" and
> as such, will end up executing the correct CPU.

Yes, but it doesn't unlock the OSLAR register, which also needs to be
done on target cpu.

Regards,
--
Alex

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 15/20] coresight: etm-perf: implementing 'setup_aux()' API
  2015-10-01 22:49     ` Mathieu Poirier
@ 2015-10-02  4:50       ` Alexander Shishkin
  0 siblings, 0 replies; 48+ messages in thread
From: Alexander Shishkin @ 2015-10-02  4:50 UTC (permalink / raw)
  To: Mathieu Poirier
  Cc: Greg KH, a.p.zijlstra, Arnaldo Carvalho de Melo, Ingo Molnar,
	Jon Corbet, Adrian Hunter, Chunyan Zhang, Mike Leach,
	Tor Jeremiassen, Al Grant, Paweł Moll, linux-arm-kernel,
	linux-doc, linux-kernel

Mathieu Poirier <mathieu.poirier@linaro.org> writes:

> On 30 September 2015 at 05:50, Alexander Shishkin
> <alexander.shishkin@linux.intel.com> wrote:
>> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>>
>>> +static void *etm_setup_aux(int cpu, void **pages,
>>> +                           int nr_pages, bool overwrite)
>>> +{
>>> +     struct coresight_device *csdev;
>>> +
>>> +     if (cpu == -1)
>>> +             cpu = smp_processor_id();
>>> +
>>> +     csdev = per_cpu(csdev_sink, cpu);
>>> +     if (!csdev)
>>> +             return NULL;
>>> +
>>> +     return sink_ops(csdev)->setup_aux(csdev, cpu, pages,
>>> +                                       nr_pages, overwrite);
>>
>> Is it guaranteed that this sink would always have .setup_aux()?
>
> A setup_aux() is vital to the design, both on Intel and ARM.  I really
> don't see how one could go without it.  I can return NULL if it hasn't
> been provided - that way the setup will fail without triggering a core
> dump.

It wasn't clear to me that the sink that ends up in csdev_sink will
always be the one that does have .setup_aux(). And if it indeed doesn't,
it's better to refuse to setup a buffer than crash.

Regards,
--
Alex

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 00/20] Coresight integration with perf
  2015-10-01 22:07   ` Mathieu Poirier
@ 2015-10-02  4:53     ` Alexander Shishkin
  2015-10-02 15:27       ` Mathieu Poirier
  0 siblings, 1 reply; 48+ messages in thread
From: Alexander Shishkin @ 2015-10-02  4:53 UTC (permalink / raw)
  To: Mathieu Poirier
  Cc: Greg KH, a.p.zijlstra, Arnaldo Carvalho de Melo, Ingo Molnar,
	Jon Corbet, Adrian Hunter, Chunyan Zhang, Mike Leach,
	Tor Jeremiassen, Al Grant, Paweł Moll, linux-arm-kernel,
	linux-doc, linux-kernel

Mathieu Poirier <mathieu.poirier@linaro.org> writes:

> On 30 September 2015 at 02:52, Alexander Shishkin
> <alexander.shishkin@linux.intel.com> wrote:
>> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>>
>>> 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
>>
>> I had a peek there -- didn't see an actual decoder for the ETM/PTM
>> binary stream or did I miss it somehow?
>
> A stream decoder is not included in this patch set but a couple of
> people are currently working on it.

Ok, thanks. Can you provide instructions in the next version on how one
can use this code to get a trace and decode it?

Regards,
--
Alex

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 00/20] Coresight integration with perf
  2015-10-02  4:53     ` Alexander Shishkin
@ 2015-10-02 15:27       ` Mathieu Poirier
  0 siblings, 0 replies; 48+ messages in thread
From: Mathieu Poirier @ 2015-10-02 15:27 UTC (permalink / raw)
  To: Alexander Shishkin
  Cc: Greg KH, a.p.zijlstra, Arnaldo Carvalho de Melo, Ingo Molnar,
	Jon Corbet, Adrian Hunter, Chunyan Zhang, Mike Leach,
	Tor Jeremiassen, Al Grant, Paweł Moll, linux-arm-kernel,
	linux-doc, linux-kernel

On 1 October 2015 at 22:53, Alexander Shishkin
<alexander.shishkin@linux.intel.com> wrote:
> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>
>> On 30 September 2015 at 02:52, Alexander Shishkin
>> <alexander.shishkin@linux.intel.com> wrote:
>>> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>>>
>>>> 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
>>>
>>> I had a peek there -- didn't see an actual decoder for the ETM/PTM
>>> binary stream or did I miss it somehow?
>>
>> A stream decoder is not included in this patch set but a couple of
>> people are currently working on it.
>
> Ok, thanks. Can you provide instructions in the next version on how one
> can use this code to get a trace and decode it?

I'm afraid it won't be ready for the next version.  I will publish
instructions as soon as the code is mature enough.

>
> Regards,
> --
> Alex

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 14/20] coresight: etm-perf: implementing 'event_init()' API
  2015-09-30  9:43       ` Alexander Shishkin
@ 2015-10-02 16:52         ` Mathieu Poirier
  0 siblings, 0 replies; 48+ messages in thread
From: Mathieu Poirier @ 2015-10-02 16:52 UTC (permalink / raw)
  To: Alexander Shishkin
  Cc: Greg KH, a.p.zijlstra, Arnaldo Carvalho de Melo, Ingo Molnar,
	Jon Corbet, Adrian Hunter, Chunyan Zhang, Mike Leach,
	Tor Jeremiassen, Al Grant, Paweł Moll, linux-arm-kernel,
	linux-doc, linux-kernel

On 30 September 2015 at 03:43, Alexander Shishkin
<alexander.shishkin@linux.intel.com> wrote:
> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>
>> On 22 September 2015 at 08:29, Alexander Shishkin
>> <alexander.shishkin@linux.intel.com> wrote:
>>> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>>>
>>>> +static void etm_event_destroy(struct perf_event *event)
>>>> +{
>>>> +     /* switching off the source will also tear down the path */
>>>> +     etm_event_power_sources(event->cpu, false);
>>>> +}
>>>> +
>>>> +static int etm_event_init(struct perf_event *event)
>>>> +{
>>>> +     int ret;
>>>> +
>>>> +     if (event->attr.type != etm_pmu.type)
>>>> +             return -ENOENT;
>>>> +
>>>> +     if (event->cpu >= nr_cpu_ids)
>>>> +             return -EINVAL;
>>>> +
>>>> +     /* only one session at a time */
>>>> +     if (etm_event_source_enabled(event->cpu))
>>>> +             return -EBUSY;
>>>
>>> Why is this the case? If you were to configure the event in pmu::add()
>>> and deconfigure it in pmu::del(), like you already do with the buffer
>>> part, you could handle as many sessions as you want.
>>
>> Apologies for the late reply, I was travelling.
>>
>> We certainly don't want to have more than once trace session going on
>> at any given time, especially if the sessions have different
>> configuration parameters.  Moreover doing the tracer configuration as
>> part of pmu::add() is highly redundant.
>
> But why?
>
> The whole point of using perf for this is that it does all the tricky
> context switching for us, all the cross-cpu calling to enable/disable
> the events etc so that we can run multiple sessions in parallel without
> having to worry (much) about scheduling. (Aside, of course, from other
> useful things like sideband events, but that's another topic).

Sessions can run in parallel for as long as they don't use the same
CPUs.  There is no doubt as to the amount of benefit incurred by using
Perf but a tracer can't be commissioned by another session once it is
already part of one.

I'm suspecting we don't understand each other here... Maybe an IRC
chat is in order.

>
>>> This can be done in pmu::add(), if you can call directly into
>>> etm_configure_cpu() or etm_config_enable() so that there's no cross-cpu
>>> calling in between.
>>
>> As per my comment above, reconfiguring the tracers every time it is
>> about to run is redundant and extensive (etm_configure_cpu() isn't
>> exactly short),  incurring a cost that is likely to be higher than
>> calling get_online_cpus().
>
> I was actually referring to synchronous smp_function_call*()s that
> obviously won't work here. But the good news is that they are also
> redundant.
>
> But I don't see anything expensive in configuring etm and etb in
> pmu::add(), as far as I can tell, it's just a bunch of register
> writes.

Right, but why re-doing a configuration that doesn't change throughout
a trace session?  To me doing the configuration in pmu::add() is
simply redundant and not needed.

> If you want to optimize those, you could compare the new context
> against the previous one and only update registers that need to be
> updated. The spinlock you also could get rid of, because there won't be
> any local racing (again, afaict neither ETM nor ETB generate
> interrupts).
>
> That said, one expensive thing is reading out the ETB buffer on every
> sched out, and that is the real problem, because it slows down the fast
> path by a loop of arbitrary length reading out hw registers. Iirc, ETBs
> could be up to 64K

I agree completely.  This work is intended to set the way for TMCs and
other, faster, sinks.

>
> But a TMC-enabled coresight should do much better in this regard.
>
> Thanks,
> --
> Alex

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [RFC PATCH 06/20] coresight: etm3x: unlocking tracer in default arch init
  2015-10-02  4:47       ` Alexander Shishkin
@ 2015-10-02 17:17         ` Mathieu Poirier
  0 siblings, 0 replies; 48+ messages in thread
From: Mathieu Poirier @ 2015-10-02 17:17 UTC (permalink / raw)
  To: Alexander Shishkin
  Cc: Greg KH, a.p.zijlstra, Arnaldo Carvalho de Melo, Ingo Molnar,
	Jon Corbet, Adrian Hunter, Chunyan Zhang, Mike Leach,
	Tor Jeremiassen, Al Grant, Paweł Moll, linux-arm-kernel,
	linux-doc, linux-kernel

On 1 October 2015 at 22:47, Alexander Shishkin
<alexander.shishkin@linux.intel.com> wrote:
> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>
>> On 30 September 2015 at 05:33, Alexander Shishkin
>> <alexander.shishkin@linux.intel.com> wrote:
>>> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>>>
>>>> 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);
>>>
>>> In case of co-processor register access, this will end up unlocking the
>>> local ETM instead of the one on target cpu, by the looks of it.
>>
>> "etm_init_arch_data()" is also called from "smp_function_calls()" and
>> as such, will end up executing the correct CPU.
>
> Yes, but it doesn't unlock the OSLAR register, which also needs to be
> done on target cpu.

Function "etm_os_unlock()" deals with ETMOSLAR and "CS_UNLOCK()" with
ETMLAR.  Both are called from "etm_init_arch_data()", which runs on
the target CPU.  One thing that I will do here is move
"etm_os_unlock()" to the beginning of "etm_init_arch_data()".  Other
than that I may be missing your point.

>
> Regards,
> --
> Alex

^ permalink raw reply	[flat|nested] 48+ messages in thread

end of thread, other threads:[~2015-10-02 17:17 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-18 16:26 [RFC PATCH 00/20] Coresight integration with perf Mathieu Poirier
2015-09-18 16:26 ` [RFC PATCH 01/20] coresight: etm3x: splitting 'etm_enable_hw()' operations Mathieu Poirier
2015-09-30  9:58   ` Alexander Shishkin
2015-10-01 22:26     ` Mathieu Poirier
2015-10-02  4:40       ` Alexander Shishkin
2015-09-18 16:26 ` [RFC PATCH 02/20] coresight: etm3x: implementing 'is_enabled()' API Mathieu Poirier
2015-09-18 16:26 ` [RFC PATCH 03/20] coresight: etm3x: implementing 'cpu_id()' API Mathieu Poirier
2015-09-30 11:16   ` Alexander Shishkin
2015-10-01 22:43     ` Mathieu Poirier
2015-09-18 16:26 ` [RFC PATCH 04/20] coresight: etm3x: using chip logic to start/stop traces Mathieu Poirier
2015-09-18 16:26 ` [RFC PATCH 05/20] coresight: etm3x: adapting default tracer setting for perf Mathieu Poirier
2015-09-18 16:26 ` [RFC PATCH 06/20] coresight: etm3x: unlocking tracer in default arch init Mathieu Poirier
2015-09-30 11:33   ` Alexander Shishkin
2015-10-01 22:42     ` Mathieu Poirier
2015-10-02  4:47       ` Alexander Shishkin
2015-10-02 17:17         ` Mathieu Poirier
2015-09-18 16:26 ` [RFC PATCH 07/20] coresight: etb10: implementing the setup_aux() API Mathieu Poirier
2015-09-18 16:26 ` [RFC PATCH 08/20] coresight: etb10: implementing buffer set and unset APIs Mathieu Poirier
2015-09-18 16:26 ` [RFC PATCH 09/20] coresight: etb10: implementing buffer update API Mathieu Poirier
2015-09-18 16:26 ` [RFC PATCH 10/20] coresight: etb10: adding snapshot mode feature Mathieu Poirier
2015-09-18 16:26 ` [RFC PATCH 11/20] coresight: making coresight_build_paths() public Mathieu Poirier
2015-09-18 16:26 ` [RFC PATCH 12/20] coresight: keeping track of enabled sink buffers Mathieu Poirier
2015-09-18 16:26 ` [RFC PATCH 13/20] coresight: etm-perf: new PMU driver for ETM tracers Mathieu Poirier
2015-09-18 16:26 ` [RFC PATCH 14/20] coresight: etm-perf: implementing 'event_init()' API Mathieu Poirier
2015-09-22 14:29   ` Alexander Shishkin
2015-09-28 21:22     ` Mathieu Poirier
2015-09-30  9:43       ` Alexander Shishkin
2015-10-02 16:52         ` Mathieu Poirier
2015-09-18 16:26 ` [RFC PATCH 15/20] coresight: etm-perf: implementing 'setup_aux()' API Mathieu Poirier
2015-09-30 11:50   ` Alexander Shishkin
2015-10-01 22:49     ` Mathieu Poirier
2015-10-02  4:50       ` Alexander Shishkin
2015-09-18 16:26 ` [RFC PATCH 16/20] coresight: etm-perf: implementing trace related APIs Mathieu Poirier
2015-09-18 16:26 ` [RFC PATCH 17/20] coresight: etm-perf: adding symbolic link for CPUs Mathieu Poirier
2015-09-18 16:26 ` [RFC PATCH 18/20] coresight: etm3x: pushing down perf configuration to tracer Mathieu Poirier
2015-09-30 12:45   ` Alexander Shishkin
2015-09-18 16:26 ` [RFC PATCH 19/20] coresight: etm3x: implementing perf's user/kernel mode Mathieu Poirier
2015-09-30 10:16   ` Alexander Shishkin
2015-10-01 23:16     ` Mathieu Poirier
2015-09-18 16:26 ` [RFC PATCH 20/20] coresight: updating documentation to reflect integration with perf Mathieu Poirier
2015-09-19 10:09   ` Ingo Molnar
2015-09-30  8:52 ` [RFC PATCH 00/20] Coresight " Alexander Shishkin
2015-10-01 22:07   ` Mathieu Poirier
2015-10-02  4:53     ` Alexander Shishkin
2015-10-02 15:27       ` Mathieu Poirier
2015-09-30  9:01 ` Alexander Shishkin
2015-10-01 22:12   ` Mathieu Poirier
2015-09-30 10:18 ` Alexander Shishkin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).