aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathieu Poirier <mathieu.poirier@linaro.org>2019-04-18 13:57:42 -0600
committerMathieu Poirier <mathieu.poirier@linaro.org>2019-05-03 09:35:28 -0600
commit4de1e6dee83da8fe67e6b7fa5cfcf1d77f8e7349 (patch)
treeaeb12557c9bd6017bcb5711ef980e18e8b20e03d
parent78e6427b4e7b017951785982f7f97cf64e2d624b (diff)
downloadcoresight-4de1e6dee83da8fe67e6b7fa5cfcf1d77f8e7349.tar.gz
coresight: Fix buffer size in snapshot mode
In snapshot mode the buffer used by the sink devices need to be equal to the ring buffer size in order for the user space mechanic to work properly. Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
-rw-r--r--drivers/hwtracing/coresight/coresight-etb10.c23
-rw-r--r--drivers/hwtracing/coresight/coresight-tmc-etf.c20
-rw-r--r--drivers/hwtracing/coresight/coresight-tmc-etr.c8
3 files changed, 49 insertions, 2 deletions
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index 4ee4c80a4354..0764647b92bc 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -374,7 +374,30 @@ static void *etb_alloc_buffer(struct coresight_device *csdev,
int nr_pages, bool overwrite)
{
int node, cpu = event->cpu;
+ u32 capacity;
struct cs_buffers *buf;
+ struct etb_drvdata *drvdata;
+
+ /*
+ * In snapsot mode the size of the perf ring buffer needs to be equal
+ * to the size of the device's internal memory if we want to reuse the
+ * generic AUX buffer management mechanic.
+ *
+ * For example (assuming 4096 byte page size):
+ *
+ * # cat /sys/bus/coresight/devices/20010000.etb/mgmt/rdp
+ * 0x2000
+ * # perf record -e cs_etm/@20010000.etf/ -S -m,8 --per-thread $APP
+ *
+ */
+ drvdata = dev_get_drvdata(csdev->dev.parent);
+ capacity = drvdata->buffer_depth * ETB_FRAME_SIZE_WORDS;
+
+ if (overwrite &&
+ ((nr_pages << PAGE_SHIFT) != capacity)) {
+ dev_err(&csdev->dev, "Ring buffer not equal to device buffer");
+ return NULL;
+ }
if (cpu == -1)
cpu = smp_processor_id();
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
index 2527b5d3b65e..7694833b13cb 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
@@ -380,6 +380,26 @@ static void *tmc_alloc_etf_buffer(struct coresight_device *csdev,
{
int node, cpu = event->cpu;
struct cs_buffers *buf;
+ struct tmc_drvdata *drvdata;
+
+ /*
+ * In snapsot mode the size of the perf ring buffer needs to be equal
+ * to the size of the device's internal memory if we want to reuse the
+ * generic AUX buffer management mechanic.
+ *
+ * For example (assuming 4096 byte page size):
+ *
+ * # cat /sys/bus/coresight/devices/20010000.etf/buffer_size
+ * 0x10000
+ * # perf record -e cs_etm/@20010000.etf/ -S -m,16 --per-thread $APP
+ *
+ */
+ drvdata = dev_get_drvdata(csdev->dev.parent);
+ if (overwrite &&
+ ((nr_pages << PAGE_SHIFT) != drvdata->size)) {
+ dev_err(&csdev->dev, "Ring buffer not equal to device buffer");
+ return NULL;
+ }
if (cpu == -1)
cpu = smp_processor_id();
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index df6e4b0b84e9..b9881d6d41ba 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -1188,9 +1188,13 @@ alloc_etr_buf(struct tmc_drvdata *drvdata, struct perf_event *event,
/*
* Try to match the perf ring buffer size if it is larger
- * than the size requested via sysfs.
+ * than the size requested via sysfs. In snapsot mode the size
+ * of the perf ring buffer needs to be equal to the allocated
+ * size if we want to reuse the generic AUX buffer management
+ * mechanic.
*/
- if ((nr_pages << PAGE_SHIFT) > drvdata->size) {
+ if (snapshot ||
+ (nr_pages << PAGE_SHIFT) > drvdata->size) {
etr_buf = tmc_alloc_etr_buf(drvdata, (nr_pages << PAGE_SHIFT),
0, node, NULL);
if (!IS_ERR(etr_buf))