Skip to content

Commit b37dda1

Browse files
committed
coresight: configfs: Allow configfs to activate configuration
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2055405 commit 7ebd0ec Author: Mike Leach <mike.leach@linaro.org> Date: Wed Nov 24 20:00:37 2021 +0000 coresight: configfs: Allow configfs to activate configuration Adds configfs attributes to allow a configuration to be enabled for use when sysfs is used to control CoreSight. perf retains independent enabling of configurations. Signed-off-by: Mike Leach <mike.leach@linaro.org> Link: https://lore.kernel.org/r/20211124200038.28662-6-mike.leach@linaro.org Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org> Signed-off-by: Jeremy Linton <jlinton@redhat.com>
1 parent f582375 commit b37dda1

File tree

5 files changed

+186
-28
lines changed

5 files changed

+186
-28
lines changed

drivers/hwtracing/coresight/coresight-etm4x-core.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -723,7 +723,16 @@ static int etm4_enable_sysfs(struct coresight_device *csdev)
723723
{
724724
struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
725725
struct etm4_enable_arg arg = { };
726-
int ret;
726+
unsigned long cfg_hash;
727+
int ret, preset;
728+
729+
/* enable any config activated by configfs */
730+
cscfg_config_sysfs_get_active_cfg(&cfg_hash, &preset);
731+
if (cfg_hash) {
732+
ret = cscfg_csdev_enable_active_config(csdev, cfg_hash, preset);
733+
if (ret)
734+
return ret;
735+
}
727736

728737
spin_lock(&drvdata->spinlock);
729738

drivers/hwtracing/coresight/coresight-syscfg-configfs.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <linux/configfs.h>
88

9+
#include "coresight-config.h"
910
#include "coresight-syscfg-configfs.h"
1011

1112
/* create a default ci_type. */
@@ -87,9 +88,75 @@ static ssize_t cscfg_cfg_values_show(struct config_item *item, char *page)
8788
}
8889
CONFIGFS_ATTR_RO(cscfg_cfg_, values);
8990

91+
static ssize_t cscfg_cfg_enable_show(struct config_item *item, char *page)
92+
{
93+
struct cscfg_fs_config *fs_config = container_of(to_config_group(item),
94+
struct cscfg_fs_config, group);
95+
96+
return scnprintf(page, PAGE_SIZE, "%d\n", fs_config->active);
97+
}
98+
99+
static ssize_t cscfg_cfg_enable_store(struct config_item *item,
100+
const char *page, size_t count)
101+
{
102+
struct cscfg_fs_config *fs_config = container_of(to_config_group(item),
103+
struct cscfg_fs_config, group);
104+
int err;
105+
bool val;
106+
107+
err = kstrtobool(page, &val);
108+
if (!err)
109+
err = cscfg_config_sysfs_activate(fs_config->config_desc, val);
110+
if (!err) {
111+
fs_config->active = val;
112+
if (val)
113+
cscfg_config_sysfs_set_preset(fs_config->preset);
114+
}
115+
return err ? err : count;
116+
}
117+
CONFIGFS_ATTR(cscfg_cfg_, enable);
118+
119+
static ssize_t cscfg_cfg_preset_show(struct config_item *item, char *page)
120+
{
121+
struct cscfg_fs_config *fs_config = container_of(to_config_group(item),
122+
struct cscfg_fs_config, group);
123+
124+
return scnprintf(page, PAGE_SIZE, "%d\n", fs_config->preset);
125+
}
126+
127+
static ssize_t cscfg_cfg_preset_store(struct config_item *item,
128+
const char *page, size_t count)
129+
{
130+
struct cscfg_fs_config *fs_config = container_of(to_config_group(item),
131+
struct cscfg_fs_config, group);
132+
int preset, err;
133+
134+
err = kstrtoint(page, 0, &preset);
135+
if (!err) {
136+
/*
137+
* presets start at 1, and go up to max (15),
138+
* but the config may provide fewer.
139+
*/
140+
if ((preset < 1) || (preset > fs_config->config_desc->nr_presets))
141+
err = -EINVAL;
142+
}
143+
144+
if (!err) {
145+
/* set new value */
146+
fs_config->preset = preset;
147+
/* set on system if active */
148+
if (fs_config->active)
149+
cscfg_config_sysfs_set_preset(fs_config->preset);
150+
}
151+
return err ? err : count;
152+
}
153+
CONFIGFS_ATTR(cscfg_cfg_, preset);
154+
90155
static struct configfs_attribute *cscfg_config_view_attrs[] = {
91156
&cscfg_cfg_attr_description,
92157
&cscfg_cfg_attr_feature_refs,
158+
&cscfg_cfg_attr_enable,
159+
&cscfg_cfg_attr_preset,
93160
NULL,
94161
};
95162

