Message ID | 20230404155121.1824126-12-james.clark@arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | coresight: Fix CTI module refcount leak by making it a helper device | expand |
On Tue, 4 Apr 2023 at 16:52, James Clark <james.clark@arm.com> wrote: > > When CATU is moved to the generic enable/disable path system in the > next commit, it will need to call into ETR and get it to pre-allocate > its buffer so add a function for it. > > No functional changes > > Signed-off-by: James Clark <james.clark@arm.com> > --- > .../hwtracing/coresight/coresight-tmc-etr.c | 50 ++++++++++++++++--- > drivers/hwtracing/coresight/coresight-tmc.h | 2 + > 2 files changed, 45 insertions(+), 7 deletions(-) > > diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c > index 689ba6abc70b..00a0c2aa8481 100644 > --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c > +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c > @@ -1169,7 +1169,7 @@ void tmc_etr_disable_hw(struct tmc_drvdata *drvdata) > drvdata->etr_buf = NULL; > } > > -static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) > +static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev) > { > int ret = 0; > unsigned long flags; > @@ -1192,7 +1192,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) > /* Allocate memory with the locks released */ > free_buf = new_buf = tmc_etr_setup_sysfs_buf(drvdata); > if (IS_ERR(new_buf)) > - return PTR_ERR(new_buf); > + return new_buf; > > /* Let's try again */ > spin_lock_irqsave(&drvdata->spinlock, flags); > @@ -1223,17 +1223,33 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) > drvdata->sysfs_buf = new_buf; > } > > - ret = tmc_etr_enable_hw(drvdata, drvdata->sysfs_buf); > - if (!ret) { > - drvdata->mode = CS_MODE_SYSFS; > - atomic_inc(&csdev->refcnt); > - } > out: > spin_unlock_irqrestore(&drvdata->spinlock, flags); > > /* Free memory outside the spinlock if need be */ > if (free_buf) > tmc_etr_free_sysfs_buf(free_buf); > + return ret ? ERR_PTR(ret) : drvdata->sysfs_buf; > +} > + > +static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) > +{ > + int ret; > + unsigned long flags; > + struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); > + struct etr_buf *sysfs_buf = tmc_etr_get_sysfs_buffer(csdev); > + > + if (IS_ERR(sysfs_buf)) > + return PTR_ERR(sysfs_buf); > + > + spin_lock_irqsave(&drvdata->spinlock, flags); > + ret = tmc_etr_enable_hw(drvdata, sysfs_buf); > + if (!ret) { > + drvdata->mode = CS_MODE_SYSFS; > + atomic_inc(&csdev->refcnt); > + } > + > + spin_unlock_irqrestore(&drvdata->spinlock, flags); > > if (!ret) > dev_dbg(&csdev->dev, "TMC-ETR enabled\n"); > @@ -1241,6 +1257,26 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) > return ret; > } > > +struct etr_buf *tmc_etr_get_buffer(struct coresight_device *csdev, > + enum cs_mode mode, void *data) > +{ > + struct perf_output_handle *handle = data; > + struct etr_perf_buffer *etr_perf; > + > + switch (mode) { > + case CS_MODE_SYSFS: > + return tmc_etr_get_sysfs_buffer(csdev); > + case CS_MODE_PERF: > + etr_perf = etm_perf_sink_config(handle); > + if (WARN_ON(!etr_perf || !etr_perf->etr_buf)) > + return ERR_PTR(-EINVAL); > + return etr_perf->etr_buf; > + default: > + return ERR_PTR(-EINVAL); > + } > +} > +EXPORT_SYMBOL_GPL(tmc_etr_get_buffer); > + > /* > * alloc_etr_buf: Allocate ETR buffer for use by perf. > * The size of the hardware buffer is dependent on the size configured > diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h > index 01c0382a29c0..b97da39652d2 100644 > --- a/drivers/hwtracing/coresight/coresight-tmc.h > +++ b/drivers/hwtracing/coresight/coresight-tmc.h > @@ -332,5 +332,7 @@ struct coresight_device *tmc_etr_get_catu_device(struct tmc_drvdata *drvdata); > > void tmc_etr_set_catu_ops(const struct etr_buf_operations *catu); > void tmc_etr_remove_catu_ops(void); > +struct etr_buf *tmc_etr_get_buffer(struct coresight_device *csdev, > + enum cs_mode mode, void *data); > > #endif > -- > 2.34.1 > Reviewed-by: Mike Leach <mike.leach@linaro.org>
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index 689ba6abc70b..00a0c2aa8481 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -1169,7 +1169,7 @@ void tmc_etr_disable_hw(struct tmc_drvdata *drvdata) drvdata->etr_buf = NULL; } -static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) +static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev) { int ret = 0; unsigned long flags; @@ -1192,7 +1192,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) /* Allocate memory with the locks released */ free_buf = new_buf = tmc_etr_setup_sysfs_buf(drvdata); if (IS_ERR(new_buf)) - return PTR_ERR(new_buf); + return new_buf; /* Let's try again */ spin_lock_irqsave(&drvdata->spinlock, flags); @@ -1223,17 +1223,33 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) drvdata->sysfs_buf = new_buf; } - ret = tmc_etr_enable_hw(drvdata, drvdata->sysfs_buf); - if (!ret) { - drvdata->mode = CS_MODE_SYSFS; - atomic_inc(&csdev->refcnt); - } out: spin_unlock_irqrestore(&drvdata->spinlock, flags); /* Free memory outside the spinlock if need be */ if (free_buf) tmc_etr_free_sysfs_buf(free_buf); + return ret ? ERR_PTR(ret) : drvdata->sysfs_buf; +} + +static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) +{ + int ret; + unsigned long flags; + struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + struct etr_buf *sysfs_buf = tmc_etr_get_sysfs_buffer(csdev); + + if (IS_ERR(sysfs_buf)) + return PTR_ERR(sysfs_buf); + + spin_lock_irqsave(&drvdata->spinlock, flags); + ret = tmc_etr_enable_hw(drvdata, sysfs_buf); + if (!ret) { + drvdata->mode = CS_MODE_SYSFS; + atomic_inc(&csdev->refcnt); + } + + spin_unlock_irqrestore(&drvdata->spinlock, flags); if (!ret) dev_dbg(&csdev->dev, "TMC-ETR enabled\n"); @@ -1241,6 +1257,26 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) return ret; } +struct etr_buf *tmc_etr_get_buffer(struct coresight_device *csdev, + enum cs_mode mode, void *data) +{ + struct perf_output_handle *handle = data; + struct etr_perf_buffer *etr_perf; + + switch (mode) { + case CS_MODE_SYSFS: + return tmc_etr_get_sysfs_buffer(csdev); + case CS_MODE_PERF: + etr_perf = etm_perf_sink_config(handle); + if (WARN_ON(!etr_perf || !etr_perf->etr_buf)) + return ERR_PTR(-EINVAL); + return etr_perf->etr_buf; + default: + return ERR_PTR(-EINVAL); + } +} +EXPORT_SYMBOL_GPL(tmc_etr_get_buffer); + /* * alloc_etr_buf: Allocate ETR buffer for use by perf. * The size of the hardware buffer is dependent on the size configured diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index 01c0382a29c0..b97da39652d2 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -332,5 +332,7 @@ struct coresight_device *tmc_etr_get_catu_device(struct tmc_drvdata *drvdata); void tmc_etr_set_catu_ops(const struct etr_buf_operations *catu); void tmc_etr_remove_catu_ops(void); +struct etr_buf *tmc_etr_get_buffer(struct coresight_device *csdev, + enum cs_mode mode, void *data); #endif
When CATU is moved to the generic enable/disable path system in the next commit, it will need to call into ETR and get it to pre-allocate its buffer so add a function for it. No functional changes Signed-off-by: James Clark <james.clark@arm.com> --- .../hwtracing/coresight/coresight-tmc-etr.c | 50 ++++++++++++++++--- drivers/hwtracing/coresight/coresight-tmc.h | 2 + 2 files changed, 45 insertions(+), 7 deletions(-)