Message ID | 20241216115006.415861-9-yeoreum.yun@arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | coresight: change some driver' spinlock type to raw_spinlock_t | expand |
On Mon, 16 Dec 2024 at 11:50, Yeoreum Yun <yeoreum.yun@arm.com> wrote: > > In coresight-tmc drivers, tmc_drvdata->spinlock can be held > during __schedule() by perf_event_task_sched_out()/in(). > > Since tmc_drvdata->spinlock type is spinlock_t and > perf_event_task_sched_out()/in() is called after acquiring rq_lock, > which is raw_spinlock_t (an unsleepable lock), > this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable. > > To address this, change type tmc_drvdata->spinlock in coresight-tmc drivers, > which can be called by perf_event_task_sched_out()/in(), > from spinlock_t to raw_spinlock_t. > > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com> > --- > .../hwtracing/coresight/coresight-tmc-core.c | 6 +-- > .../hwtracing/coresight/coresight-tmc-etf.c | 48 +++++++++---------- > .../hwtracing/coresight/coresight-tmc-etr.c | 40 ++++++++-------- > drivers/hwtracing/coresight/coresight-tmc.h | 2 +- > 4 files changed, 48 insertions(+), 48 deletions(-) > > diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c > index e9876252a789..4e9925300931 100644 > --- a/drivers/hwtracing/coresight/coresight-tmc-core.c > +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c > @@ -492,7 +492,7 @@ static int __tmc_probe(struct device *dev, struct resource *res) > drvdata->base = base; > desc.access = CSDEV_ACCESS_IOMEM(base); > > - spin_lock_init(&drvdata->spinlock); > + raw_spin_lock_init(&drvdata->spinlock); > > devid = readl_relaxed(drvdata->base + CORESIGHT_DEVID); > drvdata->config_type = BMVAL(devid, 6, 7); > @@ -596,7 +596,7 @@ static void tmc_shutdown(struct amba_device *adev) > unsigned long flags; > struct tmc_drvdata *drvdata = amba_get_drvdata(adev); > > - spin_lock_irqsave(&drvdata->spinlock, flags); > + raw_spin_lock_irqsave(&drvdata->spinlock, flags); > > if (coresight_get_mode(drvdata->csdev) == CS_MODE_DISABLED) > goto out; > @@ -610,7 +610,7 @@ static void tmc_shutdown(struct amba_device *adev) > * the system is going down after this. > */ > out: > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > } > > static void __tmc_remove(struct device *dev) > diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c > index d4f641cd9de6..fca8e9ffb3cf 100644 > --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c > +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c > @@ -182,9 +182,9 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev) > * If we don't have a buffer release the lock and allocate memory. > * Otherwise keep the lock and move along. > */ > - spin_lock_irqsave(&drvdata->spinlock, flags); > + raw_spin_lock_irqsave(&drvdata->spinlock, flags); > if (!drvdata->buf) { > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > > /* Allocating the memory here while outside of the spinlock */ > buf = kzalloc(drvdata->size, GFP_KERNEL); > @@ -192,7 +192,7 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev) > return -ENOMEM; > > /* Let's try again */ > - spin_lock_irqsave(&drvdata->spinlock, flags); > + raw_spin_lock_irqsave(&drvdata->spinlock, flags); > } > > if (drvdata->reading) { > @@ -235,7 +235,7 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev) > used = false; > } > out: > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > > /* Free memory outside the spinlock if need be */ > if (!used) > @@ -253,7 +253,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data) > struct perf_output_handle *handle = data; > struct cs_buffers *buf = etm_perf_sink_config(handle); > > - spin_lock_irqsave(&drvdata->spinlock, flags); > + raw_spin_lock_irqsave(&drvdata->spinlock, flags); > do { > ret = -EINVAL; > if (drvdata->reading) > @@ -296,7 +296,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data) > csdev->refcnt++; > } > } while (0); > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > > return ret; > } > @@ -331,16 +331,16 @@ static int tmc_disable_etf_sink(struct coresight_device *csdev) > unsigned long flags; > struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); > > - spin_lock_irqsave(&drvdata->spinlock, flags); > + raw_spin_lock_irqsave(&drvdata->spinlock, flags); > > if (drvdata->reading) { > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > return -EBUSY; > } > > csdev->refcnt--; > if (csdev->refcnt) { > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > return -EBUSY; > } > > @@ -351,7 +351,7 @@ static int tmc_disable_etf_sink(struct coresight_device *csdev) > drvdata->pid = -1; > coresight_set_mode(csdev, CS_MODE_DISABLED); > > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > > dev_dbg(&csdev->dev, "TMC-ETB/ETF disabled\n"); > return 0; > @@ -366,9 +366,9 @@ static int tmc_enable_etf_link(struct coresight_device *csdev, > struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); > bool first_enable = false; > > - spin_lock_irqsave(&drvdata->spinlock, flags); > + raw_spin_lock_irqsave(&drvdata->spinlock, flags); > if (drvdata->reading) { > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > return -EBUSY; > } > > @@ -381,7 +381,7 @@ static int tmc_enable_etf_link(struct coresight_device *csdev, > } > if (!ret) > csdev->refcnt++; > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > > if (first_enable) > dev_dbg(&csdev->dev, "TMC-ETF enabled\n"); > @@ -396,9 +396,9 @@ static void tmc_disable_etf_link(struct coresight_device *csdev, > struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); > bool last_disable = false; > > - spin_lock_irqsave(&drvdata->spinlock, flags); > + raw_spin_lock_irqsave(&drvdata->spinlock, flags); > if (drvdata->reading) { > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > return; > } > > @@ -408,7 +408,7 @@ static void tmc_disable_etf_link(struct coresight_device *csdev, > coresight_set_mode(csdev, CS_MODE_DISABLED); > last_disable = true; > } > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > > if (last_disable) > dev_dbg(&csdev->dev, "TMC-ETF disabled\n"); > @@ -488,7 +488,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev, > if (WARN_ON_ONCE(coresight_get_mode(csdev) != CS_MODE_PERF)) > return 0; > > - spin_lock_irqsave(&drvdata->spinlock, flags); > + raw_spin_lock_irqsave(&drvdata->spinlock, flags); > > /* Don't do anything if another tracer is using this sink */ > if (csdev->refcnt != 1) > @@ -585,7 +585,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev, > */ > CS_LOCK(drvdata->base); > out: > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > > return to_read; > } > @@ -623,7 +623,7 @@ int tmc_read_prepare_etb(struct tmc_drvdata *drvdata) > drvdata->config_type != TMC_CONFIG_TYPE_ETF)) > return -EINVAL; > > - spin_lock_irqsave(&drvdata->spinlock, flags); > + raw_spin_lock_irqsave(&drvdata->spinlock, flags); > > if (drvdata->reading) { > ret = -EBUSY; > @@ -655,7 +655,7 @@ int tmc_read_prepare_etb(struct tmc_drvdata *drvdata) > > drvdata->reading = true; > out: > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > > return ret; > } > @@ -672,14 +672,14 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata) > drvdata->config_type != TMC_CONFIG_TYPE_ETF)) > return -EINVAL; > > - spin_lock_irqsave(&drvdata->spinlock, flags); > + raw_spin_lock_irqsave(&drvdata->spinlock, flags); > > /* Re-enable the TMC if need be */ > if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) { > /* There is no point in reading a TMC in HW FIFO mode */ > mode = readl_relaxed(drvdata->base + TMC_MODE); > if (mode != TMC_MODE_CIRCULAR_BUFFER) { > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > return -EINVAL; > } > /* > @@ -693,7 +693,7 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata) > memset(drvdata->buf, 0, drvdata->size); > rc = __tmc_etb_enable_hw(drvdata); > if (rc) { > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > return rc; > } > } else { > @@ -706,7 +706,7 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata) > } > > drvdata->reading = false; > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > > /* > * Free allocated memory outside of the spinlock. There is no need > diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c > index a48bb85d0e7f..a0a90ce7333e 100644 > --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c > +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c > @@ -1176,10 +1176,10 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev) > * buffer, provided the size matches. Any allocation has to be done > * with the lock released. > */ > - spin_lock_irqsave(&drvdata->spinlock, flags); > + raw_spin_lock_irqsave(&drvdata->spinlock, flags); > sysfs_buf = READ_ONCE(drvdata->sysfs_buf); > if (!sysfs_buf || (sysfs_buf->size != drvdata->size)) { > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > > /* Allocate memory with the locks released */ > free_buf = new_buf = tmc_etr_setup_sysfs_buf(drvdata); > @@ -1187,7 +1187,7 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev) > return new_buf; > > /* Let's try again */ > - spin_lock_irqsave(&drvdata->spinlock, flags); > + raw_spin_lock_irqsave(&drvdata->spinlock, flags); > } > > if (drvdata->reading || coresight_get_mode(csdev) == CS_MODE_PERF) { > @@ -1206,7 +1206,7 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev) > } > > out: > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > > /* Free memory outside the spinlock if need be */ > if (free_buf) > @@ -1224,7 +1224,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) > if (IS_ERR(sysfs_buf)) > return PTR_ERR(sysfs_buf); > > - spin_lock_irqsave(&drvdata->spinlock, flags); > + raw_spin_lock_irqsave(&drvdata->spinlock, flags); > > /* > * In sysFS mode we can have multiple writers per sink. Since this > @@ -1243,7 +1243,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) > } > > out: > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > > if (!ret) > dev_dbg(&csdev->dev, "TMC-ETR enabled\n"); > @@ -1562,17 +1562,17 @@ tmc_update_etr_buffer(struct coresight_device *csdev, > struct etr_perf_buffer *etr_perf = config; > struct etr_buf *etr_buf = etr_perf->etr_buf; > > - spin_lock_irqsave(&drvdata->spinlock, flags); > + raw_spin_lock_irqsave(&drvdata->spinlock, flags); > > /* Don't do anything if another tracer is using this sink */ > if (csdev->refcnt != 1) { > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > goto out; > } > > if (WARN_ON(drvdata->perf_buf != etr_buf)) { > lost = true; > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > goto out; > } > > @@ -1582,7 +1582,7 @@ tmc_update_etr_buffer(struct coresight_device *csdev, > tmc_sync_etr_buf(drvdata); > > CS_LOCK(drvdata->base); > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > > lost = etr_buf->full; > offset = etr_buf->offset; > @@ -1651,7 +1651,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data) > struct perf_output_handle *handle = data; > struct etr_perf_buffer *etr_perf = etm_perf_sink_config(handle); > > - spin_lock_irqsave(&drvdata->spinlock, flags); > + raw_spin_lock_irqsave(&drvdata->spinlock, flags); > /* Don't use this sink if it is already claimed by sysFS */ > if (coresight_get_mode(csdev) == CS_MODE_SYSFS) { > rc = -EBUSY; > @@ -1691,7 +1691,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data) > } > > unlock_out: > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > return rc; > } > > @@ -1713,16 +1713,16 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev) > unsigned long flags; > struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); > > - spin_lock_irqsave(&drvdata->spinlock, flags); > + raw_spin_lock_irqsave(&drvdata->spinlock, flags); > > if (drvdata->reading) { > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > return -EBUSY; > } > > csdev->refcnt--; > if (csdev->refcnt) { > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > return -EBUSY; > } > > @@ -1735,7 +1735,7 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev) > /* Reset perf specific data */ > drvdata->perf_buf = NULL; > > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > > dev_dbg(&csdev->dev, "TMC-ETR disabled\n"); > return 0; > @@ -1762,7 +1762,7 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata) > if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR)) > return -EINVAL; > > - spin_lock_irqsave(&drvdata->spinlock, flags); > + raw_spin_lock_irqsave(&drvdata->spinlock, flags); > if (drvdata->reading) { > ret = -EBUSY; > goto out; > @@ -1784,7 +1784,7 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata) > > drvdata->reading = true; > out: > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > > return ret; > } > @@ -1798,7 +1798,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata) > if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR)) > return -EINVAL; > > - spin_lock_irqsave(&drvdata->spinlock, flags); > + raw_spin_lock_irqsave(&drvdata->spinlock, flags); > > /* RE-enable the TMC if need be */ > if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) { > @@ -1818,7 +1818,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata) > } > > drvdata->reading = false; > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > > /* Free allocated memory out side of the spinlock */ > if (sysfs_buf) > diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h > index 2671926be62a..60b395025bc4 100644 > --- a/drivers/hwtracing/coresight/coresight-tmc.h > +++ b/drivers/hwtracing/coresight/coresight-tmc.h > @@ -195,7 +195,7 @@ struct tmc_drvdata { > void __iomem *base; > struct coresight_device *csdev; > struct miscdevice miscdev; > - spinlock_t spinlock; > + raw_spinlock_t spinlock; > pid_t pid; > bool reading; > union { > -- > LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7} > Reviewed-by: Mike Leach <mike.leach@linaro.org>
diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c index e9876252a789..4e9925300931 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-core.c +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c @@ -492,7 +492,7 @@ static int __tmc_probe(struct device *dev, struct resource *res) drvdata->base = base; desc.access = CSDEV_ACCESS_IOMEM(base); - spin_lock_init(&drvdata->spinlock); + raw_spin_lock_init(&drvdata->spinlock); devid = readl_relaxed(drvdata->base + CORESIGHT_DEVID); drvdata->config_type = BMVAL(devid, 6, 7); @@ -596,7 +596,7 @@ static void tmc_shutdown(struct amba_device *adev) unsigned long flags; struct tmc_drvdata *drvdata = amba_get_drvdata(adev); - spin_lock_irqsave(&drvdata->spinlock, flags); + raw_spin_lock_irqsave(&drvdata->spinlock, flags); if (coresight_get_mode(drvdata->csdev) == CS_MODE_DISABLED) goto out; @@ -610,7 +610,7 @@ static void tmc_shutdown(struct amba_device *adev) * the system is going down after this. */ out: - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); } static void __tmc_remove(struct device *dev) diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c index d4f641cd9de6..fca8e9ffb3cf 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c @@ -182,9 +182,9 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev) * If we don't have a buffer release the lock and allocate memory. * Otherwise keep the lock and move along. */ - spin_lock_irqsave(&drvdata->spinlock, flags); + raw_spin_lock_irqsave(&drvdata->spinlock, flags); if (!drvdata->buf) { - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); /* Allocating the memory here while outside of the spinlock */ buf = kzalloc(drvdata->size, GFP_KERNEL); @@ -192,7 +192,7 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev) return -ENOMEM; /* Let's try again */ - spin_lock_irqsave(&drvdata->spinlock, flags); + raw_spin_lock_irqsave(&drvdata->spinlock, flags); } if (drvdata->reading) { @@ -235,7 +235,7 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev) used = false; } out: - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); /* Free memory outside the spinlock if need be */ if (!used) @@ -253,7 +253,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data) struct perf_output_handle *handle = data; struct cs_buffers *buf = etm_perf_sink_config(handle); - spin_lock_irqsave(&drvdata->spinlock, flags); + raw_spin_lock_irqsave(&drvdata->spinlock, flags); do { ret = -EINVAL; if (drvdata->reading) @@ -296,7 +296,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data) csdev->refcnt++; } } while (0); - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); return ret; } @@ -331,16 +331,16 @@ static int tmc_disable_etf_sink(struct coresight_device *csdev) unsigned long flags; struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); - spin_lock_irqsave(&drvdata->spinlock, flags); + raw_spin_lock_irqsave(&drvdata->spinlock, flags); if (drvdata->reading) { - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); return -EBUSY; } csdev->refcnt--; if (csdev->refcnt) { - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); return -EBUSY; } @@ -351,7 +351,7 @@ static int tmc_disable_etf_sink(struct coresight_device *csdev) drvdata->pid = -1; coresight_set_mode(csdev, CS_MODE_DISABLED); - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); dev_dbg(&csdev->dev, "TMC-ETB/ETF disabled\n"); return 0; @@ -366,9 +366,9 @@ static int tmc_enable_etf_link(struct coresight_device *csdev, struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); bool first_enable = false; - spin_lock_irqsave(&drvdata->spinlock, flags); + raw_spin_lock_irqsave(&drvdata->spinlock, flags); if (drvdata->reading) { - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); return -EBUSY; } @@ -381,7 +381,7 @@ static int tmc_enable_etf_link(struct coresight_device *csdev, } if (!ret) csdev->refcnt++; - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); if (first_enable) dev_dbg(&csdev->dev, "TMC-ETF enabled\n"); @@ -396,9 +396,9 @@ static void tmc_disable_etf_link(struct coresight_device *csdev, struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); bool last_disable = false; - spin_lock_irqsave(&drvdata->spinlock, flags); + raw_spin_lock_irqsave(&drvdata->spinlock, flags); if (drvdata->reading) { - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); return; } @@ -408,7 +408,7 @@ static void tmc_disable_etf_link(struct coresight_device *csdev, coresight_set_mode(csdev, CS_MODE_DISABLED); last_disable = true; } - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); if (last_disable) dev_dbg(&csdev->dev, "TMC-ETF disabled\n"); @@ -488,7 +488,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev, if (WARN_ON_ONCE(coresight_get_mode(csdev) != CS_MODE_PERF)) return 0; - spin_lock_irqsave(&drvdata->spinlock, flags); + raw_spin_lock_irqsave(&drvdata->spinlock, flags); /* Don't do anything if another tracer is using this sink */ if (csdev->refcnt != 1) @@ -585,7 +585,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev, */ CS_LOCK(drvdata->base); out: - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); return to_read; } @@ -623,7 +623,7 @@ int tmc_read_prepare_etb(struct tmc_drvdata *drvdata) drvdata->config_type != TMC_CONFIG_TYPE_ETF)) return -EINVAL; - spin_lock_irqsave(&drvdata->spinlock, flags); + raw_spin_lock_irqsave(&drvdata->spinlock, flags); if (drvdata->reading) { ret = -EBUSY; @@ -655,7 +655,7 @@ int tmc_read_prepare_etb(struct tmc_drvdata *drvdata) drvdata->reading = true; out: - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); return ret; } @@ -672,14 +672,14 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata) drvdata->config_type != TMC_CONFIG_TYPE_ETF)) return -EINVAL; - spin_lock_irqsave(&drvdata->spinlock, flags); + raw_spin_lock_irqsave(&drvdata->spinlock, flags); /* Re-enable the TMC if need be */ if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) { /* There is no point in reading a TMC in HW FIFO mode */ mode = readl_relaxed(drvdata->base + TMC_MODE); if (mode != TMC_MODE_CIRCULAR_BUFFER) { - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); return -EINVAL; } /* @@ -693,7 +693,7 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata) memset(drvdata->buf, 0, drvdata->size); rc = __tmc_etb_enable_hw(drvdata); if (rc) { - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); return rc; } } else { @@ -706,7 +706,7 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata) } drvdata->reading = false; - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); /* * Free allocated memory outside of the spinlock. There is no need diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index a48bb85d0e7f..a0a90ce7333e 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -1176,10 +1176,10 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev) * buffer, provided the size matches. Any allocation has to be done * with the lock released. */ - spin_lock_irqsave(&drvdata->spinlock, flags); + raw_spin_lock_irqsave(&drvdata->spinlock, flags); sysfs_buf = READ_ONCE(drvdata->sysfs_buf); if (!sysfs_buf || (sysfs_buf->size != drvdata->size)) { - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); /* Allocate memory with the locks released */ free_buf = new_buf = tmc_etr_setup_sysfs_buf(drvdata); @@ -1187,7 +1187,7 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev) return new_buf; /* Let's try again */ - spin_lock_irqsave(&drvdata->spinlock, flags); + raw_spin_lock_irqsave(&drvdata->spinlock, flags); } if (drvdata->reading || coresight_get_mode(csdev) == CS_MODE_PERF) { @@ -1206,7 +1206,7 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev) } out: - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); /* Free memory outside the spinlock if need be */ if (free_buf) @@ -1224,7 +1224,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) if (IS_ERR(sysfs_buf)) return PTR_ERR(sysfs_buf); - spin_lock_irqsave(&drvdata->spinlock, flags); + raw_spin_lock_irqsave(&drvdata->spinlock, flags); /* * In sysFS mode we can have multiple writers per sink. Since this @@ -1243,7 +1243,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) } out: - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); if (!ret) dev_dbg(&csdev->dev, "TMC-ETR enabled\n"); @@ -1562,17 +1562,17 @@ tmc_update_etr_buffer(struct coresight_device *csdev, struct etr_perf_buffer *etr_perf = config; struct etr_buf *etr_buf = etr_perf->etr_buf; - spin_lock_irqsave(&drvdata->spinlock, flags); + raw_spin_lock_irqsave(&drvdata->spinlock, flags); /* Don't do anything if another tracer is using this sink */ if (csdev->refcnt != 1) { - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); goto out; } if (WARN_ON(drvdata->perf_buf != etr_buf)) { lost = true; - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); goto out; } @@ -1582,7 +1582,7 @@ tmc_update_etr_buffer(struct coresight_device *csdev, tmc_sync_etr_buf(drvdata); CS_LOCK(drvdata->base); - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); lost = etr_buf->full; offset = etr_buf->offset; @@ -1651,7 +1651,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data) struct perf_output_handle *handle = data; struct etr_perf_buffer *etr_perf = etm_perf_sink_config(handle); - spin_lock_irqsave(&drvdata->spinlock, flags); + raw_spin_lock_irqsave(&drvdata->spinlock, flags); /* Don't use this sink if it is already claimed by sysFS */ if (coresight_get_mode(csdev) == CS_MODE_SYSFS) { rc = -EBUSY; @@ -1691,7 +1691,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data) } unlock_out: - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); return rc; } @@ -1713,16 +1713,16 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev) unsigned long flags; struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); - spin_lock_irqsave(&drvdata->spinlock, flags); + raw_spin_lock_irqsave(&drvdata->spinlock, flags); if (drvdata->reading) { - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); return -EBUSY; } csdev->refcnt--; if (csdev->refcnt) { - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); return -EBUSY; } @@ -1735,7 +1735,7 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev) /* Reset perf specific data */ drvdata->perf_buf = NULL; - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); dev_dbg(&csdev->dev, "TMC-ETR disabled\n"); return 0; @@ -1762,7 +1762,7 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata) if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR)) return -EINVAL; - spin_lock_irqsave(&drvdata->spinlock, flags); + raw_spin_lock_irqsave(&drvdata->spinlock, flags); if (drvdata->reading) { ret = -EBUSY; goto out; @@ -1784,7 +1784,7 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata) drvdata->reading = true; out: - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); return ret; } @@ -1798,7 +1798,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata) if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR)) return -EINVAL; - spin_lock_irqsave(&drvdata->spinlock, flags); + raw_spin_lock_irqsave(&drvdata->spinlock, flags); /* RE-enable the TMC if need be */ if (coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS) { @@ -1818,7 +1818,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata) } drvdata->reading = false; - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); /* Free allocated memory out side of the spinlock */ if (sysfs_buf) diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index 2671926be62a..60b395025bc4 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -195,7 +195,7 @@ struct tmc_drvdata { void __iomem *base; struct coresight_device *csdev; struct miscdevice miscdev; - spinlock_t spinlock; + raw_spinlock_t spinlock; pid_t pid; bool reading; union {
In coresight-tmc drivers, tmc_drvdata->spinlock can be held during __schedule() by perf_event_task_sched_out()/in(). Since tmc_drvdata->spinlock type is spinlock_t and perf_event_task_sched_out()/in() is called after acquiring rq_lock, which is raw_spinlock_t (an unsleepable lock), this poses an issue in PREEMPT_RT kernel where spinlock_t is sleepable. To address this, change type tmc_drvdata->spinlock in coresight-tmc drivers, which can be called by perf_event_task_sched_out()/in(), from spinlock_t to raw_spinlock_t. Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com> --- .../hwtracing/coresight/coresight-tmc-core.c | 6 +-- .../hwtracing/coresight/coresight-tmc-etf.c | 48 +++++++++---------- .../hwtracing/coresight/coresight-tmc-etr.c | 40 ++++++++-------- drivers/hwtracing/coresight/coresight-tmc.h | 2 +- 4 files changed, 48 insertions(+), 48 deletions(-)