drivers/hwtracing/coresight/coresight-syscfg-configfs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
struct cscfg_fs_config {
1616
struct cscfg_config_desc *config_desc;
1717
struct config_group group;
18+
bool active;
19+
int preset;
1820
};
1921

2022
/* container for feature view */

drivers/hwtracing/coresight/coresight-syscfg.c

Lines changed: 100 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -745,30 +745,20 @@ void cscfg_csdev_reset_feats(struct coresight_device *csdev)
745745
}
746746
EXPORT_SYMBOL_GPL(cscfg_csdev_reset_feats);
747747

748-
/**
749-
* cscfg_activate_config - Mark a configuration descriptor as active.
750-
*
751-
* This will be seen when csdev devices are enabled in the system.
752-
* Only activated configurations can be enabled on individual devices.
753-
* Activation protects the configuration from alteration or removal while
754-
* active.
755-
*
756-
* Selection by hash value - generated from the configuration name when it
757-
* was loaded and added to the cs_etm/configurations file system for selection
758-
* by perf.
748+
/*
749+
* This activate configuration for either perf or sysfs. Perf can have multiple
750+
* active configs, selected per event, sysfs is limited to one.
759751
*
760752
* Increments the configuration descriptor active count and the global active
761753
* count.
762754
*
763755
* @cfg_hash: Hash value of the selected configuration name.
764756
*/
765-
int cscfg_activate_config(unsigned long cfg_hash)
757+
static int _cscfg_activate_config(unsigned long cfg_hash)
766758
{
767759
struct cscfg_config_desc *config_desc;
768760
int err = -EINVAL;
769761

770-
mutex_lock(&cscfg_mutex);
771-
772762
list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) {
773763
if ((unsigned long)config_desc->event_ea->var == cfg_hash) {
774764
/* must ensure that config cannot be unloaded in use */
@@ -792,6 +782,101 @@ int cscfg_activate_config(unsigned long cfg_hash)
792782
break;
793783
}
794784
}
785+
return err;
786+
}
787+
788+
static void _cscfg_deactivate_config(unsigned long cfg_hash)
789+
{
790+
struct cscfg_config_desc *config_desc;
791+
792+
list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) {
793+
if ((unsigned long)config_desc->event_ea->var == cfg_hash) {
794+
atomic_dec(&config_desc->active_cnt);
795+
atomic_dec(&cscfg_mgr->sys_active_cnt);
796+
cscfg_owner_put(config_desc->load_owner);
797+
dev_dbg(cscfg_device(), "Deactivate config %s.\n", config_desc->name);
798+
break;
799+
}
800+
}
801+
}
802+
803+
/*
804+
* called from configfs to set/clear the active configuration for use when
805+
* using sysfs to control trace.
806+
*/
807+
int cscfg_config_sysfs_activate(struct cscfg_config_desc *config_desc, bool activate)
808+
{
809+
unsigned long cfg_hash;
810+
int err = 0;
811+
812+
mutex_lock(&cscfg_mutex);
813+
814+
cfg_hash = (unsigned long)config_desc->event_ea->var;
815+
816+
if (activate) {
817+
/* cannot be a current active value to activate this */
818+
if (cscfg_mgr->sysfs_active_config) {
819+
err = -EBUSY;
820+
goto exit_unlock;
821+
}
822+
err = _cscfg_activate_config(cfg_hash);
823+
if (!err)
824+
cscfg_mgr->sysfs_active_config = cfg_hash;
825+
} else {
826+
/* disable if matching current value */
827+
if (cscfg_mgr->sysfs_active_config == cfg_hash) {
828+
_cscfg_deactivate_config(cfg_hash);
829+
cscfg_mgr->sysfs_active_config = 0;
830+
} else
831+
err = -EINVAL;
832+
}
833+
834+
exit_unlock:
835+
mutex_unlock(&cscfg_mutex);
836+
return err;
837+
}
838+
839+
/* set the sysfs preset value */
840+
void cscfg_config_sysfs_set_preset(int preset)
841+
{
842+
mutex_lock(&cscfg_mutex);
843+
cscfg_mgr->sysfs_active_preset = preset;
844+
mutex_unlock(&cscfg_mutex);
845+
}
846+
847+
/*
848+
* Used by a device to get the config and preset selected as active in configfs,
849+
* when using sysfs to control trace.
850+
*/
851+
void cscfg_config_sysfs_get_active_cfg(unsigned long *cfg_hash, int *preset)
852+
{
853+
mutex_lock(&cscfg_mutex);
854+
*preset = cscfg_mgr->sysfs_active_preset;
855+
*cfg_hash = cscfg_mgr->sysfs_active_config;
856+
mutex_unlock(&cscfg_mutex);
857+
}
858+
EXPORT_SYMBOL_GPL(cscfg_config_sysfs_get_active_cfg);
859+
860+
/**
861+
* cscfg_activate_config - Mark a configuration descriptor as active.
862+
*
863+
* This will be seen when csdev devices are enabled in the system.
864+
* Only activated configurations can be enabled on individual devices.
865+
* Activation protects the configuration from alteration or removal while
866+
* active.
867+
*
868+
* Selection by hash value - generated from the configuration name when it
869+
* was loaded and added to the cs_etm/configurations file system for selection
870+
* by perf.
871+
*
872+
* @cfg_hash: Hash value of the selected configuration name.
873+
*/
874+
int cscfg_activate_config(unsigned long cfg_hash)
875+
{
876+
int err = 0;
877+
878+
mutex_lock(&cscfg_mutex);
879+
err = _cscfg_activate_config(cfg_hash);
795880
mutex_unlock(&cscfg_mutex);
796881

797882
return err;
@@ -807,19 +892,8 @@ EXPORT_SYMBOL_GPL(cscfg_activate_config);
807892
*/
808893
void cscfg_deactivate_config(unsigned long cfg_hash)
809894
{
810-
struct cscfg_config_desc *config_desc;
811-
812895
mutex_lock(&cscfg_mutex);
813-
814-
list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) {
815-
if ((unsigned long)config_desc->event_ea->var == cfg_hash) {
816-
atomic_dec(&config_desc->active_cnt);
817-
atomic_dec(&cscfg_mgr->sys_active_cnt);
818-
cscfg_owner_put(config_desc->load_owner);
819-
dev_dbg(cscfg_device(), "Deactivate config %s.\n", config_desc->name);
820-
break;
821-
}
822-
}
896+
_cscfg_deactivate_config(cfg_hash);
823897
mutex_unlock(&cscfg_mutex);
824898
}
825899
EXPORT_SYMBOL_GPL(cscfg_deactivate_config);

