From: Leo Yan Date: Fri, 15 May 2026 20:08:21 +0000 (+0100) Subject: coresight: syscfg: Use IRQ-safe spinlock to protect active variables X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=3b6e3e04659a7e32cfbf71d6958eb6318bae50c0;p=thirdparty%2Fkernel%2Flinux.git coresight: syscfg: Use IRQ-safe spinlock to protect active variables cscfg_config_sysfs_get_active_cfg() will be used from idle flows, while sleeping locks are not allowed. Introduce sysfs_store_lock to replace the mutex to protect sysfs_active_config and sysfs_active_preset accesses, with IRQ-safe locking to avoid lockdep complaint. Refactor cscfg_config_sysfs_activate() to use spinlock for sysfs_active_config and activate/deactivate config. Tested-by: Jie Gan Reviewed-by: Yeoreum Yun Reviewed-by: James Clark Tested-by: James Clark Signed-off-by: Leo Yan Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/20260515-arm_coresight_path_power_management_improvement-v14-14-f88c4a3ecfe9@arm.com --- diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c index d7f5037953d6..2bfdd7b45e49 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.c +++ b/drivers/hwtracing/coresight/coresight-syscfg.c @@ -953,39 +953,41 @@ 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; if (activate) { /* cannot be a current active value to activate this */ - if (cscfg_mgr->sysfs_active_config) { - err = -EBUSY; - goto exit_unlock; - } - err = _cscfg_activate_config(cfg_hash); - if (!err) + if (cscfg_mgr->sysfs_active_config) + return -EBUSY; + + scoped_guard(raw_spinlock_irqsave, &cscfg_mgr->sysfs_store_lock) { + err = _cscfg_activate_config(cfg_hash); + if (err) + return err; + cscfg_mgr->sysfs_active_config = cfg_hash; + } } else { - /* disable if matching current value */ - if (cscfg_mgr->sysfs_active_config == cfg_hash) { + if (cscfg_mgr->sysfs_active_config != cfg_hash) + return -EINVAL; + + scoped_guard(raw_spinlock_irqsave, &cscfg_mgr->sysfs_store_lock) { + /* disable if matching current value */ _cscfg_deactivate_config(cfg_hash); cscfg_mgr->sysfs_active_config = 0; - } else - err = -EINVAL; + } } -exit_unlock: - mutex_unlock(&cscfg_mutex); - return err; + return 0; } /* 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 +996,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 +1202,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 66e2db890d82..658e93c3705f 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 */