From: Mathieu Poirier <mathieu.poirier@linaro.org>
To: Mike Leach <mike.leach@linaro.org>
Cc: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org,
suzuki.poulose@arm.com, leo.yan@linaro.org
Subject: Re: [PATCH v2 2/6] coresight: configfs: Add in binary attributes to load files
Date: Fri, 28 Jan 2022 11:17:23 -0700 [thread overview]
Message-ID: <20220128181723.GB2240873@p14s> (raw)
In-Reply-To: <20211130220100.25888-3-mike.leach@linaro.org>
On Tue, Nov 30, 2021 at 10:00:56PM +0000, Mike Leach wrote:
> Add in functionality and binary attribute to load configurations
> as binary data.
>
> Reads the incoming attribute, which must be formatted correctly
> as defined in the file reader code - and will create a configuration
> and/or features and load them into the system.
>
> These will then appear in configfs ready for use.
>
> Unload functionality is also provided.
>
> Signed-off-by: Mike Leach <mike.leach@linaro.org>
> ---
> .../coresight/coresight-config-file.h | 7 +
> .../coresight/coresight-syscfg-configfs.c | 148 +++++++++++++++++-
> .../coresight/coresight-syscfg-configfs.h | 8 +
> .../hwtracing/coresight/coresight-syscfg.c | 36 +++++
> .../hwtracing/coresight/coresight-syscfg.h | 1 +
> 5 files changed, 193 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-config-file.h b/drivers/hwtracing/coresight/coresight-config-file.h
> index 6c8c5af0a614..03899f7d94c9 100644
> --- a/drivers/hwtracing/coresight/coresight-config-file.h
> +++ b/drivers/hwtracing/coresight/coresight-config-file.h
> @@ -115,4 +115,11 @@ struct cscfg_file_elem_str {
> char *str;
> };
>
> +/* kernel configfs needs to read the incoming file buffers to load. */
> +int cscfg_file_read_buffer(const u8 *buffer, const int buflen,
> + struct cscfg_fs_load_descs *desc_arrays);
> +/* to unload we just need the first name - config or first feature */
> +int cscfg_file_read_buffer_first_name(const u8 *buffer, const int buflen,
> + const char **name);
> +
> #endif /* _CORESIGHT_CORESIGHT_CONFIG_FILE_H */
> diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c
> index 433ede94dd63..50abdb5aa6b6 100644
> --- a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c
> +++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c
> @@ -7,6 +7,7 @@
> #include <linux/configfs.h>
>
> #include "coresight-config.h"
> +#include "coresight-config-file.h"
> #include "coresight-syscfg-configfs.h"
>
> /* create a default ci_type. */
> @@ -380,14 +381,147 @@ static struct config_group *cscfg_create_feature_group(struct cscfg_feature_desc
> return &feat_view->group;
> }
>
> +/* Attributes in configfs that allow load and unload of configuration binary files */
> +
> +/* load "buffer" as a configuration binary file */
> +static ssize_t cscfg_cfg_load_write(struct config_item *item, const void *buffer, size_t size)
> +{
> + struct cscfg_fs_configs_grp *configs_grp;
> + struct cscfg_fs_load_descs *load_descs = 0;
> + struct cscfg_load_owner_info *owner_info = 0;
> + int err = 0;
> + const char *name;
> +
> + configs_grp = container_of(to_config_group(item), struct cscfg_fs_configs_grp, group);
> + if (size > CSCFG_FILE_MAXSIZE) {
> + scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN,
> + "Load error: Input file too large.\n");
> + return -EINVAL;
> + }
> +
> + load_descs = kzalloc(sizeof(struct cscfg_fs_load_descs), GFP_KERNEL);
> + owner_info = kzalloc(sizeof(struct cscfg_load_owner_info), GFP_KERNEL);
> + if (!load_descs || !owner_info) {
> + err = -ENOMEM;
> + goto exit_memfree;
> + }
> +
> + load_descs->owner_info = owner_info;
> + owner_info->owner_handle = load_descs;
> + owner_info->type = CSCFG_OWNER_CONFIGFS;
> +
> + err = cscfg_file_read_buffer(buffer, size, load_descs);
> + if (err) {
> + scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN,
> + "Load error: Failed to read input file.\n");
> + goto exit_memfree;
> + }
> +
> + err = cscfg_load_config_sets(load_descs->config_descs, load_descs->feat_descs, owner_info);
> + if (err) {
> + scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN,
> + "Load error: Failed to load configuaration file.\n");
> + goto exit_memfree;
> + }
> +
> + /* name of config if there is one, otherwise first feature */
> + if (load_descs->config_descs[0])
> + name = load_descs->config_descs[0]->name;
> + else
> + name = load_descs->feat_descs[0]->name;
> + scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN,
> + "OK: configuration file loaded (%s).\n", name);
> +
> + return size;
> +
> +exit_memfree:
> + kfree(load_descs);
> + kfree(owner_info);
> + return err;
> +}
> +CONFIGFS_BIN_ATTR_WO(cscfg_cfg_, load, NULL, CSCFG_FILE_MAXSIZE);
> +
> +/* read "buffer" and unload configuration */
> +static ssize_t cscfg_cfg_unload_write(struct config_item *item, const void *buffer, size_t size)
> +{
> + struct cscfg_fs_configs_grp *configs_grp;
> + struct cscfg_fs_load_descs *load_descs;
> + const char *name;
> + int err;
> +
> + configs_grp = container_of(to_config_group(item), struct cscfg_fs_configs_grp, group);
> + if (size > CSCFG_FILE_MAXSIZE) {
> + scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN,
> + "Unload error: Input file too large\n");
> + return -EINVAL;
> + }
> +
> + err = cscfg_file_read_buffer_first_name(buffer, size, &name);
> + if (err) {
> + scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN,
> + "Unload error: Failed to read input file\n");
> + return err;
> + }
> +
> + load_descs = cscfg_find_fs_owned_cfg_by_name(name);
> + if (!load_descs) {
> + scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN,
> + "Unload error: Failed to find configuration %s from input file\n",
> + name);
> + return err;
> + }
> + err = cscfg_unload_config_sets(load_descs->owner_info);
> + if (err) {
> + scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN,
> + "Unload error: Cannot unload configuration %s\n",
> + name);
> + return err;
> + }
> +
> + scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN,
> + "OK: configuration file unloaded (%s).\n", name);
> +
> + kfree((struct cscfg_load_owner_info *)load_descs->owner_info);
> + kfree(load_descs);
> + return size;
> +}
> +CONFIGFS_BIN_ATTR_WO(cscfg_cfg_, unload, NULL, CSCFG_FILE_MAXSIZE);
> +
> +/* show the status of the last load / unload operation */
> +static ssize_t cscfg_cfg_last_load_status_show(struct config_item *item, char *page)
> +{
> + struct cscfg_fs_configs_grp *configs_grp;
> +
> + configs_grp = container_of(to_config_group(item), struct cscfg_fs_configs_grp, group);
> +
> + return scnprintf(page, PAGE_SIZE, "%s\n", configs_grp->status);
I am still very ambivalent about this status thing... Especially since it only
reports on the last item that was loaded/unloaded.
> +}
> +CONFIGFS_ATTR_RO(cscfg_cfg_, last_load_status);
> +
> +static struct configfs_attribute *cscfg_config_configs_attrs[] = {
> + &cscfg_cfg_attr_last_load_status,
> + NULL,
> +};
> +
> +static struct configfs_bin_attribute *cscfg_config_configfs_bin_attrs[] = {
> + &cscfg_cfg_attr_load,
> + &cscfg_cfg_attr_unload,
> + NULL,
> +};
> +
> static struct config_item_type cscfg_configs_type = {
> .ct_owner = THIS_MODULE,
> + .ct_bin_attrs = cscfg_config_configfs_bin_attrs,
> + .ct_attrs = cscfg_config_configs_attrs,
> };
>
> -static struct config_group cscfg_configs_grp = {
> - .cg_item = {
> - .ci_namebuf = "configurations",
> - .ci_type = &cscfg_configs_type,
> +/* group for configurations dir, with load, unload and status attribs */
> +static struct cscfg_fs_configs_grp cscfg_configs_grp = {
> + .group = {
> + .cg_item = {
> + .ci_namebuf = "configurations",
> + .ci_type = &cscfg_configs_type,
> + },
> },
> };
>
> @@ -400,7 +534,7 @@ int cscfg_configfs_add_config(struct cscfg_config_desc *config_desc)
> new_group = cscfg_create_config_group(config_desc);
> if (IS_ERR(new_group))
> return PTR_ERR(new_group);
> - err = configfs_register_group(&cscfg_configs_grp, new_group);
> + err = configfs_register_group(&cscfg_configs_grp.group, new_group);
> if (!err)
> config_desc->fs_group = new_group;
> return err;
> @@ -468,8 +602,8 @@ int cscfg_configfs_init(struct cscfg_manager *cscfg_mgr)
> mutex_init(&subsys->su_mutex);
>
> /* Add default groups to subsystem */
> - config_group_init(&cscfg_configs_grp);
> - configfs_add_default_group(&cscfg_configs_grp, &subsys->su_group);
> + config_group_init(&cscfg_configs_grp.group);
> + configfs_add_default_group(&cscfg_configs_grp.group, &subsys->su_group);
>
> config_group_init(&cscfg_features_grp);
> configfs_add_default_group(&cscfg_features_grp, &subsys->su_group);
> diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.h b/drivers/hwtracing/coresight/coresight-syscfg-configfs.h
> index 373d84d43268..8d6900e8c1ea 100644
> --- a/drivers/hwtracing/coresight/coresight-syscfg-configfs.h
> +++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.h
> @@ -11,6 +11,14 @@
>
> #define CSCFG_FS_SUBSYS_NAME "cs-syscfg"
>
> +#define CSCFG_FS_STATUS_STRLEN 256
> +
> +/* container for configs group */
> +struct cscfg_fs_configs_grp {
> + struct config_group group;
> + char status[CSCFG_FS_STATUS_STRLEN];
> +};
> +
> /* container for configuration view */
> struct cscfg_fs_config {
> struct cscfg_config_desc *config_desc;
> diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
> index 098fc34c4829..b5804cc2af9c 100644
> --- a/drivers/hwtracing/coresight/coresight-syscfg.c
> +++ b/drivers/hwtracing/coresight/coresight-syscfg.c
> @@ -587,6 +587,42 @@ int cscfg_unload_config_sets(struct cscfg_load_owner_info *owner_info)
> }
> EXPORT_SYMBOL_GPL(cscfg_unload_config_sets);
>
> +/* find a configuration owned by configfs by name of config / first feature */
> +struct cscfg_fs_load_descs *cscfg_find_fs_owned_cfg_by_name(const char *name)
> +{
> + struct cscfg_load_owner_info *owner_info;
> + struct cscfg_fs_load_descs *fs_load_cfg = NULL;
> + struct cscfg_config_desc *config_desc;
> + struct cscfg_feature_desc *feat_desc;
> +
> + mutex_lock(&cscfg_mutex);
> +
> + /* search the load_owner list for CONFIGFS loaded types */
> + list_for_each_entry(owner_info, &cscfg_mgr->load_order_list, item) {
> + /* if this is a config fs owned item, then try to match */
> + if (owner_info->type == CSCFG_OWNER_CONFIGFS) {
> + fs_load_cfg = owner_info->owner_handle;
> + /* first try to match the name against the config if it exists */
> + if (fs_load_cfg->config_descs[0]) {
> + config_desc = fs_load_cfg->config_descs[0];
> + if (!strcmp(config_desc->name, name))
> + goto exit_unlock;
> + /* no config - match against first feature name */
> + } else {
> + feat_desc = fs_load_cfg->feat_descs[0];
> + if (!strcmp(feat_desc->name, name))
> + goto exit_unlock;
> + }
> + /* no match - move on */
> + fs_load_cfg = NULL;
> + }
> + }
> +
> +exit_unlock:
> + mutex_unlock(&cscfg_mutex);
> + return fs_load_cfg;
> +}
> +
> /* Handle coresight device registration and add configs and features to devices */
>
> /* iterate through config lists and load matching configs to device */
> diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h
> index 6a6e33585be9..6bc29abe0650 100644
> --- a/drivers/hwtracing/coresight/coresight-syscfg.h
> +++ b/drivers/hwtracing/coresight/coresight-syscfg.h
> @@ -95,6 +95,7 @@ int cscfg_update_feat_param_val(struct cscfg_feature_desc *feat_desc,
> int param_idx, u64 value);
> int cscfg_config_sysfs_activate(struct cscfg_config_desc *cfg_desc, bool activate);
> void cscfg_config_sysfs_set_preset(int preset);
> +struct cscfg_fs_load_descs *cscfg_find_fs_owned_cfg_by_name(const char *name);
>
> /* syscfg manager external API */
> int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs,
> --
> 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:[~2022-01-28 18:18 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-30 22:00 [PATCH v2 0/6] coresight: syscfg: Extend configfs for config load Mike Leach
2021-11-30 22:00 ` [PATCH v2 1/6] coresight: configfs: Add in functionality for load via configfs Mike Leach
2022-01-28 18:08 ` Mathieu Poirier
2022-02-02 20:40 ` Mike Leach
2021-11-30 22:00 ` [PATCH v2 2/6] coresight: configfs: Add in binary attributes to load files Mike Leach
2022-01-28 18:17 ` Mathieu Poirier [this message]
2022-02-02 20:33 ` Mike Leach
2022-02-02 22:33 ` Mathieu Poirier
2021-11-30 22:00 ` [PATCH v2 3/6] coresight: configfs: Modify config files to allow userspace use Mike Leach
2022-01-28 18:33 ` Mathieu Poirier
2022-02-02 20:48 ` Mike Leach
2021-11-30 22:00 ` [PATCH v2 4/6] coresight: samples: Add an example config writer for configfs load Mike Leach
2022-01-13 17:56 ` Mathieu Poirier
2022-01-18 16:38 ` Mike Leach
2022-01-28 18:43 ` Mathieu Poirier
2022-02-02 20:54 ` Mike Leach
2021-11-30 22:00 ` [PATCH v2 5/6] coresight: samples: Add coresight file reader sample program Mike Leach
2021-11-30 22:01 ` [PATCH v2 6/6] Documentation: coresight: docs for config load via configfs Mike Leach
2022-01-12 17:22 ` Mathieu Poirier
2022-01-12 18:43 ` Mathieu Poirier
2022-01-13 18:15 ` Mathieu Poirier
2022-01-18 16:41 ` Mike Leach
2022-01-10 18:58 ` [PATCH v2 0/6] coresight: syscfg: Extend configfs for config load 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=20220128181723.GB2240873@p14s \
--to=mathieu.poirier@linaro.org \
--cc=coresight@lists.linaro.org \
--cc=leo.yan@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=mike.leach@linaro.org \
--cc=suzuki.poulose@arm.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.