From: Mathieu Poirier <mathieu.poirier@linaro.org>
To: Mike Leach <mike.leach@linaro.org>
Cc: yabinc@google.com, coresight@lists.linaro.org,
linux-arm-kernel@lists.infradead.org, suzuki.poulose@arm.com
Subject: Re: [RFC PATCH v3 4/9] coresight: etm-perf: update to handle configuration selection
Date: Fri, 20 Nov 2020 11:52:20 -0700 [thread overview]
Message-ID: <20201120185220.GB104873@xps15> (raw)
In-Reply-To: <20201030175655.30126-5-mike.leach@linaro.org>
On Fri, Oct 30, 2020 at 05:56:50PM +0000, Mike Leach wrote:
> Loaded coresight configurations are registered in the cs_etm\cs_config sub
> 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 | 5 +-
> .../hwtracing/coresight/coresight-etm-perf.c | 164 +++++++++++++++---
> .../hwtracing/coresight/coresight-etm-perf.h | 8 +
> .../hwtracing/coresight/coresight-syscfg.c | 23 ++-
> 4 files changed, 172 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
> index a3d374ebb70f..372f29a59688 100644
> --- a/drivers/hwtracing/coresight/coresight-config.h
> +++ b/drivers/hwtracing/coresight/coresight-config.h
> @@ -154,7 +154,8 @@ struct cscfg_config_feat_ref {
> * @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.
> - *
> + * @id_ea: Extended attribute for perf configid value
> + * @event_ea: Extended attribute for perf event value
> */
> struct cscfg_config_desc {
> const char *name;
> @@ -165,6 +166,8 @@ struct cscfg_config_desc {
> int nr_presets;
> int nr_total_params;
> const u64 *presets; /* nr_presets * nr_total_params */
> + struct dev_ext_attribute *id_ea;
> + 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 a608081bd446..8a87984195ed 100644
> --- a/drivers/hwtracing/coresight/coresight-etm-perf.c
> +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
> @@ -20,6 +20,8 @@
>
> #include "coresight-etm-perf.h"
> #include "coresight-priv.h"
> +#include "coresight-config.h"
Alphabetical order
> +#include "coresight-syscfg.h"
>
> static struct pmu etm_pmu;
> static bool etm_perf_up;
> @@ -34,6 +36,11 @@ PMU_FORMAT_ATTR(timestamp, "config:" __stringify(ETM_OPT_TS));
> PMU_FORMAT_ATTR(retstack, "config:" __stringify(ETM_OPT_RETSTK));
> /* Sink ID - same for all ETMs */
> PMU_FORMAT_ATTR(sinkid, "config2:0-31");
> +/* preset - if sink ID is used as a configuration selector */
> +PMU_FORMAT_ATTR(preset, "config:0-3");
Please move this before sinkid to keep the "config" together. I also looked at
bit 0-3 of the ETMCR on ETMv3.x and I don't think we'll be using those bits any
time soon.
> +/* config ID - set if a system configuration is selected */
> +PMU_FORMAT_ATTR(configid, "config2:32-63");
> +
>
> static struct attribute *etm_config_formats_attr[] = {
> &format_attr_cycacc.attr,
> @@ -41,6 +48,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,
> };
>
> @@ -58,9 +67,29 @@ static const struct attribute_group etm_pmu_sinks_group = {
> .attrs = etm_config_sinks_attr,
> };
>
> +static struct attribute *etm_config_cscfg_attr[] = {
> + NULL,
> +};
> +
> +static const struct attribute_group etm_pmu_cscfg_group = {
> + .name = "configurations",
> + .attrs = etm_config_cscfg_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_cscfg_group,
> + &etm_pmu_events_group,
> NULL,
> };
>
> @@ -219,7 +248,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);
> }
> @@ -537,21 +566,17 @@ 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)
> +int etm_perf_add_symlink_group(struct device *dev,
> + struct dev_ext_attribute **ext_attr,
> + 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;
> + *ext_attr = NULL;
>
> if (!etm_perf_up)
> return -EPROBE_DEFER;
> @@ -560,7 +585,6 @@ int etm_perf_add_symlink_sink(struct coresight_device *csdev)
> if (!ea)
> return -ENOMEM;
>
> - name = dev_name(dev);
> /* See function coresight_get_sink_by_id() to know where this is used */
> hash = hashlen_hash(hashlen_string(NULL, name));
>
> @@ -574,31 +598,127 @@ int etm_perf_add_symlink_sink(struct coresight_device *csdev)
> 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;
> -
> + *ext_attr = ea;
> return ret;
> }
>
> -void etm_perf_del_symlink_sink(struct coresight_device *csdev)
> +int etm_perf_add_symlink_sink(struct coresight_device *csdev)
> +{
> + const char *name;
> + struct device *dev = &csdev->dev;
> +
> + 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);
> + return etm_perf_add_symlink_group(dev, &csdev->ea, name, "sinks");
> +}
> +
> +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;
> }
>
> +/* string to contain the attribute value */
> +#define CSCFG_EVENT_STR_SIZE 32
> +
> +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, "%s\n", (const char *)(ea->var));
> +}
> +
> +static int etm_perf_add_cscfg_event(struct device *dev, struct cscfg_config_desc *cs_cfg)
> +{
> + struct dev_ext_attribute *ea;
> + unsigned long hash;
> + int ret;
> + struct device *pmu_dev = etm_pmu.dev;
> +
> + ea = devm_kzalloc(dev, sizeof(*ea), GFP_KERNEL);
> + if (!ea)
> + return -ENOMEM;
> +
> + hash = (unsigned long)cs_cfg->id_ea->var;
> +
> + sysfs_attr_init(&ea->attr.attr);
> + ea->attr.attr.name = devm_kstrdup(dev, cs_cfg->name, GFP_KERNEL);
> + if (!ea->attr.attr.name)
> + return -ENOMEM;
> +
> + /*
> + * attribute value is "configid=<hash>".
> + * this will be what perf evaluates when the config name is used
> + * on the command line.
> + */
> + ea->var = devm_kzalloc(dev, CSCFG_EVENT_STR_SIZE, GFP_KERNEL);
> + if (!ea->var)
> + return -ENOMEM;
> +
> + scnprintf(ea->var, CSCFG_EVENT_STR_SIZE, "configid=0x%lx", hash);
> + ea->attr.attr.mode = 0444;
> + ea->attr.show = etm_perf_cscfg_event_show;
> +
> + ret = sysfs_add_file_to_group(&pmu_dev->kobj,
> + &ea->attr.attr, "events");
> + if (!ret)
> + cs_cfg->event_ea = ea;
> + return ret;
> +}
> +
> +int etm_perf_add_symlink_cscfg(struct device *dev, struct cscfg_config_desc *cs_cfg)
> +{
> + int err;
> +
> + if (cs_cfg->id_ea != NULL)
> + return 0;
> +
> + err = etm_perf_add_symlink_group(dev, &cs_cfg->id_ea,
> + cs_cfg->name, "configurations");
> +
> + if (!err)
> + err = etm_perf_add_cscfg_event(dev, cs_cfg);
> +
> + return err;
> +}
> +
> +void etm_perf_del_symlink_cscfg(struct cscfg_config_desc *cs_cfg)
> +{
> + if (!cs_cfg->id_ea)
> + return;
> +
> + etm_perf_del_symlink_group(cs_cfg->id_ea, "configurations");
> + etm_perf_del_symlink_group(cs_cfg->event_ea, "events");
> + cs_cfg->id_ea = NULL;
> + cs_cfg->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..3646a3837a0b 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 *cscfg_desc);
> +void etm_perf_del_symlink_cscfg(struct cscfg_config_desc *cscfg_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 *cscfg_desc)
> +{ return -EINVAL; }
> +void etm_perf_del_symlink_cscfg(struct cscfg_config_desc *cscfg_desc) {}
>
> #endif /* CONFIG_CORESIGHT */
>
> diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
> index 98ee78e3412a..8d52580daf04 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"
>
> /*
> @@ -85,7 +86,7 @@ static int cscfg_add_csdev_cfg(struct coresight_device *csdev,
> struct cscfg_config_csdev *dev_cfg = NULL;
> struct cscfg_config_feat_ref *feat_ref;
> struct cscfg_feature_csdev *feat;
> - int checked;
> + int checked, err;
>
> /* look at each required feature and see if it matches any feature on the device */
> for (checked = 0; checked < cfg_desc->nr_refs; checked++) {
> @@ -97,16 +98,22 @@ static int cscfg_add_csdev_cfg(struct coresight_device *csdev,
> return -EINVAL;
> if (!dev_cfg) {
> dev_cfg = cscfg_alloc_csdev_cfg(csdev, cfg_desc->nr_refs);
> - if (!dev_cfg)
> - return -ENOMEM;
As far as I can tell cscfg_alloc_csdev() can still return NULL and as such the
check shouldn't be removed.
> dev_cfg->desc = cfg_desc;
> + dev_cfg->id_hash = (unsigned long)cfg_desc->id_ea->var;
Please add a comment to say that cfg_desc->id_ea->var is initalised in
etm_perf_add_symlink_cscfg().
> }
> dev_cfg->feats[dev_cfg->nr_feat++] = feat;
> }
> }
> +
> /* if matched features, add config to device.*/
> - if (dev_cfg)
> + if (dev_cfg) {
> + /* add config name to perf event directory if this is valid source */
> + if (match_info->match_flags & CS_CFG_MATCH_CLASS_SRC_ALL)
To me all configurations should be added and as such there shouldn't be a need
for a check here. I'm also puzzled about the comment, especially the "valid
source" part. To me a source is an ETM or some device that produce traces but
complex configuration also applies to CTIs.
> + err = etm_perf_add_symlink_cscfg(&csdev->dev, cfg_desc);
Why is this added here when the same configuration is also added in
cscfg_load_config()?
> + if (err)
> + return err;
> list_add(&dev_cfg->node, &csdev->syscfg_list);
> + }
>
> return 0;
> }
> @@ -282,8 +289,9 @@ static int cscfg_load_config(struct cscfg_config_desc *cfg_desc)
> return err;
>
> list_add(&cfg_desc->item, &cscfg_data.config_list);
> + err = etm_perf_add_symlink_cscfg(to_device_cscfg(), cfg_desc);
I think this is the right place to do this.
I'm done with this patch - I'll continue on Monday.
Thanks,
Mathieu
>
> - return 0;
> + return err;
> }
>
> /*
> @@ -532,7 +540,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_data.config_list, item) {
> + etm_perf_del_symlink_cscfg(cfg_desc);
> + }
> device_unregister(to_device_cscfg());
> mutex_unlock(&cscfg_mutex);
> }
> --
> 2.17.1
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2020-11-20 18:53 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-30 17:56 [RFC PATCH v3 0/9] CoreSight complex config support; ETM strobing Mike Leach
2020-10-30 17:56 ` [RFC PATCH v3 1/9] coresight: syscfg: Initial coresight system configuration Mike Leach
2020-11-12 22:09 ` Mathieu Poirier
2020-11-13 17:27 ` Mathieu Poirier
2020-11-16 18:32 ` Mathieu Poirier
2020-11-26 18:35 ` Mathieu Poirier
2020-12-24 19:21 ` Mike Leach
2020-10-30 17:56 ` [RFC PATCH v3 2/9] coresight: syscfg: Add registration and feature loading for cs devices Mike Leach
2020-11-16 18:47 ` Mathieu Poirier
2020-12-24 19:21 ` Mike Leach
2020-10-30 17:56 ` [RFC PATCH v3 3/9] coresight: config: Add configuration and feature generic functions Mike Leach
2020-11-17 19:00 ` Mathieu Poirier
2020-11-19 22:29 ` Mathieu Poirier
2020-12-24 19:21 ` Mike Leach
2020-10-30 17:56 ` [RFC PATCH v3 4/9] coresight: etm-perf: update to handle configuration selection Mike Leach
2020-11-20 18:52 ` Mathieu Poirier [this message]
2020-12-24 19:21 ` Mike Leach
2020-10-30 17:56 ` [RFC PATCH v3 5/9] coresight: etm4x: Add complex configuration handlers to etmv4 Mike Leach
2020-11-23 21:58 ` Mathieu Poirier
2020-12-24 19:21 ` Mike Leach
2020-10-30 17:56 ` [RFC PATCH v3 6/9] coresight: config: Add preloaded configurations Mike Leach
2020-11-24 17:51 ` Mathieu Poirier
2020-12-24 19:21 ` Mike Leach
2020-10-30 17:56 ` [RFC PATCH v3 7/9] coresight: syscfg: Add initial configfs support Mike Leach
2020-11-24 20:57 ` Mathieu Poirier
2020-11-25 21:52 ` Mathieu Poirier
2020-11-26 16:51 ` Mathieu Poirier
2020-10-30 17:56 ` [RFC PATCH v3 8/9] coresight: syscfg: Allow update of feature params from configfs Mike Leach
2020-11-26 17:17 ` Mathieu Poirier
2020-12-24 19:21 ` Mike Leach
2020-10-30 17:56 ` [RFC PATCH v3 9/9] coresight: docs: Add documentation for CoreSight config Mike Leach
2020-11-26 17:52 ` Mathieu Poirier
2020-12-24 19:21 ` Mike Leach
2020-11-26 18:52 ` [RFC PATCH v3 0/9] CoreSight complex config support; ETM strobing Mathieu Poirier
2020-12-24 19:20 ` Mike Leach
2021-01-06 21:15 ` Mathieu Poirier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201120185220.GB104873@xps15 \
--to=mathieu.poirier@linaro.org \
--cc=coresight@lists.linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=mike.leach@linaro.org \
--cc=suzuki.poulose@arm.com \
--cc=yabinc@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.