| From 2088b4f0d8bb38e4b3f7f7f02e7f892df88cdd8f Mon Sep 17 00:00:00 2001 |
| From: Yabin Cui <yabinc@google.com> |
| Date: Thu, 29 Aug 2019 14:28:39 -0600 |
| Subject: [PATCH] coresight: tmc-etr: Fix perf_data check |
| |
| commit bbedcb91cc3bf252e6031e199ab3d1f07107f7c5 upstream. |
| |
| When tracing etm data of multiple threads on multiple cpus through |
| perf interface, each cpu has a unique etr_perf_buffer while sharing |
| the same etr device. There is no guarantee that the last cpu starts |
| etm tracing also stops last. This makes perf_data check fail. |
| |
| Fix it by checking etr_buf instead of etr_perf_buffer. |
| Also move the code setting and clearing perf_buf to more suitable |
| places. |
| |
| Fixes: 3147da92a8a8 ("coresight: tmc-etr: Allocate and free ETR memory buffers for CPU-wide scenarios") |
| Signed-off-by: Yabin Cui <yabinc@google.com> |
| Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org> |
| Link: https://lore.kernel.org/r/20190829202842.580-15-mathieu.poirier@linaro.org |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c |
| index 9f293b9dce8c..614c749ab511 100644 |
| --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c |
| +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c |
| @@ -1476,7 +1476,7 @@ tmc_update_etr_buffer(struct coresight_device *csdev, |
| goto out; |
| } |
| |
| - if (WARN_ON(drvdata->perf_data != etr_perf)) { |
| + if (WARN_ON(drvdata->perf_buf != etr_buf)) { |
| lost = true; |
| spin_unlock_irqrestore(&drvdata->spinlock, flags); |
| goto out; |
| @@ -1488,8 +1488,6 @@ tmc_update_etr_buffer(struct coresight_device *csdev, |
| tmc_sync_etr_buf(drvdata); |
| |
| CS_LOCK(drvdata->base); |
| - /* Reset perf specific data */ |
| - drvdata->perf_data = NULL; |
| spin_unlock_irqrestore(&drvdata->spinlock, flags); |
| |
| size = etr_buf->len; |
| @@ -1543,7 +1541,6 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data) |
| } |
| |
| etr_perf->head = PERF_IDX2OFF(handle->head, etr_perf); |
| - drvdata->perf_data = etr_perf; |
| |
| /* |
| * No HW configuration is needed if the sink is already in |
| @@ -1559,6 +1556,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data) |
| /* Associate with monitored process. */ |
| drvdata->pid = pid; |
| drvdata->mode = CS_MODE_PERF; |
| + drvdata->perf_buf = etr_perf->etr_buf; |
| atomic_inc(csdev->refcnt); |
| } |
| |
| @@ -1604,6 +1602,8 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev) |
| /* Dissociate from monitored process. */ |
| drvdata->pid = -1; |
| drvdata->mode = CS_MODE_DISABLED; |
| + /* Reset perf specific data */ |
| + drvdata->perf_buf = NULL; |
| |
| spin_unlock_irqrestore(&drvdata->spinlock, flags); |
| |
| diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h |
| index 503f1b3a3741..97b3415847e2 100644 |
| --- a/drivers/hwtracing/coresight/coresight-tmc.h |
| +++ b/drivers/hwtracing/coresight/coresight-tmc.h |
| @@ -179,8 +179,8 @@ struct etr_buf { |
| * device configuration register (DEVID) |
| * @idr: Holds etr_bufs allocated for this ETR. |
| * @idr_mutex: Access serialisation for idr. |
| - * @perf_data: PERF buffer for ETR. |
| - * @sysfs_data: SYSFS buffer for ETR. |
| + * @sysfs_buf: SYSFS buffer for ETR. |
| + * @perf_buf: PERF buffer for ETR. |
| */ |
| struct tmc_drvdata { |
| void __iomem *base; |
| @@ -204,7 +204,7 @@ struct tmc_drvdata { |
| struct idr idr; |
| struct mutex idr_mutex; |
| struct etr_buf *sysfs_buf; |
| - void *perf_data; |
| + struct etr_buf *perf_buf; |
| }; |
| |
| struct etr_buf_operations { |
| -- |
| 2.27.0 |
| |