On Tue, Mar 16, 2021 at 06:03:54PM +0000, Mike Leach wrote:
Loaded coresight configurations are registered in the cs_etm\cs_config sub
This changelog is obsolete - cs_config is no longer under cs_etm.
directory. This extends the etm-perf code to handle these registrations, and the cs_syscfg driver to perform the registration on load.
Signed-off-by: Mike Leach mike.leach@linaro.org
.../hwtracing/coresight/coresight-config.h | 2 + .../hwtracing/coresight/coresight-etm-perf.c | 139 ++++++++++++++---- .../hwtracing/coresight/coresight-etm-perf.h | 8 + .../hwtracing/coresight/coresight-syscfg.c | 12 ++ 4 files changed, 130 insertions(+), 31 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h index f70561c1504b..38fd1c71eb05 100644 --- a/drivers/hwtracing/coresight/coresight-config.h +++ b/drivers/hwtracing/coresight/coresight-config.h @@ -126,6 +126,7 @@ struct cscfg_feature_desc {
- @nr_presets: Number of sets of presets supplied by this configuration.
- @nr_total_params: Sum of all parameters declared by used features
- @presets: Array of preset values.
*/
- @event_ea: Extended attribute for perf event value
struct cscfg_config_desc { @@ -137,6 +138,7 @@ struct cscfg_config_desc { int nr_presets; int nr_total_params; const u64 *presets; /* nr_presets * nr_total_params */
- struct dev_ext_attribute *event_ea;
}; /** diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c index 0e392513b2d6..66bda452a2f4 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.c +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c @@ -18,8 +18,10 @@ #include <linux/types.h> #include <linux/workqueue.h> +#include "coresight-config.h" #include "coresight-etm-perf.h" #include "coresight-priv.h" +#include "coresight-syscfg.h" static struct pmu etm_pmu; static bool etm_perf_up; @@ -38,8 +40,13 @@ PMU_FORMAT_ATTR(contextid1, "config:" __stringify(ETM_OPT_CTXTID)); PMU_FORMAT_ATTR(contextid2, "config:" __stringify(ETM_OPT_CTXTID2)); PMU_FORMAT_ATTR(timestamp, "config:" __stringify(ETM_OPT_TS)); PMU_FORMAT_ATTR(retstack, "config:" __stringify(ETM_OPT_RETSTK)); +/* preset - if sink ID is used as a configuration selector */ +PMU_FORMAT_ATTR(preset, "config:0-3"); /* Sink ID - same for all ETMs */ PMU_FORMAT_ATTR(sinkid, "config2:0-31"); +/* config ID - set if a system configuration is selected */ +PMU_FORMAT_ATTR(configid, "config2:32-63");
/*
- contextid always traces the "PID". The PID is in CONTEXTIDR_EL1
@@ -69,6 +76,8 @@ static struct attribute *etm_config_formats_attr[] = { &format_attr_timestamp.attr, &format_attr_retstack.attr, &format_attr_sinkid.attr,
- &format_attr_preset.attr,
- &format_attr_configid.attr, NULL,
}; @@ -86,9 +95,19 @@ static const struct attribute_group etm_pmu_sinks_group = { .attrs = etm_config_sinks_attr, }; +static struct attribute *etm_config_events_attr[] = {
- NULL,
+};
+static const struct attribute_group etm_pmu_events_group = {
- .name = "events",
- .attrs = etm_config_events_attr,
+};
static const struct attribute_group *etm_pmu_attr_groups[] = { &etm_pmu_format_group, &etm_pmu_sinks_group,
- &etm_pmu_events_group, NULL,
}; @@ -247,7 +266,7 @@ static void *etm_setup_aux(struct perf_event *event, void **pages, INIT_WORK(&event_data->work, free_event_data); /* First get the selected sink from user space. */
- if (event->attr.config2) {
- if (event->attr.config2 & GENMASK_ULL(31, 0)) { id = (u32)event->attr.config2; sink = coresight_get_sink_by_id(id); }
@@ -555,9 +574,9 @@ int etm_perf_symlink(struct coresight_device *csdev, bool link) } EXPORT_SYMBOL_GPL(etm_perf_symlink); -static ssize_t etm_perf_sink_name_show(struct device *dev,
struct device_attribute *dattr,
char *buf)
Because we now have etm_perf_cscfg_event_show(), this could have remained unchanged.
+static ssize_t etm_perf_name_show(struct device *dev,
struct device_attribute *dattr,
char *buf)
{ struct dev_ext_attribute *ea; @@ -565,68 +584,126 @@ static ssize_t etm_perf_sink_name_show(struct device *dev, return scnprintf(buf, PAGE_SIZE, "0x%lx\n", (unsigned long)(ea->var)); } -int etm_perf_add_symlink_sink(struct coresight_device *csdev) +static struct dev_ext_attribute * +etm_perf_add_symlink_group(struct device *dev, const char *name, const char *group_name) {
- int ret;
- struct dev_ext_attribute *ea; unsigned long hash;
- const char *name;
- int ret; struct device *pmu_dev = etm_pmu.dev;
- struct device *dev = &csdev->dev;
- struct dev_ext_attribute *ea;
- if (csdev->type != CORESIGHT_DEV_TYPE_SINK &&
csdev->type != CORESIGHT_DEV_TYPE_LINKSINK)
return -EINVAL;
- if (csdev->ea != NULL)
return -EINVAL;
if (!etm_perf_up)
return -EPROBE_DEFER;
return ERR_PTR(-EPROBE_DEFER);
ea = devm_kzalloc(dev, sizeof(*ea), GFP_KERNEL); if (!ea)
return -ENOMEM;
return ERR_PTR(-ENOMEM);
- name = dev_name(dev);
- /* See function coresight_get_sink_by_id() to know where this is used */
- /*
* If this function is called adding a sink then the hash is used for
* sink selection - see function coresight_get_sink_by_id().
* If adding a configuration then the hash is used for selection in
* cscfg_activate_config()
hash = hashlen_hash(hashlen_string(NULL, name));*/
sysfs_attr_init(&ea->attr.attr); ea->attr.attr.name = devm_kstrdup(dev, name, GFP_KERNEL); if (!ea->attr.attr.name)
return -ENOMEM;
return ERR_PTR(-ENOMEM);
ea->attr.attr.mode = 0444;
- ea->attr.show = etm_perf_sink_name_show;
- ea->attr.show = etm_perf_name_show;
I would have removed the assignment entirely from this function and moved it to etm_perf_add_symlink_cscfg() (like you already did) and etm_perf_add_symlink_link().
ea->var = (unsigned long *)hash; ret = sysfs_add_file_to_group(&pmu_dev->kobj,
&ea->attr.attr, "sinks");
&ea->attr.attr, group_name);
- if (!ret)
csdev->ea = ea;
- return ret ? ERR_PTR(ret) : ea;
+}
- return ret;
+int etm_perf_add_symlink_sink(struct coresight_device *csdev) +{
- const char *name;
- struct device *dev = &csdev->dev;
- int err = 0;
- if (csdev->type != CORESIGHT_DEV_TYPE_SINK &&
csdev->type != CORESIGHT_DEV_TYPE_LINKSINK)
return -EINVAL;
- if (csdev->ea != NULL)
return -EINVAL;
- name = dev_name(dev);
- csdev->ea = etm_perf_add_symlink_group(dev, name, "sinks");
- if (IS_ERR(csdev->ea)) {
err = PTR_ERR(csdev->ea);
csdev->ea = NULL;
- }
- return err;
} -void etm_perf_del_symlink_sink(struct coresight_device *csdev) +void etm_perf_del_symlink_group(struct dev_ext_attribute *ea, const char *group_name) { struct device *pmu_dev = etm_pmu.dev;
- struct dev_ext_attribute *ea = csdev->ea;
- sysfs_remove_file_from_group(&pmu_dev->kobj,
&ea->attr.attr, group_name);
+}
+void etm_perf_del_symlink_sink(struct coresight_device *csdev) +{ if (csdev->type != CORESIGHT_DEV_TYPE_SINK && csdev->type != CORESIGHT_DEV_TYPE_LINKSINK) return;
- if (!ea)
- if (!csdev->ea) return;
- sysfs_remove_file_from_group(&pmu_dev->kobj,
&ea->attr.attr, "sinks");
- etm_perf_del_symlink_group(csdev->ea, "sinks"); csdev->ea = NULL;
} +static ssize_t etm_perf_cscfg_event_show(struct device *dev,
struct device_attribute *dattr,
char *buf)
+{
- struct dev_ext_attribute *ea;
- ea = container_of(dattr, struct dev_ext_attribute, attr);
- return scnprintf(buf, PAGE_SIZE, "configid=0x%lx\n", (unsigned long)(ea->var));
+}
+int etm_perf_add_symlink_cscfg(struct device *dev, struct cscfg_config_desc *config_desc) +{
- int err = 0;
- if (config_desc->event_ea != NULL)
return 0;
- config_desc->event_ea = etm_perf_add_symlink_group(dev, config_desc->name, "events");
- /* override the show function to the custom cscfg event */
- if (!IS_ERR(config_desc->event_ea))
config_desc->event_ea->attr.show = etm_perf_cscfg_event_show;
- else {
err = PTR_ERR(config_desc->event_ea);
config_desc->event_ea = NULL;
- }
- return err;
+}
+void etm_perf_del_symlink_cscfg(struct cscfg_config_desc *config_desc) +{
- if (!config_desc->event_ea)
return;
- etm_perf_del_symlink_group(config_desc->event_ea, "events");
- config_desc->event_ea = NULL;
+}
int __init etm_perf_init(void) { int ret; diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.h b/drivers/hwtracing/coresight/coresight-etm-perf.h index 29d90dfeba31..ba617fe2217e 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.h +++ b/drivers/hwtracing/coresight/coresight-etm-perf.h @@ -11,6 +11,7 @@ #include "coresight-priv.h" struct coresight_device; +struct cscfg_config_desc; /*
- In both ETMv3 and v4 the maximum number of address comparator implentable
@@ -69,6 +70,9 @@ static inline void *etm_perf_sink_config(struct perf_output_handle *handle) return data->snk_config; return NULL; } +int etm_perf_add_symlink_cscfg(struct device *dev,
struct cscfg_config_desc *config_desc);
+void etm_perf_del_symlink_cscfg(struct cscfg_config_desc *config_desc); #else static inline int etm_perf_symlink(struct coresight_device *csdev, bool link) { return -EINVAL; } @@ -79,6 +83,10 @@ static inline void *etm_perf_sink_config(struct perf_output_handle *handle) { return NULL; } +int etm_perf_add_symlink_cscfg(struct device *dev,
struct cscfg_config_desc *config_desc)
+{ return -EINVAL; } +void etm_perf_del_symlink_cscfg(struct cscfg_config_desc *config_desc) {} #endif /* CONFIG_CORESIGHT */ diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c index 11d1422f0ed3..03014a2142c1 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.c +++ b/drivers/hwtracing/coresight/coresight-syscfg.c @@ -7,6 +7,7 @@ #include <linux/platform_device.h> #include "coresight-config.h" +#include "coresight-etm-perf.h" #include "coresight-syscfg.h" /* @@ -86,6 +87,7 @@ static int cscfg_add_csdev_cfg(struct coresight_device *csdev, config_csdev->feats_csdev[config_csdev->nr_feat++] = feat_csdev; } }
Spurious newline.
If you end up respinning:
Reviewed-by: Mathieu Poirier mathieu.poirier@linaro.org
Otherwise I have fixed it on my side.
Thanks, Mathieu
/* if matched features, add config to device.*/ if (config_csdev) { mutex_lock(&cscfg_csdev_mutex); @@ -276,6 +278,11 @@ static int cscfg_load_config(struct cscfg_config_desc *config_desc) if (err) return err;
- /* add config to perf fs to allow selection */
- err = etm_perf_add_symlink_cscfg(cscfg_device(), config_desc);
- if (err)
return err;
- list_add(&config_desc->item, &cscfg_mgr->config_desc_list); return 0;
} @@ -490,7 +497,12 @@ int cscfg_create_device(void) void cscfg_clear_device(void) {
- struct cscfg_config_desc *cfg_desc;
- mutex_lock(&cscfg_mutex);
- list_for_each_entry(cfg_desc, &cscfg_mgr->config_desc_list, item) {
etm_perf_del_symlink_cscfg(cfg_desc);
- } device_unregister(cscfg_device()); mutex_unlock(&cscfg_mutex);
}
2.17.1