drivers/hwtracing/coresight/coresight-syscfg.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
* @load_order_list: Ordered list of owners for dynamically loaded configurations.
2929
* @sys_active_cnt: Total number of active config descriptor references.
3030
* @cfgfs_subsys: configfs subsystem used to manage configurations.
31+
* @sysfs_active_config:Active config hash used if CoreSight controlled from sysfs.
32+
* @sysfs_active_preset:Active preset index used if CoreSight controlled from sysfs.
3133
*/
3234
struct cscfg_manager {
3335
struct device dev;
@@ -37,6 +39,8 @@ struct cscfg_manager {
3739
struct list_head load_order_list;
3840
atomic_t sys_active_cnt;
3941
struct configfs_subsystem cfgfs_subsys;
42+
u32 sysfs_active_config;
43+
int sysfs_active_preset;
4044
};
4145

4246
/* get reference to dev in cscfg_manager */
@@ -88,7 +92,8 @@ int cscfg_preload(void *owner_handle);
8892
const struct cscfg_feature_desc *cscfg_get_named_feat_desc(const char *name);
8993
int cscfg_update_feat_param_val(struct cscfg_feature_desc *feat_desc,
9094
int param_idx, u64 value);
91-
95+
int cscfg_config_sysfs_activate(struct cscfg_config_desc *cfg_desc, bool activate);
96+
void cscfg_config_sysfs_set_preset(int preset);
9297

9398
/* syscfg manager external API */
9499
int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs,
@@ -104,5 +109,6 @@ void cscfg_csdev_reset_feats(struct coresight_device *csdev);
104109
int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
105110
unsigned long cfg_hash, int preset);
106111
void cscfg_csdev_disable_active_config(struct coresight_device *csdev);
112+
void cscfg_config_sysfs_get_active_cfg(unsigned long *cfg_hash, int *preset);
107113

108114
#endif /* CORESIGHT_SYSCFG_H */

0 commit comments

Comments
 (0)