From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-14.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id ABEDEC433B4 for ; Mon, 17 May 2021 17:30:20 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1AA5960FDB for ; Mon, 17 May 2021 17:30:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1AA5960FDB Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References:Message-ID: Subject:Cc:To:From:Date:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=3AkyvNV0A1n5V036Ekzbr874v80rjlNWX2Ynv5l3/eI=; b=iaIoT6rYDJqnGv1PLOUyikDDp UZJfx8car/5/HbNjRkA43RYRbZLCzubwODey83IPOe8kHEbZ7CPrjIvaf+IE/xAg1UXL+e83O+w/i hoHXXoxeotWCQHtZ017f7OWX4Qdz2rpoFpJ3wMfkHByWhNuDzqHdrfIi/du8FdKszUR4zMVZvpcLZ HRLDg/7ssZIVsNKzTp4/gahdPPNPzMZGT6pKvbXou9Yfa6oWEeSbNJHLE83IjTi8eWFrXKXXI42sY Oo0g7FIoUSx+uBEVi4JPNVCl8ZJYVrDzcP+HmDIwWdOdLPVSuGU9zyzhckNbm2QsbCE4CShNS7c91 SZEpCt1KQ==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lih2I-00Fedj-Tu; Mon, 17 May 2021 17:28:11 +0000 Received: from bombadil.infradead.org ([2607:7c80:54:e::133]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lih28-00Fect-3X for linux-arm-kernel@desiato.infradead.org; Mon, 17 May 2021 17:28:01 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=In-Reply-To:Content-Type:MIME-Version :References:Message-ID:Subject:Cc:To:From:Date:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=ztR8Mm5biEqw+JR9p6PFjv2c60roDRi09Cz0xYEJLlQ=; b=D325+ny4xJLca1S5mfMTvx/mqr eZTj5lzQNVYULTrNuSSfSM4+PrS1aQaZ36lQtfN0XTd+RSK06DEdw3sMv/bPzo+tYY8x0+9XYWaeV KUDig6NjzRMg/+GA3Jrn08iVUA3slwsl0la4K3NWKOedbdyeNInrLsMqYj5fwnGchyNeUbLIYRU5B pHLnzJr5FjdmWK5WfKSFW23N/G+3qazajT1rXE2gJooE0hzeyLlMOdQnt7Q9Bu3i8SCpCsHxVXnKq 7SKR6sQbLVp/peip0BTb7hX7Rfpq/fzEcnSgvOBALPZ2lzRrK1+c/A22V8i5Li4gOTG9iKfDcNeLo nCmgjJcg==; Received: from mail-pj1-x1035.google.com ([2607:f8b0:4864:20::1035]) by bombadil.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lih24-00E19E-50 for linux-arm-kernel@lists.infradead.org; Mon, 17 May 2021 17:27:58 +0000 Received: by mail-pj1-x1035.google.com with SMTP id q6so4071097pjj.2 for ; Mon, 17 May 2021 10:27:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=ztR8Mm5biEqw+JR9p6PFjv2c60roDRi09Cz0xYEJLlQ=; b=xvXFooca0p/gNrME9uBrii4VHmbabRJJzKZbpiuEgLLBLNa2hCFxcLYa1xIXGbGRJn ipnwwz3bXZu6Fp0BRABcz118oklEmfbx+OT+hfcLmDi4fOk27ZjSDBkI2Vqimd9arlaI etzSu1yau/CUNzf0ltQuMaCP7GtHBCbHRbhe3F8l8ivny95Eubc2r+UDQlXq55cd8XVc 1vmKQU6XHYhopCZPoldIoz7yOYhhD7LQVLXMJQ3Gp2n6rPXF5BgzYC39vAgA0/S1Zo1D 1lA+lEjxGX9yDAjRo623JhbH2qFwJwOXEcABeeLwY7Dr5rCPnaLgPM5Gj6DRJ44Mf0iA YouA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=ztR8Mm5biEqw+JR9p6PFjv2c60roDRi09Cz0xYEJLlQ=; b=rldTj5AW1c0+ertf5XLMqE2/Z14ZlxpyOWjcYhLce3bkVuctNXX9eQVHceqVMPqQOl 1CRq237lI3eI/s2YZBL5hL7NTFX3SYIDsXIH/a4gVQgA2ETkrZcFGfk+B6uXgcnddK8p 8KGAInm6ieJ0w2Tg+11cxALydOZXOYV2mou1ZR4J20QQYsPU9jqlq4X6BcDzVf1VEUyd LP+pc8B2xUryGWp/C3nLH+jlUSXy6YHZBkPFBaS3W0cq5BTgDfNiU4y4A6EPgLBDrqPm TCQNFXK6GXDHLRiVll/h5nfE1aSiw9VNXA2hkZYyOCNA+/qOlTmnFVSW5d9dT9HfkMbA p2YQ== X-Gm-Message-State: AOAM531qNVfqp3VJnZshKcwlAWZYt10MHxy72LjUVFtQNSQNFSNyZ9eL WPFpTbCrnPnLgd01pMLrYih8xA== X-Google-Smtp-Source: ABdhPJyb40Ql330P4MkySB7m6q3E/2cj04T6ubegjH2KBQgAoTBsvy82V3qkv0ES7uQmZb0s49YEhQ== X-Received: by 2002:a17:90b:3615:: with SMTP id ml21mr561191pjb.194.1621272474611; Mon, 17 May 2021 10:27:54 -0700 (PDT) Received: from xps15 (S0106889e681aac74.cg.shawcable.net. [68.147.0.187]) by smtp.gmail.com with ESMTPSA id y190sm5865384pfb.69.2021.05.17.10.27.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 May 2021 10:27:54 -0700 (PDT) Date: Mon, 17 May 2021 11:27:52 -0600 From: Mathieu Poirier To: Mike Leach Cc: coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, suzuki.poulose@arm.com, leo.yan@linaro.org Subject: Re: [RFC PATCH 1/8] coresight: syscfg: Update API to allow dynamic load and unload Message-ID: <20210517172752.GB498571@xps15> References: <20210512211752.4103-1-mike.leach@linaro.org> <20210512211752.4103-2-mike.leach@linaro.org> <20210517171515.GA498571@xps15> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20210517171515.GA498571@xps15> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210517_102756_241381_77313D52 X-CRM114-Status: GOOD ( 43.79 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org On Mon, May 17, 2021 at 11:15:15AM -0600, Mathieu Poirier wrote: > On Wed, May 12, 2021 at 10:17:45PM +0100, Mike Leach wrote: > > Update the load API to permit the runtime loading and unloading of new > > configurations and features. > > > > On load, configurations and features are tagged with a "load owner" that > > is used to determine sets that were loaded together in a given API call. > > > > To unload the API uses the load owner to unload all elements previously > > loaded by that owner. > > > > The API also uses records the order in which different owners loaded > > their elements into the system. Later loading configurations can use > > previously loaded features, creating load dependencies. Therefore unload > > is enforced strictly in the reverse order to load. > > There seems to be something wrong with the first sentence - I think the word > "uses" is extra. I found another one like that below. > > Otherwise this patch works. Despite the relative simplicity of what it does it > took me two tries to go through it, probably because of how spread out the > changes are. I don't think you could have done things differently though. > > Reviewed-by: Mathieu Poirier > > > > > A load owner will be an additional loadable module, or a configuration > > created or loaded via configfs. > > > > Signed-off-by: Mike Leach > > --- > > .../coresight/coresight-cfg-preload.c | 9 +- > > .../hwtracing/coresight/coresight-config.h | 9 +- > > .../coresight/coresight-syscfg-configfs.c | 20 +++ > > .../coresight/coresight-syscfg-configfs.h | 2 + > > .../hwtracing/coresight/coresight-syscfg.c | 154 +++++++++++++++++- > > .../hwtracing/coresight/coresight-syscfg.h | 30 +++- > > 6 files changed, 216 insertions(+), 8 deletions(-) > > > > diff --git a/drivers/hwtracing/coresight/coresight-cfg-preload.c b/drivers/hwtracing/coresight/coresight-cfg-preload.c > > index 751af3710d56..e237a4edfa09 100644 > > --- a/drivers/hwtracing/coresight/coresight-cfg-preload.c > > +++ b/drivers/hwtracing/coresight/coresight-cfg-preload.c > > @@ -24,8 +24,13 @@ static struct cscfg_config_desc *preload_cfgs[] = { > > NULL > > }; > > > > +static struct cscfg_load_owner_info preload_owner = { > > + .type = CSCFG_OWNER_PRELOAD, > > +}; > > + > > /* preload called on initialisation */ > > -int cscfg_preload(void) > > +int cscfg_preload(void *owner_handle) > > { > > - return cscfg_load_config_sets(preload_cfgs, preload_feats); > > + preload_owner.owner_handle = owner_handle; > > + return cscfg_load_config_sets(preload_cfgs, preload_feats, &preload_owner); > > } > > diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h > > index 25eb6c632692..9bd44b940add 100644 > > --- a/drivers/hwtracing/coresight/coresight-config.h > > +++ b/drivers/hwtracing/coresight/coresight-config.h > > @@ -97,6 +97,8 @@ struct cscfg_regval_desc { > > * @params_desc: array of parameters used. > > * @nr_regs: number of registers used. > > * @regs_desc: array of registers used. > > + * @load_owner: handle to load owner for dynamic load and unload of features. > > + * @fs_group: reference to configfs group for dynamic unload. > > */ > > struct cscfg_feature_desc { > > const char *name; > > @@ -107,6 +109,8 @@ struct cscfg_feature_desc { > > struct cscfg_parameter_desc *params_desc; > > int nr_regs; > > struct cscfg_regval_desc *regs_desc; > > + void *load_owner; > > + struct config_group *fs_group; > > }; > > > > /** > > @@ -128,7 +132,8 @@ struct cscfg_feature_desc { > > * @presets: Array of preset values. > > * @event_ea: Extended attribute for perf event value > > * @active_cnt: ref count for activate on this configuration. > > - * > > + * @load_owner: handle to load owner for dynamic load and unload of configs. > > + * @fs_group: reference to configfs group for dynamic unload. > > */ > > struct cscfg_config_desc { > > const char *name; > > @@ -141,6 +146,8 @@ struct cscfg_config_desc { > > const u64 *presets; /* nr_presets * nr_total_params */ > > struct dev_ext_attribute *event_ea; > > atomic_t active_cnt; > > + void *load_owner; > > + struct config_group *fs_group; > > }; > > > > /** > > diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c > > index c547816b9000..345a62f1b728 100644 > > --- a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c > > +++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c > > @@ -334,9 +334,19 @@ int cscfg_configfs_add_config(struct cscfg_config_desc *config_desc) > > if (IS_ERR(new_group)) > > return PTR_ERR(new_group); > > err = configfs_register_group(&cscfg_configs_grp, new_group); > > + if (!err) > > + config_desc->fs_group = new_group; > > return err; > > } > > > > +void cscfg_configfs_del_config(struct cscfg_config_desc *config_desc) > > +{ > > + if (config_desc->fs_group) { > > + configfs_unregister_group(config_desc->fs_group); > > + config_desc->fs_group = NULL; > > + } > > +} > > + > > static struct config_item_type cscfg_features_type = { > > .ct_owner = THIS_MODULE, > > }; > > @@ -358,9 +368,19 @@ int cscfg_configfs_add_feature(struct cscfg_feature_desc *feat_desc) > > if (IS_ERR(new_group)) > > return PTR_ERR(new_group); > > err = configfs_register_group(&cscfg_features_grp, new_group); > > + if (!err) > > + feat_desc->fs_group = new_group; > > return err; > > } > > > > +void cscfg_configfs_del_feature(struct cscfg_feature_desc *feat_desc) > > +{ > > + if (feat_desc->fs_group) { > > + configfs_unregister_group(feat_desc->fs_group); > > + feat_desc->fs_group = NULL; > > + } > > +} > > + > > int cscfg_configfs_init(struct cscfg_manager *cscfg_mgr) > > { > > struct configfs_subsystem *subsys; > > diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.h b/drivers/hwtracing/coresight/coresight-syscfg-configfs.h > > index 7d6ffe35ca4c..ea1e54d29f7f 100644 > > --- a/drivers/hwtracing/coresight/coresight-syscfg-configfs.h > > +++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.h > > @@ -41,5 +41,7 @@ int cscfg_configfs_init(struct cscfg_manager *cscfg_mgr); > > void cscfg_configfs_release(struct cscfg_manager *cscfg_mgr); > > int cscfg_configfs_add_config(struct cscfg_config_desc *config_desc); > > int cscfg_configfs_add_feature(struct cscfg_feature_desc *feat_desc); > > +void cscfg_configfs_del_config(struct cscfg_config_desc *config_desc); > > +void cscfg_configfs_del_feature(struct cscfg_feature_desc *feat_desc); > > > > #endif /* CORESIGHT_SYSCFG_CONFIGFS_H */ > > diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c > > index 180202402eb5..ab5ec43a9dad 100644 > > --- a/drivers/hwtracing/coresight/coresight-syscfg.c > > +++ b/drivers/hwtracing/coresight/coresight-syscfg.c > > @@ -250,6 +250,13 @@ static int cscfg_check_feat_for_cfg(struct cscfg_config_desc *config_desc) > > static int cscfg_load_feat(struct cscfg_feature_desc *feat_desc) > > { > > int err; > > + struct cscfg_feature_desc *feat_desc_exist; > > + > > + /* new feature must have unique name */ > > + list_for_each_entry(feat_desc_exist, &cscfg_mgr->feat_desc_list, item) { > > + if (!strcmp(feat_desc_exist->name, feat_desc->name)) > > + return -EEXIST; > > + } > > > > /* add feature to any matching registered devices */ > > err = cscfg_add_feat_to_csdevs(feat_desc); > > @@ -267,6 +274,13 @@ static int cscfg_load_feat(struct cscfg_feature_desc *feat_desc) > > static int cscfg_load_config(struct cscfg_config_desc *config_desc) > > { > > int err; > > + struct cscfg_config_desc *config_desc_exist; > > + > > + /* new configuration must have a unique name */ > > + list_for_each_entry(config_desc_exist, &cscfg_mgr->config_desc_list, item) { > > + if (!strcmp(config_desc_exist->name, config_desc->name)) > > + return -EEXIST; > > + } > > > > /* validate features are present */ > > err = cscfg_check_feat_for_cfg(config_desc); > > @@ -354,6 +368,72 @@ int cscfg_update_feat_param_val(struct cscfg_feature_desc *feat_desc, > > return err; > > } > > > > +static void cscfg_remove_owned_csdev_configs(struct coresight_device *csdev, void *load_owner) > > +{ > > + struct cscfg_config_csdev *config_csdev, *tmp; > > + > > + if (list_empty(&csdev->config_csdev_list)) > > + return; > > + > > + list_for_each_entry_safe(config_csdev, tmp, &csdev->config_csdev_list, node) { > > + if (config_csdev->config_desc->load_owner == load_owner) > > + list_del(&config_csdev->node); > > + } > > +} > > + > > +static void cscfg_remove_owned_csdev_features(struct coresight_device *csdev, void *load_owner) > > +{ > > + struct cscfg_feature_csdev *feat_csdev, *tmp; > > + > > + if (list_empty(&csdev->feature_csdev_list)) > > + return; > > + > > + list_for_each_entry_safe(feat_csdev, tmp, &csdev->feature_csdev_list, node) { > > + if (feat_csdev->feat_desc->load_owner == load_owner) > > + list_del(&feat_csdev->node); > > + } > > +} > > + > > +/* > > + * removal is relatively easy - just remove from all lists, anything that > > + * matches the owner. Memory for the descriptors will be managed by the owner, > > + * memory for the csdev items is devm_ allocated with the individual csdev > > + * devices. > > + */ > > +static void cscfg_unload_owned_cfgs_feats(void *load_owner) > > +{ > > + struct cscfg_config_desc *config_desc, *cfg_tmp; > > + struct cscfg_feature_desc *feat_desc, *feat_tmp; > > + struct cscfg_registered_csdev *csdev_item; > > + > > + /* remove from each csdev instance feature and config lists */ > > + list_for_each_entry(csdev_item, &cscfg_mgr->csdev_desc_list, item) { > > + /* > > + * for each csdev, check the loaded lists and remove if > > + * referenced descriptor is owned > > + */ > > + cscfg_remove_owned_csdev_configs(csdev_item->csdev, load_owner); > > + cscfg_remove_owned_csdev_features(csdev_item->csdev, load_owner); > > + } > > + > > + /* remove from the config descriptor lists */ > > + list_for_each_entry_safe(config_desc, cfg_tmp, &cscfg_mgr->config_desc_list, item) { > > + if (config_desc->load_owner == load_owner) { > > + cscfg_configfs_del_config(config_desc); > > + etm_perf_del_symlink_cscfg(config_desc); > > + list_del(&config_desc->item); > > + } > > + } > > + > > + /* remove from the feature descriptor lists */ > > + list_for_each_entry_safe(feat_desc, feat_tmp, &cscfg_mgr->feat_desc_list, item) { > > + if (feat_desc->load_owner == load_owner) { > > + cscfg_configfs_del_feature(feat_desc); > > + list_del(&feat_desc->item); > > + } > > + } > > +} > > + > > /** > > * cscfg_load_config_sets - API function to load feature and config sets. > > * > > @@ -361,13 +441,22 @@ int cscfg_update_feat_param_val(struct cscfg_feature_desc *feat_desc, > > * descriptors and load into the system. > > * Features are loaded first to ensure configuration dependencies can be met. > > * > > + * To facilitate dynamic loading and unloading, features and configurations > > + * have a "load_owner", to allow later unload by the same owner. An owner may > > + * be a loadable module or configuration dynamically created via configfs. > > + * As later loaded configurations can use earlier loaded features, creating load > > + * dependencies, a load order list is maintained. Unload is strictly in the > > + * reverse order to load. > > + * > > * @config_descs: 0 terminated array of configuration descriptors. > > * @feat_descs: 0 terminated array of feature descriptors. > > + * @owner_info: Information on the owner of this set. > > */ > > int cscfg_load_config_sets(struct cscfg_config_desc **config_descs, > > - struct cscfg_feature_desc **feat_descs) > > + struct cscfg_feature_desc **feat_descs, > > + struct cscfg_load_owner_info *owner_info) > > { > > - int err, i = 0; > > + int err = 0, i = 0; > > > > mutex_lock(&cscfg_mutex); > > > > @@ -380,8 +469,10 @@ int cscfg_load_config_sets(struct cscfg_config_desc **config_descs, > > if (err) { > > pr_err("coresight-syscfg: Failed to load feature %s\n", > > feat_descs[i]->name); > > + cscfg_unload_owned_cfgs_feats(owner_info); > > goto exit_unlock; > > } > > + feat_descs[i]->load_owner = owner_info; > > i++; > > } > > } > > @@ -396,18 +487,74 @@ int cscfg_load_config_sets(struct cscfg_config_desc **config_descs, > > if (err) { > > pr_err("coresight-syscfg: Failed to load configuration %s\n", > > config_descs[i]->name); > > + cscfg_unload_owned_cfgs_feats(owner_info); > > goto exit_unlock; > > } > > + config_descs[i]->load_owner = owner_info; > > i++; > > } > > } > > > > + /* add the load owner to the load order list */ > > + list_add_tail(&owner_info->item, &cscfg_mgr->load_order_list); > > + > > exit_unlock: > > mutex_unlock(&cscfg_mutex); > > return err; > > } > > EXPORT_SYMBOL_GPL(cscfg_load_config_sets); > > > > +/** > > + * cscfg_unload_config_sets - unload a set of configurations be owner. Shouldn't this be "by owner."? > > + * > > + * Dynamic unload of configuration and feature sets is done on the basis of > > + * the load owner of that set. Later loaded configurations can depend on > > + * features loaded earlier. > > + * > > + * Therefore, unload is only possible if:- > > + * 1) no configurations are active. > > + * 2) the set being unloaded was the last to be loaded to maintain dependencies. > > + * > > + * @owner_info: Information on owner for set being unloaded. > > + */ > > +int cscfg_unload_config_sets(struct cscfg_load_owner_info *owner_info) > > +{ > > + int err = 0; > > + struct cscfg_load_owner_info *load_list_item = NULL; > > + > > + mutex_lock(&cscfg_mutex); > > + > > + /* cannot unload if anything is active */ > > + if (atomic_read(&cscfg_mgr->sys_active_cnt)) { > > + err = -EBUSY; > > + goto exit_unlock; > > + } > > + > > + /* cannot unload if not last loaded in load order */ > > + if (!list_empty(&cscfg_mgr->load_order_list)) { > > + load_list_item = list_last_entry(&cscfg_mgr->load_order_list, > > + struct cscfg_load_owner_info, item); > > + if (load_list_item != owner_info) > > + load_list_item = NULL; > > + } > > + > > + if (!load_list_item) { > > + err = -EINVAL; > > + goto exit_unlock; > > + } > > + > > + /* unload all belonging to load_owner */ > > + cscfg_unload_owned_cfgs_feats(owner_info); > > + > > + /* remove from load order list */ > > + list_del(&load_list_item->item); > > + > > +exit_unlock: > > + mutex_unlock(&cscfg_mutex); > > + return err; > > +} > > +EXPORT_SYMBOL_GPL(cscfg_unload_config_sets); > > + > > /* Handle coresight device registration and add configs and features to devices */ > > > > /* iterate through config lists and load matching configs to device */ > > @@ -783,10 +930,11 @@ int __init cscfg_init(void) > > INIT_LIST_HEAD(&cscfg_mgr->csdev_desc_list); > > INIT_LIST_HEAD(&cscfg_mgr->feat_desc_list); > > INIT_LIST_HEAD(&cscfg_mgr->config_desc_list); > > + INIT_LIST_HEAD(&cscfg_mgr->load_order_list); > > atomic_set(&cscfg_mgr->sys_active_cnt, 0); > > > > /* preload built-in configurations */ > > - err = cscfg_preload(); > > + err = cscfg_preload(THIS_MODULE); > > if (err) > > goto exit_err; > > > > diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h > > index 8d018efd6ead..e2b2bdab31aa 100644 > > --- a/drivers/hwtracing/coresight/coresight-syscfg.h > > +++ b/drivers/hwtracing/coresight/coresight-syscfg.h > > @@ -25,6 +25,7 @@ > > * @csdev_desc_list: List of coresight devices registered with the configuration manager. > > * @feat_desc_list: List of feature descriptors to load into registered devices. > > * @config_desc_list: List of system configuration descriptors to load into registered devices. > > + * @load_order_list: Ordered list of owners for dynamically loaded configurations. > > * @sys_active_cnt: Total number of active config descriptor references. > > * @cfgfs_subsys: configfs subsystem used to manage configurations. > > */ > > @@ -33,6 +34,7 @@ struct cscfg_manager { > > struct list_head csdev_desc_list; > > struct list_head feat_desc_list; > > struct list_head config_desc_list; > > + struct list_head load_order_list; > > atomic_t sys_active_cnt; > > struct configfs_subsystem cfgfs_subsys; > > }; > > @@ -56,10 +58,32 @@ struct cscfg_registered_csdev { > > struct list_head item; > > }; > > > > +/* owner types for loading and unloading of config and feature sets */ > > +enum cscfg_load_owner_type { > > + CSCFG_OWNER_PRELOAD, > > +}; > > + > > +/** > > + * Load item - item to add to the load order list allowing dynamic load and > > + * unload of configurations and features. Caller loading a config > > + * set provides a context handle for unload. API ensures that > > + * items unloaded strictly in reverse order from load to ensure > > + * dependencies are respected. > > + * > > + * @item: list entry for load order list. > > + * @type: type of owner - allows interpretation of owner_handle. > > + * @owner_handle: load context - handle for owner of loaded configs. > > + */ > > +struct cscfg_load_owner_info { > > + struct list_head item; > > + int type; > > + void *owner_handle; > > +}; > > + > > /* internal core operations for cscfg */ > > int __init cscfg_init(void); > > void cscfg_exit(void); > > -int cscfg_preload(void); > > +int cscfg_preload(void *owner_handle); > > const struct cscfg_feature_desc *cscfg_get_named_feat_desc(const char *name); > > int cscfg_update_feat_param_val(struct cscfg_feature_desc *feat_desc, > > int param_idx, u64 value); > > @@ -67,7 +91,9 @@ int cscfg_update_feat_param_val(struct cscfg_feature_desc *feat_desc, > > > > /* syscfg manager external API */ > > int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs, > > - struct cscfg_feature_desc **feat_descs); > > + struct cscfg_feature_desc **feat_descs, > > + struct cscfg_load_owner_info *owner_info); > > +int cscfg_unload_config_sets(struct cscfg_load_owner_info *owner_info); > > int cscfg_register_csdev(struct coresight_device *csdev, u32 match_flags, > > struct cscfg_csdev_feat_ops *ops); > > void cscfg_unregister_csdev(struct coresight_device *csdev); > > -- > > 2.17.1 > > _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel