Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3d6e8935 authored by Suzuki K Poulose's avatar Suzuki K Poulose Committed by Greg Kroah-Hartman
Browse files

coresight: perf: Remove set_buffer call back



In coresight perf mode, we need to prepare the sink before
starting a session, which is done via set_buffer call back.
We then proceed to enable the tracing. If we fail to start
the session successfully, we leave the sink configuration
unchanged.  In order to make the operation atomic and to
avoid yet another call back to clear the buffer, we get
rid of the "set_buffer" call back and pass the buffer details
via enable() call back to the sink.

Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: default avatarSuzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: default avatarMathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d25054ee
Loading
Loading
Loading
Loading
+25 −7
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@


#include "coresight-priv.h"
#include "coresight-etm-perf.h"

#define ETB_RAM_DEPTH_REG	0x004
#define ETB_STATUS_REG		0x00c
@@ -90,6 +91,9 @@ struct etb_drvdata {
	u32			trigger_cntr;
};

static int etb_set_buffer(struct coresight_device *csdev,
			  struct perf_output_handle *handle);

static unsigned int etb_get_buffer_depth(struct etb_drvdata *drvdata)
{
	u32 depth = 0;
@@ -131,12 +135,24 @@ static void etb_enable_hw(struct etb_drvdata *drvdata)
	CS_LOCK(drvdata->base);
}

static int etb_enable(struct coresight_device *csdev, u32 mode)
static int etb_enable(struct coresight_device *csdev, u32 mode, void *data)
{
	int ret = 0;
	u32 val;
	unsigned long flags;
	struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);

	/*
	 * We don't have an internal state to clean up if we fail to setup
	 * the perf buffer. So we can perform the step before we turn the
	 * ETB on and leave without cleaning up.
	 */
	if (mode == CS_MODE_PERF) {
		ret = etb_set_buffer(csdev, (struct perf_output_handle *)data);
		if (ret)
			goto out;
	}

	val = local_cmpxchg(&drvdata->mode,
			    CS_MODE_DISABLED, mode);
	/*
@@ -160,8 +176,9 @@ static int etb_enable(struct coresight_device *csdev, u32 mode)
	spin_unlock_irqrestore(&drvdata->spinlock, flags);

out:
	if (!ret)
		dev_dbg(drvdata->dev, "ETB enabled\n");
	return 0;
	return ret;
}

static void etb_disable_hw(struct etb_drvdata *drvdata)
@@ -298,12 +315,14 @@ static void etb_free_buffer(void *config)
}

static int etb_set_buffer(struct coresight_device *csdev,
			  struct perf_output_handle *handle,
			  void *sink_config)
			  struct perf_output_handle *handle)
{
	int ret = 0;
	unsigned long head;
	struct cs_buffers *buf = sink_config;
	struct cs_buffers *buf = etm_perf_sink_config(handle);

	if (!buf)
		return -EINVAL;

	/* wrap head around to the amount of space we have */
	head = handle->head & ((buf->nr_pages << PAGE_SHIFT) - 1);
@@ -457,7 +476,6 @@ static const struct coresight_ops_sink etb_sink_ops = {
	.disable	= etb_disable,
	.alloc_buffer	= etb_alloc_buffer,
	.free_buffer	= etb_free_buffer,
	.set_buffer	= etb_set_buffer,
	.update_buffer	= etb_update_buffer,
};

+2 −7
Original line number Diff line number Diff line
@@ -286,16 +286,11 @@ static void etm_event_start(struct perf_event *event, int flags)
	path = etm_event_cpu_path(event_data, cpu);
	/* We need a sink, no need to continue without one */
	sink = coresight_get_sink(path);
	if (WARN_ON_ONCE(!sink || !sink_ops(sink)->set_buffer))
		goto fail_end_stop;

	/* Configure the sink */
	if (sink_ops(sink)->set_buffer(sink, handle,
				       event_data->snk_config))
	if (WARN_ON_ONCE(!sink))
		goto fail_end_stop;

	/* Nothing will happen without a path */
	if (coresight_enable_path(path, CS_MODE_PERF))
	if (coresight_enable_path(path, CS_MODE_PERF, handle))
		goto fail_end_stop;

	/* Tell the perf core the event is alive */
