]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
coresight: syscfg: Use IRQ-safe spinlock to protect active variables
authorLeo Yan <leo.yan@arm.com>
Fri, 15 May 2026 20:08:21 +0000 (21:08 +0100)
committerSuzuki K Poulose <suzuki.poulose@arm.com>
Mon, 18 May 2026 09:18:46 +0000 (10:18 +0100)
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 <jie.gan@oss.qualcomm.com>
Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com>
Reviewed-by: James Clark <james.clark@linaro.org>
Tested-by: James Clark <james.clark@linaro.org>
Signed-off-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Link: https://lore.kernel.org/r/20260515-arm_coresight_path_power_management_improvement-v14-14-f88c4a3ecfe9@arm.com
drivers/hwtracing/coresight/coresight-syscfg.c
drivers/hwtracing/coresight/coresight-syscfg.h

index d7f5037953d6ba7fb7f83a8012a1abc5ffd0a147..2bfdd7b45e49c8bec88428545069577431083bda 100644 (file)
@@ -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();
index 66e2db890d8203853a0c3c907b48aa66dd8014e6..658e93c3705f1cb3ba3523d0bc27ac704697dd70 100644 (file)
@@ -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 */