Message ID | 20241216115006.415861-5-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-cti drivers, cti_drvdata->spinlock can be held during __schedule() > by perf_event_task_sched_out()/in(). > > Since cti_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 cti_drvdata->spinlock in coresight-cti 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-cti-core.c | 44 +++++------ > .../hwtracing/coresight/coresight-cti-sysfs.c | 76 +++++++++---------- > drivers/hwtracing/coresight/coresight-cti.h | 2 +- > 3 files changed, 61 insertions(+), 61 deletions(-) > > diff --git a/drivers/hwtracing/coresight/coresight-cti-core.c b/drivers/hwtracing/coresight/coresight-cti-core.c > index d2b5a5718c29..80f6265e3740 100644 > --- a/drivers/hwtracing/coresight/coresight-cti-core.c > +++ b/drivers/hwtracing/coresight/coresight-cti-core.c > @@ -93,7 +93,7 @@ static int cti_enable_hw(struct cti_drvdata *drvdata) > unsigned long flags; > int rc = 0; > > - spin_lock_irqsave(&drvdata->spinlock, flags); > + raw_spin_lock_irqsave(&drvdata->spinlock, flags); > > /* no need to do anything if enabled or unpowered*/ > if (config->hw_enabled || !config->hw_powered) > @@ -108,7 +108,7 @@ static int cti_enable_hw(struct cti_drvdata *drvdata) > > config->hw_enabled = true; > drvdata->config.enable_req_count++; > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > return rc; > > cti_state_unchanged: > @@ -116,7 +116,7 @@ static int cti_enable_hw(struct cti_drvdata *drvdata) > > /* cannot enable due to error */ > cti_err_not_enabled: > - spin_unlock_irqrestore(&drvdata->spinlock, flags); > + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); > return rc; > } > > @@ -125,7 +125,7 @@ static void cti_cpuhp_enable_hw(struct cti_drvdata *drvdata) > { > struct cti_config *config = &drvdata->config; > > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > config->hw_powered = true; > > /* no need to do anything if no enable request */ > @@ -138,12 +138,12 @@ static void cti_cpuhp_enable_hw(struct cti_drvdata *drvdata) > > cti_write_all_hw_regs(drvdata); > config->hw_enabled = true; > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > return; > > /* did not re-enable due to no claim / no request */ > cti_hp_not_enabled: > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > } > > /* disable hardware */ > @@ -153,7 +153,7 @@ static int cti_disable_hw(struct cti_drvdata *drvdata) > struct coresight_device *csdev = drvdata->csdev; > int ret = 0; > > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > > /* don't allow negative refcounts, return an error */ > if (!drvdata->config.enable_req_count) { > @@ -177,12 +177,12 @@ static int cti_disable_hw(struct cti_drvdata *drvdata) > > coresight_disclaim_device_unlocked(csdev); > CS_LOCK(drvdata->base); > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > return ret; > > /* not disabled this call */ > cti_not_disabled: > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > return ret; > } > > @@ -198,11 +198,11 @@ void cti_write_intack(struct device *dev, u32 ackval) > struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); > struct cti_config *config = &drvdata->config; > > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > /* write if enabled */ > if (cti_active(config)) > cti_write_single_reg(drvdata, CTIINTACK, ackval); > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > } > > /* > @@ -369,7 +369,7 @@ int cti_channel_trig_op(struct device *dev, enum cti_chan_op op, > reg_offset = (direction == CTI_TRIG_IN ? CTIINEN(trigger_idx) : > CTIOUTEN(trigger_idx)); > > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > > /* read - modify write - the trigger / channel enable value */ > reg_value = direction == CTI_TRIG_IN ? config->ctiinen[trigger_idx] : > @@ -388,7 +388,7 @@ int cti_channel_trig_op(struct device *dev, enum cti_chan_op op, > /* write through if enabled */ > if (cti_active(config)) > cti_write_single_reg(drvdata, reg_offset, reg_value); > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > return 0; > } > > @@ -406,7 +406,7 @@ int cti_channel_gate_op(struct device *dev, enum cti_chan_gate_op op, > > chan_bitmask = BIT(channel_idx); > > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > reg_value = config->ctigate; > switch (op) { > case CTI_GATE_CHAN_ENABLE: > @@ -426,7 +426,7 @@ int cti_channel_gate_op(struct device *dev, enum cti_chan_gate_op op, > if (cti_active(config)) > cti_write_single_reg(drvdata, CTIGATE, reg_value); > } > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > return err; > } > > @@ -445,7 +445,7 @@ int cti_channel_setop(struct device *dev, enum cti_chan_set_op op, > > chan_bitmask = BIT(channel_idx); > > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > reg_value = config->ctiappset; > switch (op) { > case CTI_CHAN_SET: > @@ -473,7 +473,7 @@ int cti_channel_setop(struct device *dev, enum cti_chan_set_op op, > > if ((err == 0) && cti_active(config)) > cti_write_single_reg(drvdata, reg_offset, reg_value); > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > > return err; > } > @@ -676,7 +676,7 @@ static int cti_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd, > if (WARN_ON_ONCE(drvdata->ctidev.cpu != cpu)) > return NOTIFY_BAD; > > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > > switch (cmd) { > case CPU_PM_ENTER: > @@ -716,7 +716,7 @@ static int cti_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd, > } > > cti_notify_exit: > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > return notify_res; > } > > @@ -743,11 +743,11 @@ static int cti_dying_cpu(unsigned int cpu) > if (!drvdata) > return 0; > > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > drvdata->config.hw_powered = false; > if (drvdata->config.hw_enabled) > coresight_disclaim_device(drvdata->csdev); > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > return 0; > } > > @@ -888,7 +888,7 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id) > drvdata->ctidev.ctm_id = 0; > INIT_LIST_HEAD(&drvdata->ctidev.trig_cons); > > - spin_lock_init(&drvdata->spinlock); > + raw_spin_lock_init(&drvdata->spinlock); > > /* initialise CTI driver config values */ > cti_set_default_config(dev, drvdata); > diff --git a/drivers/hwtracing/coresight/coresight-cti-sysfs.c b/drivers/hwtracing/coresight/coresight-cti-sysfs.c > index d25dd2737b49..572b80ee96fb 100644 > --- a/drivers/hwtracing/coresight/coresight-cti-sysfs.c > +++ b/drivers/hwtracing/coresight/coresight-cti-sysfs.c > @@ -84,11 +84,11 @@ static ssize_t enable_show(struct device *dev, > bool enabled, powered; > struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); > > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > enable_req = drvdata->config.enable_req_count; > powered = drvdata->config.hw_powered; > enabled = drvdata->config.hw_enabled; > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > > if (powered) > return sprintf(buf, "%d\n", enabled); > @@ -134,9 +134,9 @@ static ssize_t powered_show(struct device *dev, > bool powered; > struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); > > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > powered = drvdata->config.hw_powered; > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > > return sprintf(buf, "%d\n", powered); > } > @@ -181,10 +181,10 @@ static ssize_t coresight_cti_reg_show(struct device *dev, > u32 val = 0; > > pm_runtime_get_sync(dev->parent); > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > if (drvdata->config.hw_powered) > val = readl_relaxed(drvdata->base + cti_attr->off); > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > pm_runtime_put_sync(dev->parent); > return sysfs_emit(buf, "0x%x\n", val); > } > @@ -202,10 +202,10 @@ static __maybe_unused ssize_t coresight_cti_reg_store(struct device *dev, > return -EINVAL; > > pm_runtime_get_sync(dev->parent); > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > if (drvdata->config.hw_powered) > cti_write_single_reg(drvdata, cti_attr->off, val); > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > pm_runtime_put_sync(dev->parent); > return size; > } > @@ -264,7 +264,7 @@ static ssize_t cti_reg32_show(struct device *dev, char *buf, > struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); > struct cti_config *config = &drvdata->config; > > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > if ((reg_offset >= 0) && cti_active(config)) { > CS_UNLOCK(drvdata->base); > val = readl_relaxed(drvdata->base + reg_offset); > @@ -274,7 +274,7 @@ static ssize_t cti_reg32_show(struct device *dev, char *buf, > } else if (pcached_val) { > val = *pcached_val; > } > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > return sprintf(buf, "%#x\n", val); > } > > @@ -293,7 +293,7 @@ static ssize_t cti_reg32_store(struct device *dev, const char *buf, > if (kstrtoul(buf, 0, &val)) > return -EINVAL; > > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > /* local store */ > if (pcached_val) > *pcached_val = (u32)val; > @@ -301,7 +301,7 @@ static ssize_t cti_reg32_store(struct device *dev, const char *buf, > /* write through if offset and enabled */ > if ((reg_offset >= 0) && cti_active(config)) > cti_write_single_reg(drvdata, reg_offset, val); > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > return size; > } > > @@ -349,9 +349,9 @@ static ssize_t inout_sel_store(struct device *dev, > if (val > (CTIINOUTEN_MAX - 1)) > return -EINVAL; > > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > drvdata->config.ctiinout_sel = val; > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > return size; > } > static DEVICE_ATTR_RW(inout_sel); > @@ -364,10 +364,10 @@ static ssize_t inen_show(struct device *dev, > int index; > struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); > > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > index = drvdata->config.ctiinout_sel; > val = drvdata->config.ctiinen[index]; > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > return sprintf(buf, "%#lx\n", val); > } > > @@ -383,14 +383,14 @@ static ssize_t inen_store(struct device *dev, > if (kstrtoul(buf, 0, &val)) > return -EINVAL; > > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > index = config->ctiinout_sel; > config->ctiinen[index] = val; > > /* write through if enabled */ > if (cti_active(config)) > cti_write_single_reg(drvdata, CTIINEN(index), val); > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > return size; > } > static DEVICE_ATTR_RW(inen); > @@ -403,10 +403,10 @@ static ssize_t outen_show(struct device *dev, > int index; > struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); > > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > index = drvdata->config.ctiinout_sel; > val = drvdata->config.ctiouten[index]; > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > return sprintf(buf, "%#lx\n", val); > } > > @@ -422,14 +422,14 @@ static ssize_t outen_store(struct device *dev, > if (kstrtoul(buf, 0, &val)) > return -EINVAL; > > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > index = config->ctiinout_sel; > config->ctiouten[index] = val; > > /* write through if enabled */ > if (cti_active(config)) > cti_write_single_reg(drvdata, CTIOUTEN(index), val); > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > return size; > } > static DEVICE_ATTR_RW(outen); > @@ -463,7 +463,7 @@ static ssize_t appclear_store(struct device *dev, > if (kstrtoul(buf, 0, &val)) > return -EINVAL; > > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > > /* a 1'b1 in appclr clears down the same bit in appset*/ > config->ctiappset &= ~val; > @@ -471,7 +471,7 @@ static ssize_t appclear_store(struct device *dev, > /* write through if enabled */ > if (cti_active(config)) > cti_write_single_reg(drvdata, CTIAPPCLEAR, val); > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > return size; > } > static DEVICE_ATTR_WO(appclear); > @@ -487,12 +487,12 @@ static ssize_t apppulse_store(struct device *dev, > if (kstrtoul(buf, 0, &val)) > return -EINVAL; > > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > > /* write through if enabled */ > if (cti_active(config)) > cti_write_single_reg(drvdata, CTIAPPPULSE, val); > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > return size; > } > static DEVICE_ATTR_WO(apppulse); > @@ -681,9 +681,9 @@ static ssize_t trig_filter_enable_show(struct device *dev, > u32 val; > struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); > > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > val = drvdata->config.trig_filter_enable; > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > return sprintf(buf, "%d\n", val); > } > > @@ -697,9 +697,9 @@ static ssize_t trig_filter_enable_store(struct device *dev, > if (kstrtoul(buf, 0, &val)) > return -EINVAL; > > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > drvdata->config.trig_filter_enable = !!val; > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > return size; > } > static DEVICE_ATTR_RW(trig_filter_enable); > @@ -728,7 +728,7 @@ static ssize_t chan_xtrigs_reset_store(struct device *dev, > struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); > struct cti_config *config = &drvdata->config; > > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > > /* clear the CTI trigger / channel programming registers */ > for (i = 0; i < config->nr_trig_max; i++) { > @@ -747,7 +747,7 @@ static ssize_t chan_xtrigs_reset_store(struct device *dev, > if (cti_active(config)) > cti_write_all_hw_regs(drvdata); > > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > return size; > } > static DEVICE_ATTR_WO(chan_xtrigs_reset); > @@ -768,9 +768,9 @@ static ssize_t chan_xtrigs_sel_store(struct device *dev, > if (val > (drvdata->config.nr_ctm_channels - 1)) > return -EINVAL; > > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > drvdata->config.xtrig_rchan_sel = val; > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > return size; > } > > @@ -781,9 +781,9 @@ static ssize_t chan_xtrigs_sel_show(struct device *dev, > unsigned long val; > struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); > > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > val = drvdata->config.xtrig_rchan_sel; > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > > return sprintf(buf, "%ld\n", val); > } > @@ -838,12 +838,12 @@ static ssize_t print_chan_list(struct device *dev, > unsigned long inuse_bits = 0, chan_mask; > > /* scan regs to get bitmap of channels in use. */ > - spin_lock(&drvdata->spinlock); > + raw_spin_lock(&drvdata->spinlock); > for (i = 0; i < config->nr_trig_max; i++) { > inuse_bits |= config->ctiinen[i]; > inuse_bits |= config->ctiouten[i]; > } > - spin_unlock(&drvdata->spinlock); > + raw_spin_unlock(&drvdata->spinlock); > > /* inverse bits if printing free channels */ > if (!inuse) > diff --git a/drivers/hwtracing/coresight/coresight-cti.h b/drivers/hwtracing/coresight/coresight-cti.h > index cb9ee616d01f..16e310e7e9d4 100644 > --- a/drivers/hwtracing/coresight/coresight-cti.h > +++ b/drivers/hwtracing/coresight/coresight-cti.h > @@ -175,7 +175,7 @@ struct cti_drvdata { > void __iomem *base; > struct coresight_device *csdev; > struct cti_device ctidev; > - spinlock_t spinlock; > + raw_spinlock_t spinlock; > struct cti_config config; > struct list_head node; > void (*csdev_release)(struct device *dev); > -- > LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7} > Reviewed-by: Mike Leach <mike.leach@linaro.org> -- Mike Leach Principal Engineer, ARM Ltd. Manchester Design Centre. UK
diff --git a/drivers/hwtracing/coresight/coresight-cti-core.c b/drivers/hwtracing/coresight/coresight-cti-core.c index d2b5a5718c29..80f6265e3740 100644 --- a/drivers/hwtracing/coresight/coresight-cti-core.c +++ b/drivers/hwtracing/coresight/coresight-cti-core.c @@ -93,7 +93,7 @@ static int cti_enable_hw(struct cti_drvdata *drvdata) unsigned long flags; int rc = 0; - spin_lock_irqsave(&drvdata->spinlock, flags); + raw_spin_lock_irqsave(&drvdata->spinlock, flags); /* no need to do anything if enabled or unpowered*/ if (config->hw_enabled || !config->hw_powered) @@ -108,7 +108,7 @@ static int cti_enable_hw(struct cti_drvdata *drvdata) config->hw_enabled = true; drvdata->config.enable_req_count++; - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); return rc; cti_state_unchanged: @@ -116,7 +116,7 @@ static int cti_enable_hw(struct cti_drvdata *drvdata) /* cannot enable due to error */ cti_err_not_enabled: - spin_unlock_irqrestore(&drvdata->spinlock, flags); + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); return rc; } @@ -125,7 +125,7 @@ static void cti_cpuhp_enable_hw(struct cti_drvdata *drvdata) { struct cti_config *config = &drvdata->config; - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); config->hw_powered = true; /* no need to do anything if no enable request */ @@ -138,12 +138,12 @@ static void cti_cpuhp_enable_hw(struct cti_drvdata *drvdata) cti_write_all_hw_regs(drvdata); config->hw_enabled = true; - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); return; /* did not re-enable due to no claim / no request */ cti_hp_not_enabled: - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); } /* disable hardware */ @@ -153,7 +153,7 @@ static int cti_disable_hw(struct cti_drvdata *drvdata) struct coresight_device *csdev = drvdata->csdev; int ret = 0; - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); /* don't allow negative refcounts, return an error */ if (!drvdata->config.enable_req_count) { @@ -177,12 +177,12 @@ static int cti_disable_hw(struct cti_drvdata *drvdata) coresight_disclaim_device_unlocked(csdev); CS_LOCK(drvdata->base); - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); return ret; /* not disabled this call */ cti_not_disabled: - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); return ret; } @@ -198,11 +198,11 @@ void cti_write_intack(struct device *dev, u32 ackval) struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); struct cti_config *config = &drvdata->config; - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); /* write if enabled */ if (cti_active(config)) cti_write_single_reg(drvdata, CTIINTACK, ackval); - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); } /* @@ -369,7 +369,7 @@ int cti_channel_trig_op(struct device *dev, enum cti_chan_op op, reg_offset = (direction == CTI_TRIG_IN ? CTIINEN(trigger_idx) : CTIOUTEN(trigger_idx)); - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); /* read - modify write - the trigger / channel enable value */ reg_value = direction == CTI_TRIG_IN ? config->ctiinen[trigger_idx] : @@ -388,7 +388,7 @@ int cti_channel_trig_op(struct device *dev, enum cti_chan_op op, /* write through if enabled */ if (cti_active(config)) cti_write_single_reg(drvdata, reg_offset, reg_value); - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); return 0; } @@ -406,7 +406,7 @@ int cti_channel_gate_op(struct device *dev, enum cti_chan_gate_op op, chan_bitmask = BIT(channel_idx); - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); reg_value = config->ctigate; switch (op) { case CTI_GATE_CHAN_ENABLE: @@ -426,7 +426,7 @@ int cti_channel_gate_op(struct device *dev, enum cti_chan_gate_op op, if (cti_active(config)) cti_write_single_reg(drvdata, CTIGATE, reg_value); } - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); return err; } @@ -445,7 +445,7 @@ int cti_channel_setop(struct device *dev, enum cti_chan_set_op op, chan_bitmask = BIT(channel_idx); - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); reg_value = config->ctiappset; switch (op) { case CTI_CHAN_SET: @@ -473,7 +473,7 @@ int cti_channel_setop(struct device *dev, enum cti_chan_set_op op, if ((err == 0) && cti_active(config)) cti_write_single_reg(drvdata, reg_offset, reg_value); - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); return err; } @@ -676,7 +676,7 @@ static int cti_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd, if (WARN_ON_ONCE(drvdata->ctidev.cpu != cpu)) return NOTIFY_BAD; - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); switch (cmd) { case CPU_PM_ENTER: @@ -716,7 +716,7 @@ static int cti_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd, } cti_notify_exit: - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); return notify_res; } @@ -743,11 +743,11 @@ static int cti_dying_cpu(unsigned int cpu) if (!drvdata) return 0; - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); drvdata->config.hw_powered = false; if (drvdata->config.hw_enabled) coresight_disclaim_device(drvdata->csdev); - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); return 0; } @@ -888,7 +888,7 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id) drvdata->ctidev.ctm_id = 0; INIT_LIST_HEAD(&drvdata->ctidev.trig_cons); - spin_lock_init(&drvdata->spinlock); + raw_spin_lock_init(&drvdata->spinlock); /* initialise CTI driver config values */ cti_set_default_config(dev, drvdata); diff --git a/drivers/hwtracing/coresight/coresight-cti-sysfs.c b/drivers/hwtracing/coresight/coresight-cti-sysfs.c index d25dd2737b49..572b80ee96fb 100644 --- a/drivers/hwtracing/coresight/coresight-cti-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-cti-sysfs.c @@ -84,11 +84,11 @@ static ssize_t enable_show(struct device *dev, bool enabled, powered; struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); enable_req = drvdata->config.enable_req_count; powered = drvdata->config.hw_powered; enabled = drvdata->config.hw_enabled; - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); if (powered) return sprintf(buf, "%d\n", enabled); @@ -134,9 +134,9 @@ static ssize_t powered_show(struct device *dev, bool powered; struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); powered = drvdata->config.hw_powered; - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); return sprintf(buf, "%d\n", powered); } @@ -181,10 +181,10 @@ static ssize_t coresight_cti_reg_show(struct device *dev, u32 val = 0; pm_runtime_get_sync(dev->parent); - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); if (drvdata->config.hw_powered) val = readl_relaxed(drvdata->base + cti_attr->off); - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); pm_runtime_put_sync(dev->parent); return sysfs_emit(buf, "0x%x\n", val); } @@ -202,10 +202,10 @@ static __maybe_unused ssize_t coresight_cti_reg_store(struct device *dev, return -EINVAL; pm_runtime_get_sync(dev->parent); - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); if (drvdata->config.hw_powered) cti_write_single_reg(drvdata, cti_attr->off, val); - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); pm_runtime_put_sync(dev->parent); return size; } @@ -264,7 +264,7 @@ static ssize_t cti_reg32_show(struct device *dev, char *buf, struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); struct cti_config *config = &drvdata->config; - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); if ((reg_offset >= 0) && cti_active(config)) { CS_UNLOCK(drvdata->base); val = readl_relaxed(drvdata->base + reg_offset); @@ -274,7 +274,7 @@ static ssize_t cti_reg32_show(struct device *dev, char *buf, } else if (pcached_val) { val = *pcached_val; } - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); return sprintf(buf, "%#x\n", val); } @@ -293,7 +293,7 @@ static ssize_t cti_reg32_store(struct device *dev, const char *buf, if (kstrtoul(buf, 0, &val)) return -EINVAL; - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); /* local store */ if (pcached_val) *pcached_val = (u32)val; @@ -301,7 +301,7 @@ static ssize_t cti_reg32_store(struct device *dev, const char *buf, /* write through if offset and enabled */ if ((reg_offset >= 0) && cti_active(config)) cti_write_single_reg(drvdata, reg_offset, val); - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); return size; } @@ -349,9 +349,9 @@ static ssize_t inout_sel_store(struct device *dev, if (val > (CTIINOUTEN_MAX - 1)) return -EINVAL; - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); drvdata->config.ctiinout_sel = val; - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); return size; } static DEVICE_ATTR_RW(inout_sel); @@ -364,10 +364,10 @@ static ssize_t inen_show(struct device *dev, int index; struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); index = drvdata->config.ctiinout_sel; val = drvdata->config.ctiinen[index]; - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); return sprintf(buf, "%#lx\n", val); } @@ -383,14 +383,14 @@ static ssize_t inen_store(struct device *dev, if (kstrtoul(buf, 0, &val)) return -EINVAL; - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); index = config->ctiinout_sel; config->ctiinen[index] = val; /* write through if enabled */ if (cti_active(config)) cti_write_single_reg(drvdata, CTIINEN(index), val); - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); return size; } static DEVICE_ATTR_RW(inen); @@ -403,10 +403,10 @@ static ssize_t outen_show(struct device *dev, int index; struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); index = drvdata->config.ctiinout_sel; val = drvdata->config.ctiouten[index]; - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); return sprintf(buf, "%#lx\n", val); } @@ -422,14 +422,14 @@ static ssize_t outen_store(struct device *dev, if (kstrtoul(buf, 0, &val)) return -EINVAL; - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); index = config->ctiinout_sel; config->ctiouten[index] = val; /* write through if enabled */ if (cti_active(config)) cti_write_single_reg(drvdata, CTIOUTEN(index), val); - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); return size; } static DEVICE_ATTR_RW(outen); @@ -463,7 +463,7 @@ static ssize_t appclear_store(struct device *dev, if (kstrtoul(buf, 0, &val)) return -EINVAL; - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); /* a 1'b1 in appclr clears down the same bit in appset*/ config->ctiappset &= ~val; @@ -471,7 +471,7 @@ static ssize_t appclear_store(struct device *dev, /* write through if enabled */ if (cti_active(config)) cti_write_single_reg(drvdata, CTIAPPCLEAR, val); - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); return size; } static DEVICE_ATTR_WO(appclear); @@ -487,12 +487,12 @@ static ssize_t apppulse_store(struct device *dev, if (kstrtoul(buf, 0, &val)) return -EINVAL; - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); /* write through if enabled */ if (cti_active(config)) cti_write_single_reg(drvdata, CTIAPPPULSE, val); - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); return size; } static DEVICE_ATTR_WO(apppulse); @@ -681,9 +681,9 @@ static ssize_t trig_filter_enable_show(struct device *dev, u32 val; struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); val = drvdata->config.trig_filter_enable; - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); return sprintf(buf, "%d\n", val); } @@ -697,9 +697,9 @@ static ssize_t trig_filter_enable_store(struct device *dev, if (kstrtoul(buf, 0, &val)) return -EINVAL; - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); drvdata->config.trig_filter_enable = !!val; - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); return size; } static DEVICE_ATTR_RW(trig_filter_enable); @@ -728,7 +728,7 @@ static ssize_t chan_xtrigs_reset_store(struct device *dev, struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); struct cti_config *config = &drvdata->config; - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); /* clear the CTI trigger / channel programming registers */ for (i = 0; i < config->nr_trig_max; i++) { @@ -747,7 +747,7 @@ static ssize_t chan_xtrigs_reset_store(struct device *dev, if (cti_active(config)) cti_write_all_hw_regs(drvdata); - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); return size; } static DEVICE_ATTR_WO(chan_xtrigs_reset); @@ -768,9 +768,9 @@ static ssize_t chan_xtrigs_sel_store(struct device *dev, if (val > (drvdata->config.nr_ctm_channels - 1)) return -EINVAL; - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); drvdata->config.xtrig_rchan_sel = val; - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); return size; } @@ -781,9 +781,9 @@ static ssize_t chan_xtrigs_sel_show(struct device *dev, unsigned long val; struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); val = drvdata->config.xtrig_rchan_sel; - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); return sprintf(buf, "%ld\n", val); } @@ -838,12 +838,12 @@ static ssize_t print_chan_list(struct device *dev, unsigned long inuse_bits = 0, chan_mask; /* scan regs to get bitmap of channels in use. */ - spin_lock(&drvdata->spinlock); + raw_spin_lock(&drvdata->spinlock); for (i = 0; i < config->nr_trig_max; i++) { inuse_bits |= config->ctiinen[i]; inuse_bits |= config->ctiouten[i]; } - spin_unlock(&drvdata->spinlock); + raw_spin_unlock(&drvdata->spinlock); /* inverse bits if printing free channels */ if (!inuse) diff --git a/drivers/hwtracing/coresight/coresight-cti.h b/drivers/hwtracing/coresight/coresight-cti.h index cb9ee616d01f..16e310e7e9d4 100644 --- a/drivers/hwtracing/coresight/coresight-cti.h +++ b/drivers/hwtracing/coresight/coresight-cti.h @@ -175,7 +175,7 @@ struct cti_drvdata { void __iomem *base; struct coresight_device *csdev; struct cti_device ctidev; - spinlock_t spinlock; + raw_spinlock_t spinlock; struct cti_config config; struct list_head node; void (*csdev_release)(struct device *dev);
In coresight-cti drivers, cti_drvdata->spinlock can be held during __schedule() by perf_event_task_sched_out()/in(). Since cti_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 cti_drvdata->spinlock in coresight-cti 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-cti-core.c | 44 +++++------ .../hwtracing/coresight/coresight-cti-sysfs.c | 76 +++++++++---------- drivers/hwtracing/coresight/coresight-cti.h | 2 +- 3 files changed, 61 insertions(+), 61 deletions(-)