[PATCH v8 09/23] coresight: syscfg: Use spinlock to protect active variables
Leo Yan
leo.yan at arm.com
Wed Mar 25 07:26:46 PDT 2026
To support dynamically enabling and disabling the CoreSight path during
CPU idle, cscfg_config_sysfs_get_active_cfg() may be called by the ETM
driver in an atomic context. However, the function currently acquires a
mutex, which is a sleepable lock, and this is not allowed in atomic
context.
To make cscfg_config_sysfs_get_active_cfg() called in the idle flow,
replace the mutex with a raw spinlock to protect the active
variables.
Acquire the raw spinlock with IRQ-safe to avoid lockdep complaint.
Reviewed-by: James Clark <james.clark at linaro.org>
Tested-by: James Clark <james.clark at linaro.org>
Reviewed-by: Yeoreum Yun <yeoreum.yun at arm.com>
Signed-off-by: Leo Yan <leo.yan at arm.com>
---
drivers/hwtracing/coresight/coresight-syscfg.c | 21 ++++++++++-----------
drivers/hwtracing/coresight/coresight-syscfg.h | 2 ++
2 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
index d7f5037953d6ba7fb7f83a8012a1abc5ffd0a147..7e070787e18b47bc4be17b0f9821267268600513 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.c
+++ b/drivers/hwtracing/coresight/coresight-syscfg.c
@@ -953,19 +953,21 @@ int cscfg_config_sysfs_activate(struct cscfg_config_desc *config_desc, bool acti
unsigned long cfg_hash;
int err = 0;
- mutex_lock(&cscfg_mutex);
+ guard(mutex)(&cscfg_mutex);
cfg_hash = (unsigned long)config_desc->event_ea->var;
+ guard(raw_spinlock_irqsave)(&cscfg_mgr->sysfs_store_lock);
+
if (activate) {
/* cannot be a current active value to activate this */
if (cscfg_mgr->sysfs_active_config) {
err = -EBUSY;
- goto exit_unlock;
+ } else {
+ err = _cscfg_activate_config(cfg_hash);
+ if (!err)
+ cscfg_mgr->sysfs_active_config = cfg_hash;
}
- err = _cscfg_activate_config(cfg_hash);
- if (!err)
- cscfg_mgr->sysfs_active_config = cfg_hash;
} else {
/* disable if matching current value */
if (cscfg_mgr->sysfs_active_config == cfg_hash) {
@@ -975,17 +977,14 @@ int cscfg_config_sysfs_activate(struct cscfg_config_desc *config_desc, bool acti
err = -EINVAL;
}
-exit_unlock:
- mutex_unlock(&cscfg_mutex);
return err;
}
/* set the sysfs preset value */
void cscfg_config_sysfs_set_preset(int preset)
{
- mutex_lock(&cscfg_mutex);
+ guard(raw_spinlock_irqsave)(&cscfg_mgr->sysfs_store_lock);
cscfg_mgr->sysfs_active_preset = preset;
- mutex_unlock(&cscfg_mutex);
}
/*
@@ -994,10 +993,9 @@ void cscfg_config_sysfs_set_preset(int preset)
*/
void cscfg_config_sysfs_get_active_cfg(unsigned long *cfg_hash, int *preset)
{
- mutex_lock(&cscfg_mutex);
+ guard(raw_spinlock_irqsave)(&cscfg_mgr->sysfs_store_lock);
*preset = cscfg_mgr->sysfs_active_preset;
*cfg_hash = cscfg_mgr->sysfs_active_config;
- mutex_unlock(&cscfg_mutex);
}
EXPORT_SYMBOL_GPL(cscfg_config_sysfs_get_active_cfg);
@@ -1201,6 +1199,7 @@ static int cscfg_create_device(void)
INIT_LIST_HEAD(&cscfg_mgr->load_order_list);
atomic_set(&cscfg_mgr->sys_active_cnt, 0);
cscfg_mgr->load_state = CSCFG_NONE;
+ raw_spin_lock_init(&cscfg_mgr->sysfs_store_lock);
/* setup the device */
dev = cscfg_device();
diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h
index 66e2db890d8203853a0c3c907b48aa66dd8014e6..658e93c3705f1cb3ba3523d0bc27ac704697dd70 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.h
+++ b/drivers/hwtracing/coresight/coresight-syscfg.h
@@ -42,6 +42,7 @@ enum cscfg_load_ops {
* @sysfs_active_config:Active config hash used if CoreSight controlled from sysfs.
* @sysfs_active_preset:Active preset index used if CoreSight controlled from sysfs.
* @load_state: A multi-stage load/unload operation is in progress.
+ * @sysfs_store_lock: Exclusive access sysfs stored variables.
*/
struct cscfg_manager {
struct device dev;
@@ -54,6 +55,7 @@ struct cscfg_manager {
u32 sysfs_active_config;
int sysfs_active_preset;
enum cscfg_load_ops load_state;
+ raw_spinlock_t sysfs_store_lock;
};
/* get reference to dev in cscfg_manager */
--
2.34.1
More information about the linux-arm-kernel
mailing list