mirror of
https://github.com/torvalds/linux.git
synced 2026-07-29 02:31:27 +02:00
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 <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
This commit is contained in:
parent
81bf1c33f6
commit
3b6e3e0465
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user