+1 −1
Original line number Diff line number Diff line
@@ -137,7 +137,7 @@ static inline void coresight_write_reg_pair(void __iomem *addr, u64 val,
}

void coresight_disable_path(struct list_head *path);
int coresight_enable_path(struct list_head *path, u32 mode);
int coresight_enable_path(struct list_head *path, u32 mode, void *sink_data);
struct coresight_device *coresight_get_sink(struct list_head *path);
struct coresight_device *coresight_get_enabled_sink(bool reset);
struct list_head *coresight_build_path(struct coresight_device *csdev,
+19 −9
Original line number Diff line number Diff line
@@ -10,6 +10,10 @@
#include <linux/slab.h>
#include "coresight-priv.h"
#include "coresight-tmc.h"
#include "coresight-etm-perf.h"

static int tmc_set_etf_buffer(struct coresight_device *csdev,
			      struct perf_output_handle *handle);

static void tmc_etb_enable_hw(struct tmc_drvdata *drvdata)
{
@@ -182,11 +186,12 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
	return ret;
}

static int tmc_enable_etf_sink_perf(struct coresight_device *csdev)
static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data)
{
	int ret = 0;
	unsigned long flags;
	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
	struct perf_output_handle *handle = data;

	spin_lock_irqsave(&drvdata->spinlock, flags);
	if (drvdata->reading) {
@@ -204,15 +209,19 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev)
		goto out;
	}

	ret = tmc_set_etf_buffer(csdev, handle);
	if (!ret) {
		drvdata->mode = CS_MODE_PERF;
		tmc_etb_enable_hw(drvdata);
	}
out:
	spin_unlock_irqrestore(&drvdata->spinlock, flags);

	return ret;
}

static int tmc_enable_etf_sink(struct coresight_device *csdev, u32 mode)
static int tmc_enable_etf_sink(struct coresight_device *csdev,
			       u32 mode, void *data)
{
	int ret;
	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
@@ -222,7 +231,7 @@ static int tmc_enable_etf_sink(struct coresight_device *csdev, u32 mode)
		ret = tmc_enable_etf_sink_sysfs(csdev);
		break;
	case CS_MODE_PERF:
		ret = tmc_enable_etf_sink_perf(csdev);
		ret = tmc_enable_etf_sink_perf(csdev, data);
		break;
	/* We shouldn't be here */
	default:
@@ -328,12 +337,14 @@ static void tmc_free_etf_buffer(void *config)
}

static int tmc_set_etf_buffer(struct coresight_device *csdev,
			      struct perf_output_handle *handle,
			      void *sink_config)
			      struct perf_output_handle *handle)
{
	int ret = 0;
	unsigned long head;
	struct cs_buffers *buf = sink_config;
	struct cs_buffers *buf = etm_perf_sink_config(handle);

	if (!buf)
		return -EINVAL;

	/* wrap head around to the amount of space we have */
	head = handle->head & ((buf->nr_pages << PAGE_SHIFT) - 1);
@@ -472,7 +483,6 @@ static const struct coresight_ops_sink tmc_etf_sink_ops = {
	.disable	= tmc_disable_etf_sink,
	.alloc_buffer	= tmc_alloc_etf_buffer,
	.free_buffer	= tmc_free_etf_buffer,
	.set_buffer	= tmc_set_etf_buffer,
	.update_buffer	= tmc_update_etf_buffer,
};

+4 −3
Original line number Diff line number Diff line
@@ -1103,19 +1103,20 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
	return ret;
}

static int tmc_enable_etr_sink_perf(struct coresight_device *csdev)
static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
{
	/* We don't support perf mode yet ! */
	return -EINVAL;
}

static int tmc_enable_etr_sink(struct coresight_device *csdev, u32 mode)
static int tmc_enable_etr_sink(struct coresight_device *csdev,
			       u32 mode, void *data)
{
	switch (mode) {
	case CS_MODE_SYSFS:
		return tmc_enable_etr_sink_sysfs(csdev);
	case CS_MODE_PERF:
		return tmc_enable_etr_sink_perf(csdev);
		return tmc_enable_etr_sink_perf(csdev, data);
	}

	/* We shouldn't be here */
Loading