From patchwork Wed May 12 21:17:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12254687 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=-17.4 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,USER_AGENT_GIT 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 E2428C433ED for ; Wed, 12 May 2021 21:21:35 +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 372256108D for ; Wed, 12 May 2021 21:21:35 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 372256108D 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:MIME-Version:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:Cc:To :From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=1D5+OahJ5i6vBUfkvMGlK3ub2g7ZyBD820eGXsQ2XYA=; b=o3Z1XHVJ+C54DOnIb1ANh1kRbk XBIfAWngEr/pyNliubadEeZKG/HN+0wlyfr13ot10bmHCkAx9tbp/6c3ThpYOP0xCS9mPmRM+26CS Q9y72JWVHZALUWBzHsxfdHOXNDEtjzycxsxSvekVlYWfaEFCimLU/GotlpBWcxy3mRehjWHI9i0am k1JveKyZmzH++MhZFEpLOYSHLZiPmp3eAr0h6JMtEyjVShBd45sNHoQHUxhW1Yizp/6HWdr3PPyes 7pbz3fqGGb3AOMCPFxJLjYDmKu3uEA7b571Fzw7bqbcsDRcZk/U0gOoIgdy4z8bBgUOTV+2HX+XaF VBXhmQqQ==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lgwFv-0040dy-1e; Wed, 12 May 2021 21:18:59 +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 1lgwF7-0040Sk-BP for linux-arm-kernel@desiato.infradead.org; Wed, 12 May 2021 21:18:10 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description; bh=XQMDhnRKltpmtB3/vY/dd1prIeHKPagMFdaUtlHSwx0=; b=mh4RQ9UVE5wXw3pgqA9OdGNpZM 12ffZ2AxhE4GQQcAfRCXn1BIQYzGzQcj/uknD+7HPo4fFvCNktn+ZaHgdtxwHhSgPa6pxfW6ngzH2 +zBCoc8ptTPRrBTU4Qdnu1MkvhlSpLjcCrixfwwacaPsPf+aehB/8+UyDmbcWBvdQrLFY0SlJAnEu GFeECBjoerJP9rAqxLoEDPQ4ustCbDJN12FCvjSJJWr09ZGHCd2NWqCCsRJ3vD8M6+eCszK2hCdlc /1KSIIuQ3MpGJEsL5px5MPl9gjEt/0FLKJaYtvlsH+CEsHWvde0Aips68HLCkUruxfj+8RC4CoFJe yBo8uYJg==; Received: from mail-wr1-x42b.google.com ([2a00:1450:4864:20::42b]) by bombadil.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lgwF2-00Apen-AH for linux-arm-kernel@lists.infradead.org; Wed, 12 May 2021 21:18:08 +0000 Received: by mail-wr1-x42b.google.com with SMTP id t18so25030678wry.1 for ; Wed, 12 May 2021 14:18:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=XQMDhnRKltpmtB3/vY/dd1prIeHKPagMFdaUtlHSwx0=; b=r7L+BlbTw7Q7XtowJ+T/jX0MFoL/HlpwU5k7riU44STIJ6gjpu1IfyuFTbeC+txflv bLiE631WNILzYZe7Nv5ocHKKnHThVBL6ExUBEBSyL6a77Fggv0LtjIAhXGoAG49KANUz q/F7J+Q904blebCTa74sZNXhGLv7kxDQDDMSjAqUL8gPyqEWotzc5egWbYAG43WLvlSk 4IDkjH3mWqdGbMpXzeKPNi2LPx4AyEkse80LrwIalw2GV+bwLSfbUJid5MQHfoZpDcqv TevZiycnJut5lgIWj93537sYyHbVWoGu/r5uT4WhB4ccKwhMDW8k3XSFFZ7YKviSVp9d B9Og== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=XQMDhnRKltpmtB3/vY/dd1prIeHKPagMFdaUtlHSwx0=; b=lyloDlOs7ggdSVcOEagfPelw8ssPNORedLrNAZfmmTRiSb71mcJdbsin5Tr1pgEV15 CepP9gtekbHavIPxGh+nawv36tukqlSqDInBgRFrUbfIERHrASQXs0JbbhLIb27NffOp kWqbaL14MsIZ8kJMnY/Qjk4HCdHoJ3gVJM4yafZgdRtUn2ADAARIlvRfiKBy7WoDcWKh XPepmz0/212vMK+LvyORj51IkDOfv4cqrSMj7iAsGWylt4Lcfpo/PtQ8+9XO1zZdceFt z9xjI804G0mrfHQ/O3tmrSux2Bh5JRmHQhYpNc9Bkejk1+wTcl1fKT54wcOVAYzdxSu6 7CQA== X-Gm-Message-State: AOAM533gkvtBmz/CVx+1vmZyT5qqsXlDA7/fYfMPSSwNJxtMBcc3HfTx H6DtYKbpel58dGozrJJNuuYueA== X-Google-Smtp-Source: ABdhPJxsATxs7G6ri9gTWyGKAh/Li+BjCNOEDRdYdQJ7e3LJAAp0VdeF0JwoYtOCJ+/5rWMAC6NLmA== X-Received: by 2002:adf:eac9:: with SMTP id o9mr10808659wrn.120.1620854282066; Wed, 12 May 2021 14:18:02 -0700 (PDT) Received: from linaro.org ([2a00:23c5:6809:2201:3d54:dc15:c65b:180c]) by smtp.gmail.com with ESMTPSA id e10sm908745wrw.20.2021.05.12.14.18.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 May 2021 14:18:01 -0700 (PDT) From: Mike Leach To: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org, mathieu.poirier@linaro.org, suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [RFC PATCH 1/8] coresight: syscfg: Update API to allow dynamic load and unload Date: Wed, 12 May 2021 22:17:45 +0100 Message-Id: <20210512211752.4103-2-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210512211752.4103-1-mike.leach@linaro.org> References: <20210512211752.4103-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210512_141804_395622_B236CC90 X-CRM114-Status: GOOD ( 30.59 ) 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org 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. A load owner will be an additional loadable module, or a configuration created or loaded via configfs. Signed-off-by: Mike Leach Reviewed-by: Mathieu Poirier --- .../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. + * + * 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); From patchwork Wed May 12 21:17:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12254679 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=-17.4 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,USER_AGENT_GIT 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 340D5C433ED for ; Wed, 12 May 2021 21:21:08 +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 70D2F611BD for ; Wed, 12 May 2021 21:21:07 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 70D2F611BD 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:MIME-Version:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:Cc:To :From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=E8HGGO80cde86QDWj+VGpfrsFY1xF5AOM875bxHmRZ0=; b=SypEupoAhp1iE0H0HPH//iM1ee U/zlSUoqSDHZXq+7L/Y8UoURD5L/Ha2HrKK8XiAvq0V5PuoVtmy9oJOGlB6InfpDd/YyYF2u4I9q9 JsFgRcJ3WYkbW1u7UroWOBoxXhSSfnKgDXmJIyRJXNypjMltaCf/Fc8rmc2mUjWy+XxcHXqipAe3/ NUrl73YthKWjjcOUNh/ZieG6K2/uJEoSHLUqvC1pEy663Y8AXX5BtP9f+7LjiiFJESYXd2wA6LKhn wxbg8b12vFXsx/RqMagUwAyN+lGOQI7l5snfMaYWB5jvwFdJH/bocerb2EQn0dUg3l1uFnQFWbsZA RCAoToMg==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lgwFC-0040Ud-SJ; Wed, 12 May 2021 21:18:15 +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 1lgwF5-0040Sf-0J for linux-arm-kernel@desiato.infradead.org; Wed, 12 May 2021 21:18:10 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description; bh=mmU+ziRlyL6f5t/Combz3dolaekQmEheTrbdG+QX+BI=; b=x6EAwKJy+yduMncBIr9wSvrAZu Ypiz7eedeoD+N89/PoffujEHY47dSY/yIo3Ni6Jj5CKqBoupq1Ij+q+rssNUCagX90m7r0dDVMqhU NXWUD+n0xaFaHHDxaeQeNKLn75dGw7PTS6sOAEo2jhxXPF0Yfc7rxDht6ibDGSZxYKNooYhwv0F77 Z6O8qOpqj+ONyppIUR9hagg6z86TNDKR4cr6Ez0FPLWdA6ry/PR1bUrMj1I5fMGgxNS8w8fIeKyKE usi3osz1+WIXq9ChhrBYLISU1GK5ek8W1qtNVzpvSH/+qDRisK3qfbTzYBJGKbXlcyDsllVc4Oe/M lAA4UPRQ==; Received: from mail-wr1-x42a.google.com ([2a00:1450:4864:20::42a]) by bombadil.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lgwF2-00Apeo-6L for linux-arm-kernel@lists.infradead.org; Wed, 12 May 2021 21:18:05 +0000 Received: by mail-wr1-x42a.google.com with SMTP id z17so5942727wrq.7 for ; Wed, 12 May 2021 14:18:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=mmU+ziRlyL6f5t/Combz3dolaekQmEheTrbdG+QX+BI=; b=IHv/d7B2M5tyTKAkuWcLwy+a8w1Z1NlC+gfITmMqpQBtDEIhUWeyUdVRseU0Dga/or 18yoMJLffMaz+b/hqI9fQnEiTq/T2w/JAT7wr3b36e72hqw3aJpTOtP3fmY1x2i3NPsv tjG+p3y319E3tN6EPG1vX1K+ZfCU4zgtHzC49gkapTJ3zR8idGtnFaj63LRPPPcNiays g5WANFrnZDrHYy1/KyIabiIMZzRekQhUJQKcQGdocG+u23G5MTil15vPOVW+1REIW3PH 91xeI7P5PGsmO0LfsH8CrgZnRYtBr0YQ9iaAxGcGC+fI4+ZMvCXmlbvrih82fjx2FuIm 6ivQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=mmU+ziRlyL6f5t/Combz3dolaekQmEheTrbdG+QX+BI=; b=giSYswDjUeFJJuUDmkS5MU7Zq2O36QdUkRqVZnpWlBsXNGY1LXQEvhKR7Bei6FPCiE m3uKNhvV/n9GlqhM+qKgC5EOoJ9q24LxCaxKDARII6lH0ajCJnix6Mzk3QyHpjIoZ3NC feAAhuF35FPg1UJ3J4xRIdm6rymCbeW9aMb0z9HTCA61PmCxRmXYM9Sd0few7sfEFVME nb86ppWC7h3px0MknTnM5KBG6xVGkvXtHdmBz5mKgC1jj7JwkgpJOnVSQhtiffqJ0h+O wz9eEquiJEeVvsZIUyeCcVLP5W3eqjdPu9cSeKXD732hdq7zdCBl3FSsX6IZ147I9Bol qX0Q== X-Gm-Message-State: AOAM533e6lfxvA+5mjyEZoMoerkcUzRQHwfBuj7DeeMks9g9MypolNXa /WbdSPWzZVn7lEz2tXi5ut6l6h/4I5q6UQ== X-Google-Smtp-Source: ABdhPJy6D9MK6w87UotmfAroa2gh2QyUSKwgBdrB6rIo9D+h1b7XdoNTHIbvNkTxo//jZ+oqV6RJAw== X-Received: by 2002:a5d:4a48:: with SMTP id v8mr48656390wrs.204.1620854282710; Wed, 12 May 2021 14:18:02 -0700 (PDT) Received: from linaro.org ([2a00:23c5:6809:2201:3d54:dc15:c65b:180c]) by smtp.gmail.com with ESMTPSA id e10sm908745wrw.20.2021.05.12.14.18.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 May 2021 14:18:02 -0700 (PDT) From: Mike Leach To: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org, mathieu.poirier@linaro.org, suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [RFC PATCH 2/8] coresight: syscfg: Update load API for config loadable modules Date: Wed, 12 May 2021 22:17:46 +0100 Message-Id: <20210512211752.4103-3-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210512211752.4103-1-mike.leach@linaro.org> References: <20210512211752.4103-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210512_141804_275146_B47116B0 X-CRM114-Status: GOOD ( 19.93 ) 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org CoreSight configurations and features can be added as kernel loadable modules. This patch updates the load owner API to ensure that the module cannot be unloaded either:- 1) if the config it supplies is in use 2) if the module is not the last in the load order list. Signed-off-by: Mike Leach Reviewed-by: Mathieu Poirier --- .../hwtracing/coresight/coresight-syscfg.c | 39 ++++++++++++++++++- .../hwtracing/coresight/coresight-syscfg.h | 1 + 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c index ab5ec43a9dad..26c1a244c2b1 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.c +++ b/drivers/hwtracing/coresight/coresight-syscfg.c @@ -368,6 +368,26 @@ int cscfg_update_feat_param_val(struct cscfg_feature_desc *feat_desc, return err; } +/* + * Conditionally up reference count on owner to prevent unload. + * + * module loaded configs need to be locked in to prevent premature unload. + */ +static int cscfg_owner_get(struct cscfg_load_owner_info *owner_info) +{ + if ((owner_info->type == CSCFG_OWNER_MODULE) && + (!try_module_get(owner_info->owner_handle))) + return -EINVAL; + return 0; +} + +/* conditionally lower ref count on an owner */ +static void cscfg_owner_put(struct cscfg_load_owner_info *owner_info) +{ + if (owner_info->type == CSCFG_OWNER_MODULE) + module_put(owner_info->owner_handle); +} + static void cscfg_remove_owned_csdev_configs(struct coresight_device *csdev, void *load_owner) { struct cscfg_config_csdev *config_csdev, *tmp; @@ -497,6 +517,14 @@ int cscfg_load_config_sets(struct cscfg_config_desc **config_descs, /* add the load owner to the load order list */ list_add_tail(&owner_info->item, &cscfg_mgr->load_order_list); + if (!list_is_singular(&cscfg_mgr->load_order_list)) { + /* lock previous item in load order list */ + err = cscfg_owner_get(list_prev_entry(owner_info, item)); + if (err) { + cscfg_unload_owned_cfgs_feats(owner_info); + list_del(&owner_info->item); + } + } exit_unlock: mutex_unlock(&cscfg_mutex); @@ -547,7 +575,11 @@ int cscfg_unload_config_sets(struct cscfg_load_owner_info *owner_info) cscfg_unload_owned_cfgs_feats(owner_info); /* remove from load order list */ - list_del(&load_list_item->item); + if (!list_is_singular(&cscfg_mgr->load_order_list)) { + /* unlock previous item in load order list */ + cscfg_owner_put(list_prev_entry(owner_info, item)); + } + list_del(&owner_info->item); exit_unlock: mutex_unlock(&cscfg_mutex); @@ -737,6 +769,10 @@ int cscfg_activate_config(unsigned long cfg_hash) list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) { if ((unsigned long)config_desc->event_ea->var == cfg_hash) { + /* must ensure that config cannot be unloaded in use */ + err = cscfg_owner_get(config_desc->load_owner); + if (err) + break; /* * increment the global active count - control changes to * active configurations @@ -777,6 +813,7 @@ void cscfg_deactivate_config(unsigned long cfg_hash) if ((unsigned long)config_desc->event_ea->var == cfg_hash) { atomic_dec(&config_desc->active_cnt); atomic_dec(&cscfg_mgr->sys_active_cnt); + cscfg_owner_put(config_desc->load_owner); dev_dbg(cscfg_device(), "Deactivate config %s.\n", config_desc->name); break; } diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h index e2b2bdab31aa..1da37874f70f 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.h +++ b/drivers/hwtracing/coresight/coresight-syscfg.h @@ -61,6 +61,7 @@ struct cscfg_registered_csdev { /* owner types for loading and unloading of config and feature sets */ enum cscfg_load_owner_type { CSCFG_OWNER_PRELOAD, + CSCFG_OWNER_MODULE, }; /** From patchwork Wed May 12 21:17:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12254681 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=-17.4 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,USER_AGENT_GIT 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 CB928C433B4 for ; Wed, 12 May 2021 21:21:15 +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 318F0611C9 for ; Wed, 12 May 2021 21:21:15 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 318F0611C9 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:MIME-Version:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:Cc:To :From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=W+oDA5UU998viv9e/P5rG3lfxtac4ZUGnTn9hvktUJo=; b=MW0jr3/FyvHvoLFse11HitYULT 58PaR9ynci5NQRfEnauDMK76mFtnI1JQ8ITR/lNrCNP18XV9UM6YIaP9aGLPaeIZ6ttJCCBxXTysY FwtzTLQa7lt95bc3hREpEm0zOc5jyygOxtZKUBItzrLEZIyWjtipjA9RM4t2emYEmyO09QN8rxztw 3Ej3hgBnfDmMXwqVRm3yDLmJmwNc/aMieV9gn6naxsRKIN8fmRP7ljiBfBpsM2Y1WmtwOawqb83TT PRpPsBWgoA0CKe0vtyedNAY5Dw85R9hB+Pxy9Z0Hf4YNo7JVHBpKg/Q/rdnmENnFUjB5Ghnh7ujWp 8QfoL31g==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lgwFY-0040XO-GW; Wed, 12 May 2021 21:18:36 +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 1lgwF6-0040Sh-Eh for linux-arm-kernel@desiato.infradead.org; Wed, 12 May 2021 21:18:10 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description; bh=WlYi+SHiGyL5WUEUZac2YTO9w6rW9DmdcDFUKtKvVSE=; b=Go4ehf99GinXchgopSHcKNIyGd FPinNFHdL2JfqLG66mHYA+xj3iFMcIhOrTeEHR80qJMMAxXuBNzRK4Cle+ZZX0cCM3Y9uEU/XJRZt lZcglduclXVjoDLFI6xmUsVYeOeI7AHXozVguKpOWTjA3J0MQzdAvkUsq9tsU/9mRLs3vmL1TNNd1 lalXtCXZ+KLALJkdxWgCMEEtrjizU52nIubJKifZDVqfAwCi6E786pQeimLYVPpwFuNqYuciSTHvL BWvBVkNGMif4mV2QwZITXDFe9y+8lP1UmCEP+r9gH7Lbtw/03ETuy2/rLcDmKvlu+SCz3/jlKhXcS UYUjdOiA==; Received: from mail-wr1-x42d.google.com ([2a00:1450:4864:20::42d]) by bombadil.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lgwF2-00Apep-Og for linux-arm-kernel@lists.infradead.org; Wed, 12 May 2021 21:18:07 +0000 Received: by mail-wr1-x42d.google.com with SMTP id l14so25020708wrx.5 for ; Wed, 12 May 2021 14:18:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=WlYi+SHiGyL5WUEUZac2YTO9w6rW9DmdcDFUKtKvVSE=; b=FUsY0OsX/mgcdPw1YhxEy65vtbsSiiFiKciITa09rR+cECb25NvHg/KmKv3TS+HRGH kKHeILvdL8JvkrKXSqAaW98NjwrB8mmKCjxUQWj9mkcOndsmfE9P/xwpQhg82X+r7wFK w1aWVXK63qEOVJQq48YxuT/2JsjMS6h79W0bFqrs3YKoaYuKzFBEBQlsrT+Kq6mD3syO WuP9qH74D1dMLRRpdrexxU+Yef+kPhUDAzeGXP5xS/K99dSfdcd2sRBmLppLc08cvY9i j1CWPGAdXs/DNsnvDSNOq0SGGfJ+u0OPnoLZgNU4FF1c4I8srPeraIyA7/7tbXT6eiAO amdQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=WlYi+SHiGyL5WUEUZac2YTO9w6rW9DmdcDFUKtKvVSE=; b=n/FVZHB5IyKP4OQMZFnu72HMHxDSVIHiMFyK19Ver0TeOb3S2POQ9kjlp7EfP6W8vX 5riDs+iZj+6zFyPujUpQ6Gai5uKLUyM/YsS417ddsMoZCTNXHMN3WO8OvE0xpnBIhPds A/YWFz4iWAQtGt7RD4+ZG1jq4vyngE6p15Lhv5hw4xEXr9qikg2QwYl3we7MFu1Cg1eR WVbR8I3L1RTLGigtKhNN3+SFGGHiJSw2U6ITvgRdCks5F+5I0d3Jf13yALmTr0GRhNOr KJhRM9RLYF6xwIBbk/0gDwMP4+LPl1tJ6Vw5snoFHCDY4PopbzLhd/X25BoE4S45c/hr EJVQ== X-Gm-Message-State: AOAM531jYW3ngP9Y7tlAzctxFDNFAsRBoQnGcu5SaCpJadCmaMqu7L+R Dk20qtyhv8xUZ6+Ap5rnJlJl9A== X-Google-Smtp-Source: ABdhPJxZqoJxK5GkkEZhllbxMwmXlILS3aa6mGuBhnzz9lKzGDXMSIIDcyPtr/hWs5dRzphQJ1ZVKg== X-Received: by 2002:adf:f38c:: with SMTP id m12mr47021391wro.282.1620854283251; Wed, 12 May 2021 14:18:03 -0700 (PDT) Received: from linaro.org ([2a00:23c5:6809:2201:3d54:dc15:c65b:180c]) by smtp.gmail.com with ESMTPSA id e10sm908745wrw.20.2021.05.12.14.18.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 May 2021 14:18:03 -0700 (PDT) From: Mike Leach To: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org, mathieu.poirier@linaro.org, suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [RFC PATCH 3/8] coresight: syscfg: Example CoreSight configuration loadable module Date: Wed, 12 May 2021 22:17:47 +0100 Message-Id: <20210512211752.4103-4-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210512211752.4103-1-mike.leach@linaro.org> References: <20210512211752.4103-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210512_141804_826163_2D66C105 X-CRM114-Status: GOOD ( 22.26 ) 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org An example of creating a loadable module to add CoreSight configurations into a system. In the Kernel samples/coresight directory. Signed-off-by: Mike Leach Reviewed-by: Mathieu Poirier --- MAINTAINERS | 1 + samples/Kconfig | 9 +++ samples/Makefile | 1 + samples/coresight/Makefile | 4 ++ samples/coresight/coresight-cfg-sample.c | 73 ++++++++++++++++++++++++ 5 files changed, 88 insertions(+) create mode 100644 samples/coresight/Makefile create mode 100644 samples/coresight/coresight-cfg-sample.c diff --git a/MAINTAINERS b/MAINTAINERS index bd7aff0c120f..9ff5f5e7dd06 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1789,6 +1789,7 @@ F: Documentation/trace/coresight/* F: drivers/hwtracing/coresight/* F: include/dt-bindings/arm/coresight-cti-dt.h F: include/linux/coresight* +F: samples/coresight/* F: tools/perf/arch/arm/util/auxtrace.c F: tools/perf/arch/arm/util/cs-etm.c F: tools/perf/arch/arm/util/cs-etm.h diff --git a/samples/Kconfig b/samples/Kconfig index b5a1a7aa7e23..0cd618e15571 100644 --- a/samples/Kconfig +++ b/samples/Kconfig @@ -223,4 +223,13 @@ config SAMPLE_WATCH_QUEUE Build example userspace program to use the new mount_notify(), sb_notify() syscalls and the KEYCTL_WATCH_KEY keyctl() function. +config SAMPLE_CORESIGHT_SYSCFG + tristate "Build example loadable module for CoreSight config" + depends on CORESIGHT && m + help + Build an example loadable module that adds new CoreSight features + and configuration using the CoreSight system configuration API. + This demonstrates how a user may create their own CoreSight + configurations and easily load them into the system at runtime. + endif # SAMPLES diff --git a/samples/Makefile b/samples/Makefile index 087e0988ccc5..6c96297001a8 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -30,3 +30,4 @@ obj-$(CONFIG_SAMPLE_INTEL_MEI) += mei/ subdir-$(CONFIG_SAMPLE_WATCHDOG) += watchdog subdir-$(CONFIG_SAMPLE_WATCH_QUEUE) += watch_queue obj-$(CONFIG_DEBUG_KMEMLEAK_TEST) += kmemleak/ +obj-$(CONFIG_SAMPLE_CORESIGHT_SYSCFG) += coresight/ diff --git a/samples/coresight/Makefile b/samples/coresight/Makefile new file mode 100644 index 000000000000..09126aabf43d --- /dev/null +++ b/samples/coresight/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only + +obj-$(CONFIG_SAMPLE_CORESIGHT_SYSCFG) += coresight-cfg-sample.o +ccflags-y += -I$(src)/../../drivers/hwtracing/coresight diff --git a/samples/coresight/coresight-cfg-sample.c b/samples/coresight/coresight-cfg-sample.c new file mode 100644 index 000000000000..865c188fae34 --- /dev/null +++ b/samples/coresight/coresight-cfg-sample.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright(C) 2020 Linaro Limited. All rights reserved. + * Author: Mike Leach + */ + +#include "coresight-config.h" +#include "coresight-syscfg.h" + +/* create an alternate autofdo configuration */ + +/* we will provide 4 sets of preset parameter values */ +#define AFDO2_NR_PRESETS 4 +/* the total number of parameters in used features - strobing has 2 */ +#define AFDO2_NR_PARAM_SUM 2 + +static const char *afdo2_ref_names[] = { + "strobing", +}; + +/* + * set of presets leaves strobing window constant while varying period to allow + * experimentation with mark / space ratios for various workloads + */ +static u64 afdo2_presets[AFDO2_NR_PRESETS][AFDO2_NR_PARAM_SUM] = { + { 1000, 100 }, + { 1000, 1000 }, + { 1000, 5000 }, + { 1000, 10000 }, +}; + +struct cscfg_config_desc afdo2 = { + .name = "autofdo2", + .description = "Setup ETMs with strobing for autofdo\n" + "Supplied presets allow experimentation with mark-space ratio for various loads\n", + .nr_feat_refs = ARRAY_SIZE(afdo2_ref_names), + .feat_ref_names = afdo2_ref_names, + .nr_presets = AFDO2_NR_PRESETS, + .nr_total_params = AFDO2_NR_PARAM_SUM, + .presets = &afdo2_presets[0][0], +}; + +static struct cscfg_feature_desc *sample_feats[] = { + 0 +}; + +static struct cscfg_config_desc *sample_cfgs[] = { + &afdo2, + 0 +}; + +static struct cscfg_load_owner_info mod_owner = { + .type = CSCFG_OWNER_MODULE, + .owner_handle = THIS_MODULE, +}; + +/* module init and exit - just load and unload configs */ +static int __init cscfg_sample_init(void) +{ + return cscfg_load_config_sets(sample_cfgs, sample_feats, &mod_owner); +} + +static void __exit cscfg_sample_exit(void) +{ + cscfg_unload_config_sets(&mod_owner); +} + +module_init(cscfg_sample_init); +module_exit(cscfg_sample_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Mike Leach "); +MODULE_DESCRIPTION("CoreSight Syscfg Example"); From patchwork Wed May 12 21:17:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12254685 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=-17.4 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,USER_AGENT_GIT 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 E3BBAC43460 for ; Wed, 12 May 2021 21:21:17 +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 3EAD261264 for ; Wed, 12 May 2021 21:21:17 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3EAD261264 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:MIME-Version:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:Cc:To :From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=bLtHyFZ8iP7sHqK7ODDmaeXBNJlv5ee4BRMKebTs1SE=; b=LwFXRlg0BG15hdCRfFOUdH5+47 bDwTyvK0vZaXj2DTIiAhPeixaNhtlP/zB5zzmyvnqeTDEX2h3XpkkiuxfHo/JMNyQRc5n8dwi8Ir9 lsgvBLvB6yXOwu7hEmn1pDHMbbsIirCAn78oQUHPh1YYYDGTvbDeqOJ8oNOSG7UEiRPD83Bb7IMs1 GzOt0t953KeCrX7cCYlfdOJkrZAwaMTXxPzr/oR2Qlt3HcY9lsP03CQ4u1VXoyOqv4NwV771ydLgd nUtLEzWpyuvl/wPESDJ7yYdbv4mDELKHILE1R5ZLq5SYX2wW8nZRMtzycmm7rlHO5okvBFu+9kVuD zwC/427A==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lgwFi-0040aQ-Sp; Wed, 12 May 2021 21:18:47 +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 1lgwF7-0040Si-6g for linux-arm-kernel@desiato.infradead.org; Wed, 12 May 2021 21:18:10 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description; bh=X29LQIy5WVkatfJsupsDpSzEEIeN1D5SXi0DHsURTqA=; b=NjBrOogfFmnSGGMr8N+aIUj8Di s35QOuS514hBeKu7OJ2Ud0Jp5iS3KsD3wWk8soU+yBB6FmZlNvsrgXmaq2Ff5hgSueEBMW+UfuMWQ rPfFJV4vYw1J6Zqe6MtraSPp1EfbjysmSLif4KUdg9EphxWkuA94WYaA/RiigrNvZS3q5rQkHwiQn IHO2FoFe7VqBs5UGqFJs1D0i6BjD9IYc6zZbgQWdplAmc2jHqkiIagsM8TnpkLTI04roSpopG768p 1rVZU4tnZkq5E0aIskYa30JQPSrBBkLDFF+2XxHCwa9iRvJV5tBF5KUM20FOeuoMt3MNLrxuCOY58 H4z8AjUw==; Received: from mail-wr1-x42e.google.com ([2a00:1450:4864:20::42e]) by bombadil.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lgwF3-00ApfA-B6 for linux-arm-kernel@lists.infradead.org; Wed, 12 May 2021 21:18:07 +0000 Received: by mail-wr1-x42e.google.com with SMTP id l14so25020736wrx.5 for ; Wed, 12 May 2021 14:18:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=X29LQIy5WVkatfJsupsDpSzEEIeN1D5SXi0DHsURTqA=; b=ygXBysmUonfhWPMdudSS0nCQgIqNe34r8dZfHo07pCOGqOEvuuXuuYNQS42I0u8Br8 VOkx54KRnDH5rZRMacun9Ukx9VAHNqU6LdvdFjC9wVbZfLl2KpL+/P2o3Os9nQAhFsq0 2o8AuDEjr2mgfB87XmG55ifKlqfTxJbd973BlGUnkANBF2ISGkfa0mlupiC7US64ACLc 6s4dtzyMx4AVpnxFdEGu52A3l0m8hBBy1LgBExZhP319wf+2mAM7iuSKaTcMIwI7No39 7yWd6YJDXuYZjWfsx27wVSlkVnGvHWhxIRlMRvwU6CvdiLNl4tFbr+RLxs6OwqswbupG Sh5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=X29LQIy5WVkatfJsupsDpSzEEIeN1D5SXi0DHsURTqA=; b=M6EcltP6NJAwPoB+GNTzW9EhjtNDRis60GQT7Eo017pel+Dpxa6gbSc/xs2E7o9HC+ VGqUzjj4Q2lvEua7esnXQcIE5Gs36z9/TexOWnqeVw/9JuJWmCfVIIAvfgNtCTWKJXIh HqGjNy/QJzkh3f/atdbqtU8oUBMo/DcnqNL+/yN1tM7ZLHfmOdLcJeXL8GLHw4A4wisJ UwGJu5248Z7suChgxUYK98gSi1thTt6C3E1HSmXEEAlt4jIJrw6sKdQ3jpW6hJfjvyUo itLsgqPrb63KAgeUlT4a3QlqIzQ+k/F7ooj2/jx/YRQtPDPlv1mcq9FDpCL0gOr6iQTP SnIw== X-Gm-Message-State: AOAM532yKsaZb+698chhkOvIgb89PQwxwVfWC9el5PMP57H6z2RqH/x6 kbOM+6jfqvSqQC49GfCjsD6ksg== X-Google-Smtp-Source: ABdhPJzol2oc0HfubYUNswAILajL/q/e1xwE19I1tDhm92VjhI2ENzV9Kn51ycGOAAShfaEmiu2vLQ== X-Received: by 2002:adf:fa4c:: with SMTP id y12mr47645598wrr.393.1620854283820; Wed, 12 May 2021 14:18:03 -0700 (PDT) Received: from linaro.org ([2a00:23c5:6809:2201:3d54:dc15:c65b:180c]) by smtp.gmail.com with ESMTPSA id e10sm908745wrw.20.2021.05.12.14.18.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 May 2021 14:18:03 -0700 (PDT) From: Mike Leach To: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org, mathieu.poirier@linaro.org, suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [RFC PATCH 4/8] coresight: configfs: Allow configfs to activate configuration. Date: Wed, 12 May 2021 22:17:48 +0100 Message-Id: <20210512211752.4103-5-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210512211752.4103-1-mike.leach@linaro.org> References: <20210512211752.4103-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210512_141805_409681_D90D55CD X-CRM114-Status: GOOD ( 32.77 ) 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org 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 Reviewed-by: Mathieu Poirier --- .../coresight/coresight-etm4x-core.c | 5 + .../coresight/coresight-syscfg-configfs.c | 67 +++++++++ .../coresight/coresight-syscfg-configfs.h | 2 + .../hwtracing/coresight/coresight-syscfg.c | 129 ++++++++++++++---- .../hwtracing/coresight/coresight-syscfg.h | 7 +- 5 files changed, 182 insertions(+), 28 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index b7a4aeaa2bc7..2637096c4621 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -688,6 +688,11 @@ static int etm4_enable_sysfs(struct coresight_device *csdev) struct etm4_enable_arg arg = { }; int ret; + /* enable any config activated by configfs */ + ret = cscfg_csdev_enable_active_config(csdev, 0, 0); + if (ret) + return ret; + spin_lock(&drvdata->spinlock); /* diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c index 345a62f1b728..ae79ae8b1d7e 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c +++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c @@ -6,6 +6,7 @@ #include +#include "coresight-config.h" #include "coresight-syscfg-configfs.h" /* create a default ci_type. */ @@ -87,9 +88,75 @@ static ssize_t cscfg_cfg_values_show(struct config_item *item, char *page) } CONFIGFS_ATTR_RO(cscfg_cfg_, values); +static ssize_t cscfg_cfg_activate_show(struct config_item *item, char *page) +{ + struct cscfg_fs_config *fs_config = container_of(to_config_group(item), + struct cscfg_fs_config, group); + + return scnprintf(page, PAGE_SIZE, "%d\n", fs_config->active); +} + +static ssize_t cscfg_cfg_activate_store(struct config_item *item, + const char *page, size_t count) +{ + struct cscfg_fs_config *fs_config = container_of(to_config_group(item), + struct cscfg_fs_config, group); + int err; + bool val; + + err = kstrtobool(page, &val); + if (!err) + err = cscfg_config_sysfs_activation(fs_config->config_desc, val); + if (!err) { + fs_config->active = val; + if (val) + cscfg_config_sysfs_preset(fs_config->preset); + } + return err ? err : count; +} +CONFIGFS_ATTR(cscfg_cfg_, activate); + +static ssize_t cscfg_cfg_active_preset_show(struct config_item *item, char *page) +{ + struct cscfg_fs_config *fs_config = container_of(to_config_group(item), + struct cscfg_fs_config, group); + + return scnprintf(page, PAGE_SIZE, "%d\n", fs_config->preset); +} + +static ssize_t cscfg_cfg_active_preset_store(struct config_item *item, + const char *page, size_t count) +{ + struct cscfg_fs_config *fs_config = container_of(to_config_group(item), + struct cscfg_fs_config, group); + int preset, err; + + err = kstrtoint(page, 0, &preset); + if (!err) { + /* + * presets start at 1, and go up to max (15), + * but the config may provide fewer. + */ + if ((preset < 1) || (preset > fs_config->config_desc->nr_presets)) + err = -EINVAL; + } + + if (!err) { + /* set new value */ + fs_config->preset = preset; + /* set on system if active */ + if (fs_config->active) + cscfg_config_sysfs_preset(fs_config->preset); + } + return err ? err : count; +} +CONFIGFS_ATTR(cscfg_cfg_, active_preset); + static struct configfs_attribute *cscfg_config_view_attrs[] = { &cscfg_cfg_attr_description, &cscfg_cfg_attr_feature_refs, + &cscfg_cfg_attr_activate, + &cscfg_cfg_attr_active_preset, NULL, }; diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.h b/drivers/hwtracing/coresight/coresight-syscfg-configfs.h index ea1e54d29f7f..373d84d43268 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg-configfs.h +++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.h @@ -15,6 +15,8 @@ struct cscfg_fs_config { struct cscfg_config_desc *config_desc; struct config_group group; + bool active; + int preset; }; /* container for feature view */ diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c index 26c1a244c2b1..ab74e33b892b 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.c +++ b/drivers/hwtracing/coresight/coresight-syscfg.c @@ -743,32 +743,23 @@ void cscfg_csdev_reset_feats(struct coresight_device *csdev) } EXPORT_SYMBOL_GPL(cscfg_csdev_reset_feats); -/** - * cscfg_activate_config - Mark a configuration descriptor as active. - * - * This will be seen when csdev devices are enabled in the system. - * Only activated configurations can be enabled on individual devices. - * Activation protects the configuration from alteration or removal while - * active. - * - * Selection by hash value - generated from the configuration name when it - * was loaded and added to the cs_etm/configurations file system for selection - * by perf. +/* + * This activate configuration for either perf or sysfs. Perf can have multiple + * active configs, selected per event, sysfs is limited to one. * * Increments the configuration descriptor active count and the global active * count. * * @cfg_hash: Hash value of the selected configuration name. */ -int cscfg_activate_config(unsigned long cfg_hash) +static int _cscfg_activate_config(unsigned long cfg_hash) { struct cscfg_config_desc *config_desc; int err = -EINVAL; - mutex_lock(&cscfg_mutex); - list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) { if ((unsigned long)config_desc->event_ea->var == cfg_hash) { + /* must ensure that config cannot be unloaded in use */ err = cscfg_owner_get(config_desc->load_owner); if (err) @@ -790,6 +781,88 @@ int cscfg_activate_config(unsigned long cfg_hash) break; } } + return err; +} + +static void _cscfg_deactivate_config(unsigned long cfg_hash) +{ + struct cscfg_config_desc *config_desc; + + list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) { + if ((unsigned long)config_desc->event_ea->var == cfg_hash) { + atomic_dec(&config_desc->active_cnt); + atomic_dec(&cscfg_mgr->sys_active_cnt); + cscfg_owner_put(config_desc->load_owner); + dev_dbg(cscfg_device(), "Deactivate config %s.\n", config_desc->name); + break; + } + } +} + +/* + * called from configfs to set/clear the active configuration for use when + * using sysfs to control trace. + */ +int cscfg_config_sysfs_activation(struct cscfg_config_desc *config_desc, bool activate) +{ + unsigned long cfg_hash_desc; + int err = 0; + + mutex_lock(&cscfg_mutex); + + cfg_hash_desc = (unsigned long)config_desc->event_ea->var; + + if (activate) { + /* cannot be a current active value to activate this */ + if (cscfg_mgr->sysfs_active_config) { + err = -EBUSY; + goto exit_unlock; + } + err = _cscfg_activate_config(cfg_hash_desc); + if (!err) + cscfg_mgr->sysfs_active_config = cfg_hash_desc; + } else { + /* disable if matching current value */ + if (cscfg_mgr->sysfs_active_config == cfg_hash_desc) { + _cscfg_deactivate_config(cfg_hash_desc); + cscfg_mgr->sysfs_active_config = 0; + } else + err = -EINVAL; + } + +exit_unlock: + mutex_unlock(&cscfg_mutex); + return err; +} + +/* set the sysfs preset value */ +void cscfg_config_sysfs_preset(int preset) +{ + mutex_lock(&cscfg_mutex); + cscfg_mgr->sysfs_active_preset = preset; + mutex_unlock(&cscfg_mutex); +} + +/** + * cscfg_activate_config - Mark a configuration descriptor as active. + * + * This will be seen when csdev devices are enabled in the system. + * Only activated configurations can be enabled on individual devices. + * Activation protects the configuration from alteration or removal while + * active. + * + * Selection by hash value - generated from the configuration name when it + * was loaded and added to the cs_etm/configurations file system for selection + * by perf. + * + * @cfg_hash: Hash value of the selected configuration name. + */ +int cscfg_activate_config(unsigned long cfg_hash) +{ + int err = 0; + + mutex_lock(&cscfg_mutex); + err = _cscfg_activate_config(cfg_hash); mutex_unlock(&cscfg_mutex); return err; @@ -805,19 +878,8 @@ EXPORT_SYMBOL_GPL(cscfg_activate_config); */ void cscfg_deactivate_config(unsigned long cfg_hash) { - struct cscfg_config_desc *config_desc; - mutex_lock(&cscfg_mutex); - - list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) { - if ((unsigned long)config_desc->event_ea->var == cfg_hash) { - atomic_dec(&config_desc->active_cnt); - atomic_dec(&cscfg_mgr->sys_active_cnt); - cscfg_owner_put(config_desc->load_owner); - dev_dbg(cscfg_device(), "Deactivate config %s.\n", config_desc->name); - break; - } - } + _cscfg_deactivate_config(cfg_hash); mutex_unlock(&cscfg_mutex); } EXPORT_SYMBOL_GPL(cscfg_deactivate_config); @@ -826,7 +888,8 @@ EXPORT_SYMBOL_GPL(cscfg_deactivate_config); * cscfg_csdev_enable_active_config - Enable matching active configuration for device. * * Enables the configuration selected by @cfg_hash if the configuration is supported - * on the device and has been activated. + * on the device and has been activated. A @cfg_hash value of 0 is used if the device + * is being programmed from sysfs, to select the current sysfs active config. * * If active and supported the CoreSight device @csdev will be programmed with the * configuration, using @preset parameters. @@ -850,6 +913,16 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev, return 0; mutex_lock(&cscfg_csdev_mutex); + + /* sysfs controlled coresight will call with cfg_hash == 0 */ + if (!cfg_hash) { + if (!cscfg_mgr->sysfs_active_config) + goto exit_unlock; + + cfg_hash = cscfg_mgr->sysfs_active_config; + preset = cscfg_mgr->sysfs_active_preset; + } + list_for_each_entry(config_csdev_item, &csdev->config_csdev_list, node) { config_desc = config_csdev_item->config_desc; if ((atomic_read(&config_desc->active_cnt)) && @@ -863,6 +936,8 @@ int cscfg_csdev_enable_active_config(struct coresight_device *csdev, if (!err) csdev->active_cscfg_ctxt = (void *)config_csdev_active; } + +exit_unlock: mutex_unlock(&cscfg_csdev_mutex); return err; } diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h index 1da37874f70f..e07e1b872806 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.h +++ b/drivers/hwtracing/coresight/coresight-syscfg.h @@ -28,6 +28,8 @@ * @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. + * @sysfs_active_config:Active config hash used if CoreSight controlled from sysfs. + * @sysfs_active_preset:Active preset index used if CoreSight controlled from sysfs. */ struct cscfg_manager { struct device dev; @@ -37,6 +39,8 @@ struct cscfg_manager { struct list_head load_order_list; atomic_t sys_active_cnt; struct configfs_subsystem cfgfs_subsys; + u32 sysfs_active_config; + int sysfs_active_preset; }; /* get reference to dev in cscfg_manager */ @@ -88,7 +92,8 @@ 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); - +int cscfg_config_sysfs_activation(struct cscfg_config_desc *cfg_desc, bool activate); +void cscfg_config_sysfs_preset(int preset); /* syscfg manager external API */ int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs, From patchwork Wed May 12 21:17:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12254691 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=-17.4 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,USER_AGENT_GIT 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 11C11C433ED for ; Wed, 12 May 2021 21:21:58 +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 7405C611C9 for ; Wed, 12 May 2021 21:21:57 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7405C611C9 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:MIME-Version:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:Cc:To :From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=GnRL6yHYt1JI9z3ZHVCYJCiQ/aOTT3kP+wxvLDHrBp0=; b=HCijHViFZKB38vn/Pxd7gKbgnV WzS8NsAraVYHyEySKQj2VaslAcPLn7XvGxD6m2IMNzjyjkpM+Tr6YzZilC6lV9qmW9McICzfF4ZDD dnPEq5ctD/TLidDLvcnjSEeFxOUVDGh37llFb9+mJKMaPOjRy1ATY3D4FscX2DAIwoZ5vh3xrdLoA zhyJOmU8aI8YrFYIS5uqS89bSXiUo5xkjs18DY8gxpoduqdwNffCeBxTY6YQ4E0ayiS7HrkYhsvhE xXe7DsL8nXCCUcdK6Rt7KwTic6he5/L7WdG59NSDdtaPCxwI93sVp6KnlyyFaNV7HZHdShp0S2vls lz2ZMidA==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lgwGO-0040m6-HU; Wed, 12 May 2021 21:19:28 +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 1lgwF7-0040Sm-SE for linux-arm-kernel@desiato.infradead.org; Wed, 12 May 2021 21:18:11 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description; bh=/2B+m3JQzCXJiqd3Y+kjLvDba4XsvQeCp6DFTa+jT8U=; b=ZzFie38OcjmexqYXV9IKQpTcTK u7NIYL05HdGp5ZefswwBUV7KkcyhjTaEWWgydP4l8fd9BEMcCrodXYBvZ9uM425euV6aRSvquzPXe qEgJK1/+rDEXbTLdYyoHrafuFH9w5m+A1Y1ZufivCDd+gb0q2uUuDRLL1ABGz/xaGdFXV8bQtzUqu 00VCbSBnFL6aXj5+HykTEdrloKD9Ng01D1vRQ6NG6E5+qrLIs0m/a/KJxL/G1cdzPBtAi08UKEhAU F9mx2KiGJt2hKN+sqeMKLSAKhBKGz5nbwuhezTt9efcGbYiLohevrF0oWRcDQPUpXIs4fOHfuZ0Eq vUid7oBw==; Received: from mail-wr1-x432.google.com ([2a00:1450:4864:20::432]) by bombadil.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lgwF4-00Apfj-0Q for linux-arm-kernel@lists.infradead.org; Wed, 12 May 2021 21:18:08 +0000 Received: by mail-wr1-x432.google.com with SMTP id e7so6487632wrc.11 for ; Wed, 12 May 2021 14:18:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=/2B+m3JQzCXJiqd3Y+kjLvDba4XsvQeCp6DFTa+jT8U=; b=eSPQ3o5vSyxaq56JQrGZATEnXBuXINo8bzMt7wyW+50/2VoA6PJoWDz7v3G7zjO99U 5X1BOAjN3O5gK0aRJ8TOtyKXYUplmgBiyrcTvbdFqymEACfH2uZBYiJEr92sZN1P5SVV hmpnPXUOT+Zwo/7+/hsfvMNJrSDZbmJrOU/eOfm1CuLf+C2tMMTZcvFiGrv53+e5C7NI 1mi6p/YCJpO064j2nOyygLkgTlUZDQBt96dCkLkg81RrvRk9mBPTdoqlz2EYZdFn7WnJ MRzrWoJs+8KCgEoXyPobkTQ/BvmEwPUw3bheHzj7kFOMrUnjzxZ7BE8uX0PVlQfav3u6 YH/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=/2B+m3JQzCXJiqd3Y+kjLvDba4XsvQeCp6DFTa+jT8U=; b=f1FAuB+g/voVmqsilAxTBcvgr3bKhSEm0ps+tNcVG70016thyzTBsTyVRZ+MzGKb6x qkFf+vzDp2QuzcMsp1QfXYhNnCLqsALWnGdzspOK7NGkyzV0ci15+ZaMb1Tq4lLjgrMo NIqWxu8n26+JjBa7Nvy2/zVE91btRQda4bwtZSfX7nfoRzTGaKbqC+PSzaGVpcA2dmGH pTK0HCsd7oNyUFAOq/JnRj0+QLh7tDtpjecl6SCb9VyJ80QA0EIej79wfcDYAw6s0cgT tOI4tlVaeQfAbBXGQzaLlKraaN/sEz1XOv9VTaW+oNcH19iMRzeDJ+m1Q3BtXEWMQ65m OTpA== X-Gm-Message-State: AOAM533Sl+0U/XEyBkfeXnJwO8xXdn6XGUNWclA0yFP8MmoYImUMmJ99 V4Qwh00g93BvjchmwepzCyXuCXJMv2HOSg== X-Google-Smtp-Source: ABdhPJyK77ludpVOVh/ta9lgaeCx06I36IjnBUrXl8Zw6o3lYqEEWQbFD+Gf/P4BLH5pmNkYodG/SQ== X-Received: by 2002:a5d:590b:: with SMTP id v11mr47364103wrd.55.1620854284481; Wed, 12 May 2021 14:18:04 -0700 (PDT) Received: from linaro.org ([2a00:23c5:6809:2201:3d54:dc15:c65b:180c]) by smtp.gmail.com with ESMTPSA id e10sm908745wrw.20.2021.05.12.14.18.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 May 2021 14:18:04 -0700 (PDT) From: Mike Leach To: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org, mathieu.poirier@linaro.org, suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [RFC PATCH 5/8] coresight: syscfg: Add API to check and validate device resources. Date: Wed, 12 May 2021 22:17:49 +0100 Message-Id: <20210512211752.4103-6-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210512211752.4103-1-mike.leach@linaro.org> References: <20210512211752.4103-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210512_141806_106099_36BE3C00 X-CRM114-Status: GOOD ( 35.24 ) 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Adds in API to allow features which define device resources, to check resource availability on load, and allocate on enable. 1) Check on load ensures that the resources required by the feature do not exceed the maximum avialable on the device. 2) Allocate on enable ensures that sufficient unused resources are available to satifsfy the feature on enable. Allocate can also be used to resolve any resource selection requirements - i.e. select an available resource from a pool of resources. Signed-off-by: Mike Leach --- .../hwtracing/coresight/coresight-config.c | 71 +++++++++++++++--- .../hwtracing/coresight/coresight-config.h | 36 +++++++++- .../hwtracing/coresight/coresight-syscfg.c | 72 +++++++++++++++++-- 3 files changed, 163 insertions(+), 16 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-config.c b/drivers/hwtracing/coresight/coresight-config.c index 3c501e027bc0..fdfda1975188 100644 --- a/drivers/hwtracing/coresight/coresight-config.c +++ b/drivers/hwtracing/coresight/coresight-config.c @@ -23,6 +23,10 @@ static void cscfg_set_reg(struct cscfg_regval_csdev *reg_csdev) u32 *p_val32 = (u32 *)reg_csdev->driver_regval; u32 tmp32 = reg_csdev->reg_desc.val32; + /* resource mapped registers may have custom handling in the device */ + if (!reg_csdev->driver_regval) + return; + if (reg_csdev->reg_desc.type & CS_CFG_REG_TYPE_VAL_64BIT) { *((u64 *)reg_csdev->driver_regval) = reg_csdev->reg_desc.val64; return; @@ -43,6 +47,8 @@ static void cscfg_save_reg(struct cscfg_regval_csdev *reg_csdev) { if (!(reg_csdev->reg_desc.type & CS_CFG_REG_TYPE_VAL_SAVE)) return; + if (!reg_csdev->driver_regval) + return; if (reg_csdev->reg_desc.type & CS_CFG_REG_TYPE_VAL_64BIT) reg_csdev->reg_desc.val64 = *(u64 *)(reg_csdev->driver_regval); else @@ -73,15 +79,20 @@ static void cscfg_init_reg_param(struct cscfg_feature_csdev *feat_csdev, /* set values into the driver locations referenced in cscfg_reg_csdev */ static int cscfg_set_on_enable(struct cscfg_feature_csdev *feat_csdev) { - int i; + int i, err = 0; spin_lock(feat_csdev->drv_spinlock); for (i = 0; i < feat_csdev->nr_regs; i++) cscfg_set_reg(&feat_csdev->regs_csdev[i]); spin_unlock(feat_csdev->drv_spinlock); + + if (feat_csdev->feat_ops->set_on_enable) + err = feat_csdev->feat_ops->set_on_enable(feat_csdev); + dev_dbg(&feat_csdev->csdev->dev, "Feature %s: %s", - feat_csdev->feat_desc->name, "set on enable"); - return 0; + feat_csdev->feat_desc->name, + err ? "error on enable" : "set on enable"); + return err; } /* copy back values from the driver locations referenced in cscfg_reg_csdev */ @@ -89,6 +100,9 @@ static void cscfg_save_on_disable(struct cscfg_feature_csdev *feat_csdev) { int i; + if (feat_csdev->feat_ops->clear_on_disable) + feat_csdev->feat_ops->clear_on_disable(feat_csdev); + spin_lock(feat_csdev->drv_spinlock); for (i = 0; i < feat_csdev->nr_regs; i++) cscfg_save_reg(&feat_csdev->regs_csdev[i]); @@ -217,6 +231,37 @@ static int cscfg_update_curr_params(struct cscfg_config_csdev *config_csdev) return 0; } +static void cscfg_clear_res_config(struct cscfg_config_csdev *config_csdev) +{ + int i; + struct cscfg_feature_csdev *feat_csdev; + + for (i = 0; i < config_csdev->nr_feat; i++) { + feat_csdev = config_csdev->feats_csdev[i]; + if (feat_csdev->feat_ops->clear_feat_res) + feat_csdev->feat_ops->clear_feat_res(feat_csdev); + } +} + +#define FEAT_ALLOC_RES_FMT "coresight-syscfg: Insufficient resource to enable feature %s\n" +static int cscfg_alloc_res_config(struct cscfg_config_csdev *config_csdev) +{ + int err = 0, i; + struct cscfg_feature_csdev *feat_csdev; + + for (i = 0; i < config_csdev->nr_feat; i++) { + feat_csdev = config_csdev->feats_csdev[i]; + if (feat_csdev->feat_ops->alloc_feat_res) + err = feat_csdev->feat_ops->alloc_feat_res(feat_csdev); + if (err) { + pr_warn(FEAT_ALLOC_RES_FMT, feat_csdev->feat_desc->name); + cscfg_clear_res_config(config_csdev); + break; + } + } + return err; +} + /* * Configuration values will be programmed into the driver locations if enabling, or read * from relevant locations on disable. @@ -227,19 +272,29 @@ static int cscfg_prog_config(struct cscfg_config_csdev *config_csdev, bool enabl struct cscfg_feature_csdev *feat_csdev; struct coresight_device *csdev; + /* check we have resources to enable this */ + if (enable) { + err = cscfg_alloc_res_config(config_csdev); + if (err) + return err; + } else + cscfg_clear_res_config(config_csdev); + for (i = 0; i < config_csdev->nr_feat; i++) { feat_csdev = config_csdev->feats_csdev[i]; csdev = feat_csdev->csdev; dev_dbg(&csdev->dev, "cfg %s; %s feature:%s", config_csdev->config_desc->name, enable ? "enable" : "disable", feat_csdev->feat_desc->name); - if (enable) + if (enable) { err = cscfg_set_on_enable(feat_csdev); - else + if (err) { + /* failed to enable - release any resources */ + cscfg_clear_res_config(config_csdev); + break; + } + } else cscfg_save_on_disable(feat_csdev); - - if (err) - break; } return err; } diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h index 9bd44b940add..0e46832df993 100644 --- a/drivers/hwtracing/coresight/coresight-config.h +++ b/drivers/hwtracing/coresight/coresight-config.h @@ -199,6 +199,8 @@ struct cscfg_parameter_csdev { * @params_csdev: current parameter values on this device * @nr_regs: number of registers to be programmed. * @regs_csdev: Programming details for the registers + * @res_used: Device specific context for resources used on enable. + * @feat_ops: Feature operations to support alloc/release of resources. */ struct cscfg_feature_csdev { const struct cscfg_feature_desc *feat_desc; @@ -209,6 +211,8 @@ struct cscfg_feature_csdev { struct cscfg_parameter_csdev *params_csdev; int nr_regs; struct cscfg_regval_csdev *regs_csdev; + void *res_used; + struct cscfg_csdev_feat_ops *feat_ops; }; /** @@ -238,14 +242,44 @@ struct cscfg_config_csdev { * Coresight device operations. * * Registered coresight devices provide these operations to manage feature - * instances compatible with the device hardware and drivers + * instances compatible with the device hardware and drivers. + * + * The @check_feat_res function can be used at load time to see if the device has + * sufficient resources to support the feature. This takes into account all resources + * on the device. e.g. if the feature requires three counters, and the device has a + * total of two implemented counters, this will return a -ENODEV error. + * + * The @alloc_feat_res function checks if there are sufficient unallocated resources + * left to enable the feature. This allows for multiple features being loaded that + * may compete for resources and also selects and allocates resources at enable time. + * e.g. if a feature requires two comparators, and there is only one left unallocated, + * then this will return a -ENOSPC error. * * @load_feat: Pass a feature descriptor into the device and create the * loaded feature instance (struct cscfg_feature_csdev). + * @check_feat_res: Check that the coresight device has sufficient resources to + * load the feature. Optional function. Return -ENODEV if this device + * does not have enough resources. Called before @load_feat for feature + * to ensure all feature can be installed on device. + * @alloc_feat_res: Allocate release feature resources when enabling a feature on the device + * . Optional function. Returns -ENOSPC if the device has not enough available + * resources to enable the feature. Called before registers programmed. + * @clear_feat_res: Release allocated resources. Must be implemented if @alloc_feat_res is + * implemented. + * @set_on_enable : Optional programming specific to device. Called immediately after + * generic register programming operation. + * @clear_on_disable: Optional programming specific to device. Called before generic register + * save operation. */ struct cscfg_csdev_feat_ops { int (*load_feat)(struct coresight_device *csdev, struct cscfg_feature_csdev *feat_csdev); + int (*check_feat_res)(struct coresight_device *csdev, + struct cscfg_feature_desc *feat_desc); + int (*alloc_feat_res)(struct cscfg_feature_csdev *feat_csdev); + void (*clear_feat_res)(struct cscfg_feature_csdev *feat_csdev); + int (*set_on_enable)(struct cscfg_feature_csdev *feat_csdev); + void (*clear_on_disable)(struct cscfg_feature_csdev *feat_csdev); }; /* coresight config helper functions*/ diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c index ab74e33b892b..984459c8f168 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.c +++ b/drivers/hwtracing/coresight/coresight-syscfg.c @@ -121,7 +121,8 @@ static int cscfg_add_cfg_to_csdevs(struct cscfg_config_desc *config_desc) * memory allocated using the csdev->dev object using devm managed allocator. */ static struct cscfg_feature_csdev * -cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_desc *feat_desc) +cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_desc *feat_desc, + struct cscfg_csdev_feat_ops *ops) { struct cscfg_feature_csdev *feat_csdev = NULL; struct device *dev = csdev->dev.parent; @@ -165,9 +166,16 @@ cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_desc if (!feat_csdev->regs_csdev) return NULL; + /* copy the static register info */ + for (i = 0; i < feat_desc->nr_regs; i++) { + memcpy(&feat_csdev->regs_csdev[i].reg_desc, + &feat_desc->regs_desc[i], sizeof(struct cscfg_regval_desc)); + } + /* load the feature default values */ feat_csdev->feat_desc = feat_desc; feat_csdev->csdev = csdev; + feat_csdev->feat_ops = ops; return feat_csdev; } @@ -180,10 +188,7 @@ static int cscfg_load_feat_csdev(struct coresight_device *csdev, struct cscfg_feature_csdev *feat_csdev; int err; - if (!ops->load_feat) - return -EINVAL; - - feat_csdev = cscfg_alloc_csdev_feat(csdev, feat_desc); + feat_csdev = cscfg_alloc_csdev_feat(csdev, feat_desc, ops); if (!feat_csdev) return -ENOMEM; @@ -201,6 +206,57 @@ static int cscfg_load_feat_csdev(struct coresight_device *csdev, return 0; } +#define WARN_RES_FMT "coresight-syscfg: Insufficient resources to load feature %s in device %s\n" +#define PARAM_ERR_FMT "coresight-syscfg: Cannot load feature %s. Invalid parameter index\n" + +/* + * Check if device supports resource check function, and check for sufficient resources + * to load feature onto device. Validate parameter references. + * + * Load feature if sufficient resources & valid parameter references. + */ +static int cscfg_check_feat_res_load(struct coresight_device *csdev, + struct cscfg_feature_desc *feat_desc, + struct cscfg_csdev_feat_ops *ops) +{ + int err = 0, i; + + /* if we cannot load - fail early */ + if (!ops->load_feat) + return -EINVAL; + + /* ensure matched resource ops */ + if ((ops->alloc_feat_res && !ops->clear_feat_res) || + (!ops->alloc_feat_res && ops->clear_feat_res)) + return -EINVAL; + + /* ensure that the coresight device can support the feature */ + if (ops->check_feat_res) { + err = ops->check_feat_res(csdev, feat_desc); + if (err == -ENODEV) { + /* treat as mismatch, warn and continue */ + pr_warn(WARN_RES_FMT, feat_desc->name, + dev_name(&csdev->dev)); + return 0; + } + } + + /* check parameter indexes are valid */ + for (i = 0; i < feat_desc->nr_regs; i++) { + if (feat_desc->regs_desc[i].type & CS_CFG_REG_TYPE_VAL_PARAM) { + if (feat_desc->regs_desc[i].param_idx >= feat_desc->nr_params) { + pr_err(PARAM_ERR_FMT, feat_desc->name); + return -EINVAL; + } + } + } + + /* sufficient resources - load if no other error */ + if (!err) + err = cscfg_load_feat_csdev(csdev, feat_desc, ops); + return err; +} + /* * Add feature to any matching devices - call with mutex locked. * Iterates through devices - any device that matches the feature will be @@ -213,7 +269,9 @@ static int cscfg_add_feat_to_csdevs(struct cscfg_feature_desc *feat_desc) list_for_each_entry(csdev_item, &cscfg_mgr->csdev_desc_list, item) { if (csdev_item->match_flags & feat_desc->match_flags) { - err = cscfg_load_feat_csdev(csdev_item->csdev, feat_desc, &csdev_item->ops); + /* check sufficient resources and load feature */ + err = cscfg_check_feat_res_load(csdev_item->csdev, feat_desc, + &csdev_item->ops); if (err) return err; } @@ -616,7 +674,7 @@ static int cscfg_add_feats_csdev(struct coresight_device *csdev, list_for_each_entry(feat_desc, &cscfg_mgr->feat_desc_list, item) { if (feat_desc->match_flags & match_flags) { - err = cscfg_load_feat_csdev(csdev, feat_desc, ops); + err = cscfg_check_feat_res_load(csdev, feat_desc, ops); if (err) break; } From patchwork Wed May 12 21:17:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12254695 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=-17.4 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,USER_AGENT_GIT 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 AFA2FC433ED for ; Wed, 12 May 2021 21:22:26 +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 E0E046108D for ; Wed, 12 May 2021 21:22:25 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E0E046108D 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:MIME-Version:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:Cc:To :From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=blzyWdgSKwsizyVHrAcPfccaj9cNzL9PETBTcAl+rAI=; b=I68I6EGBh5M7VpVME4hcI6dSvo SgM55629bZ2+R6sUo7ZDoKtVBwKrfhSKQ1N1y5D+ABQ6m1lJJYXThcyH0UrJXN4XBv6OqE1CbyMcJ c31Bf7IeiOMC9gRkt/wA9U6JXc+kbSZNesuVHg84VqL+adgc4CwPYHovWdq4+sG+ElS5Njj/ml/u1 Y+l7AmxahXcIwUy89jwsJOLZFYiacWux0peDiooaYfUVNJS62sDgSHfSZ2CHJewDgQKgDsO73GWkx t478yTZ3MTLY6D12U0px4Xz1RD1Vl9OBLJ6AZ8NPYvoa+ixMrG9iXh/HK2eoBksCrDX0a2O2Mr9Vm mln+J04A==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lgwH1-0040va-Py; Wed, 12 May 2021 21:20:08 +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 1lgwF9-0040Sy-K3 for linux-arm-kernel@desiato.infradead.org; Wed, 12 May 2021 21:18:12 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description; bh=YAkBxlEq1dseQbidbyD37v47Spnzh/TfLCEbLMmeb68=; b=EV+/4Apypq/KoON21ufF67aCMb LvmtQxnxtcQHEihEd/8/cVfRXPpKUf+pp3eBtwv/gH/OpQkUsex8i9HK8e+uT93d1KlNxAGJphDQt hzbewd5UQHSlnrefvcVJp/RmS6mxEL/wVMGsccK88YNuL9IGl4BC5CE6uQ42GK5hnZ4qLjkKy8zxg NG/2/67SMde3TpJqPtDATCHKkjEBMwg8VTJOJkChZeM26Fmiy9vOSB5iz1xmyjyewSXe0oxE0wLAr TonLCBSdR5g4SOLU8ApzY6RtvZ8j85tlt4ifUz3mdqI/gYmXFzsIw/WxOCriLfZXks5YvFqS7qnc/ XZny3aUw==; Received: from mail-wr1-x42f.google.com ([2a00:1450:4864:20::42f]) by bombadil.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lgwF4-00Apg0-SK for linux-arm-kernel@lists.infradead.org; Wed, 12 May 2021 21:18:10 +0000 Received: by mail-wr1-x42f.google.com with SMTP id n2so25083064wrm.0 for ; Wed, 12 May 2021 14:18:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=YAkBxlEq1dseQbidbyD37v47Spnzh/TfLCEbLMmeb68=; b=Bby/ygI5B7xVAwy0qbcDfpB3Pwg6X2bEZE1Rn1TN5T0AoQoHm4cO/zh/LzWKf1U6qX UCWKhHv8Tr8lkmcsE1VV0E4LHnid4/M+ABLTfXiXMfVIFzPuEIhzuB72YfBsU61hoKRt lOoiXJ8EgahlP4Sqa5NKLgPsu1ETDwEgk2zJjj0/RYlQhcL7DrbPao+WVss9nVOpgXV0 R/ZYy+Y0aOdiBdJ1fI8IrLztVO/7NySG9GskNMmvnm8MeRW/mxgJCNA9y67dIkj8XoUF NEO8oNkC9NOraDTGKqGJDBhZekCl1Y2cY/Q93D9GInsy7n2Ia8WrWFM6CHk6s33eC+lU kFLw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=YAkBxlEq1dseQbidbyD37v47Spnzh/TfLCEbLMmeb68=; b=ahS/Oe7kxqTIN3p9cz7yuhVB7RhI7rW8egl6giL0vYpSjTr4E2bVCbmzA7G0EtpoPx h9/silz7lh2IbU402s1azy+rV6yroOGGCYfHijGJ4ohvYNpK/42/tyyEp3roxiGMYLvg +4D8sd4eERMSTyDtUqk+QvIqQJL/fR2G04QnJl50wU8koThyo2Y8FYDcZ6M/GzT11cMW 4BH3QIWZY1rRGeVWLrwbrJCffS39qYuFs96nPc0wlqggBYyLmoJ/bDNw6MqFwizg2jyc xBxpb5eo4BKuapukbbDVQ8rM8kYfTiH1lyh4xlT9xbVN0Zdvv8MzIwPbEx+aTtgu8pD6 l41g== X-Gm-Message-State: AOAM530DuZRQtNWu5bYXM1ngAmUXwO/WFury6Bbh18ducK1PjxDOi2A/ pUwbHv6UuHHMD2VQYEw2rsjRXA== X-Google-Smtp-Source: ABdhPJwQmoXl7QSe0OF7CRpsSeuLyymC7wuziahJioFmHiztjpqowUyjwBkeK3xVX6AIVBX5sGSUJg== X-Received: by 2002:adf:e5cd:: with SMTP id a13mr47168414wrn.303.1620854285125; Wed, 12 May 2021 14:18:05 -0700 (PDT) Received: from linaro.org ([2a00:23c5:6809:2201:3d54:dc15:c65b:180c]) by smtp.gmail.com with ESMTPSA id e10sm908745wrw.20.2021.05.12.14.18.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 May 2021 14:18:04 -0700 (PDT) From: Mike Leach To: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org, mathieu.poirier@linaro.org, suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [RFC PATCH 6/8] coresight: etm4x: syscfg: Add resource management to etm4x. Date: Wed, 12 May 2021 22:17:50 +0100 Message-Id: <20210512211752.4103-7-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210512211752.4103-1-mike.leach@linaro.org> References: <20210512211752.4103-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210512_141806_971934_7A540674 X-CRM114-Status: GOOD ( 37.72 ) 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Adds resource management to configuration and feature handling for ETM4 using the system configuration resource management API. Allows specification of ETM4 resources when creating configurations and features. Adds in checking and validation of resources used by features to prevent over allocation when multiple features used in a configuration. Signed-off-by: Mike Leach --- .../hwtracing/coresight/coresight-etm4x-cfg.c | 533 ++++++++++++++++++ .../hwtracing/coresight/coresight-etm4x-cfg.h | 196 ++++++- include/linux/coresight.h | 2 + 3 files changed, 724 insertions(+), 7 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c index d2ea903231b2..ba6d20b58a9a 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c @@ -28,6 +28,11 @@ } \ } +/* check for a match to ts rate */ +static bool etm4_cfg_feat_is_ts_rate(const struct cscfg_feature_desc *feat_desc); + +#define TS_RATE_REG_VAL_IDX 0 + /** * etm4_cfg_map_reg_offset - validate and map the register offset into a * location in the driver config struct. @@ -128,6 +133,66 @@ static int etm4_cfg_map_reg_offset(struct etmv4_drvdata *drvdata, return err; } +static void etm4_cfg_dump_res_mask(const char *name, struct etm4_cfg_resources *res) +{ + pr_debug("Mask %s\n", name); + pr_debug("selectors %08x; addr_cmp %04x\n", res->selectors, res->addr_cmp); + pr_debug("cid_cmp %02x; vmid_cmp %02x; counters %02x\n", res->cid_cmp, + res->vmid_cmp, res->counters); + pr_debug("misc bits %08x\n", res->misc); +} + +/* + * generate an address offset from a resource type and index + * Bit selected resources will return a ETM4_RES_OFFSET_SKIP value + * as these require special handling on enable / disable. + */ +static u32 etm4_cfg_get_res_offset(u16 res_type, u32 res_idx) +{ + u32 offset = ETM4_RES_OFFSET_ERR; + + switch (res_type & ETM4_CFG_RES_MASK) { + case ETM4_CFG_RES_CTR: + if (res_type & ETM4_CTR_VAL) + offset = TRCCNTVRn(res_idx); + else if (res_type & ETM4_CTR_RLD) + offset = TRCCNTRLDVRn(res_idx); + else if (res_type & ETM4_CTR_CTRL) + offset = TRCCNTCTLRn(res_idx); + break; + case ETM4_CFG_RES_CMP: + if (res_type & ETM4_CMP_VAL) + offset = TRCACVRn(res_idx); + else if (res_type & ETM4_CMP_CTL) + offset = TRCACATRn(res_idx); + break; + case ETM4_CFG_RES_SEL: + offset = TRCRSCTLRn(res_idx); + break; + + case ETM4_CFG_RES_SEQ: + if (res_type & ETM4_SEQ_STATE_R) + offset = TRCSEQEVRn(res_idx); + else if (res_type & ETM4_SEQ_RESET_R) + offset = TRCSEQRSTEVR; + break; + case ETM4_CFG_RES_CID_CMP: + offset = TRCCIDCVRn(res_idx); + break; + + case ETM4_CFG_RES_VID_CMP: + offset = TRCVMIDCVRn(res_idx); + break; + + /* these two have dedicated enable functions, no address needed */ + case ETM4_CFG_RES_BITCTRL: + case ETM4_CFG_RES_TS: + offset = ETM4_RES_OFFSET_SKIP; + break; + } + return offset; +} + /** * etm4_cfg_load_feature - load a feature into a device instance. * @@ -163,11 +228,349 @@ static int etm4_cfg_load_feature(struct coresight_device *csdev, /* process the register descriptions */ for (i = 0; i < feat_csdev->nr_regs && !err; i++) { offset = feat_desc->regs_desc[i].offset; + + /* resource needs conversion to a register access value */ + if (feat_desc->regs_desc[i].type & CS_CFG_REG_TYPE_RESOURCE) { + offset = etm4_cfg_get_res_offset(feat_desc->regs_desc[i].hw_info, + offset); + if (offset == ETM4_RES_OFFSET_ERR) { + err = -ENODEV; + break; + } else if (offset == ETM4_RES_OFFSET_SKIP) + continue; + } err = etm4_cfg_map_reg_offset(drvdata, &feat_csdev->regs_csdev[i], offset); } return err; } +/* + * ts rate - set a counter to emit timestamp requests at a set interval. + * if we have sufficient resources then we use a counter and resource + * selector to achieve this. + * + * However, if not then do the best possible - which prevents the perf + * event timestamp request from failing if any configuration selection + * is using resources. e.g. when profiling, timestamps do not really matter. + */ +void etm4_cfg_set_ts_rate(struct coresight_device *csdev, u32 ts_rate_val) +{ + struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + struct etmv4_config *drvcfg = &drvdata->config; + struct cscfg_res_impl_used *res_impl_used; + int counter_idx, res_sel_idx; + u32 tsctlr_val = 0; + + res_impl_used = (struct cscfg_res_impl_used *)csdev->cscfg_res_mask; + + /* look for resources */ + counter_idx = etm4_res_find_counter(res_impl_used); + res_sel_idx = etm4_res_find_selector(res_impl_used); + if (counter_idx >= 0 && res_sel_idx >= 0) { + /* counter and selector - can set up ts rate normally */ + /* + * counter @ 1 and reload @ rate supplied - + * immediate timestamp then every rate + */ + drvcfg->cntr_val[counter_idx] = 1; + drvcfg->cntrldvr[counter_idx] = ts_rate_val; + /* + * counter ctrl - bit 16: 1 for reload self, + * bit 7: 0 single event, + * bit 6:0 res sel 1 - true + */ + drvcfg->cntr_ctrl[counter_idx] = 0x1 << 16 | 0x1; + + /* + * set up resource selector for the counter. + * bits 19:16 - group 0b0010 counter + * bits 15:0 - bit select for counter idx + */ + drvcfg->res_ctrl[res_sel_idx] = (0x2 << 16) | (0x1 << counter_idx); + + /* single selector bit 7 == 0, bit 6:0 - selector index */ + tsctlr_val = res_sel_idx; + + } else if (ts_rate_val == 1) { + /* + * perf always tries to use a min value - + * emulate by setting the ts event to true + */ + /* single selector bit 7 == 0, bit 6:0 - selector 1 - always true */ + tsctlr_val = 0x1; + } + + /* set the configr reg to enable TS, and the ts control reg */ + drvcfg->ts_ctrl = tsctlr_val; + drvcfg->cfg |= BIT(11); +} + +/* + * on enable a feature - called after generic routine has programmed other registers. + * handle bit selects and custom elements + */ +static int etm4_cfg_on_enable_feat(struct cscfg_feature_csdev *feat_csdev) +{ + int err = 0; + struct etm4_cfg_resources *res_feat; + struct device *dev = feat_csdev->csdev->dev.parent; + struct etmv4_drvdata *drvdata = dev_get_drvdata(dev); + struct etmv4_config *drvcfg = &drvdata->config; + u32 ts_rate_val; + + /* + * look for the bit selected resources in this feature and set driver + * values to be programmed when enabling hardware. + */ + res_feat = (struct etm4_cfg_resources *)feat_csdev->res_used; + + /* if none of the bit selected resources in use, exit early */ + if (!res_feat->misc) + return 0; + + /* otherwise check each and set as required */ + if (res_feat->ctxt_id) + drvcfg->cfg |= BIT(6); + + if (res_feat->vm_id) + drvcfg->cfg |= BIT(7); + + /* return stack is bit 12 in config register */ + if (res_feat->return_stack) + drvcfg->cfg |= BIT(12); + + /* branch broadcast - feature using this must program the bbctlr */ + if (res_feat->branch_broadcast) + drvcfg->cfg |= BIT(3); + + /* cycle count */ + if (res_feat->cycle_cnt) { + drvcfg->cfg |= BIT(4); + /* TRM: Must program this for cycacc to work - ensure mun permitted */ + if (drvcfg->ccctlr < drvdata->ccitmin) + drvcfg->ccctlr = drvdata->ccitmin; + } + + /* + * timestamps - if not ts-rate just set to on, otherwise + * set using reload counter according to requested rate + */ + if (res_feat->timestamp) { + /* the current feature is the ts-rate feature */ + if (res_feat->ts_rate) { + ts_rate_val = feat_csdev->regs_csdev[TS_RATE_REG_VAL_IDX].reg_desc.val32; + etm4_cfg_set_ts_rate(feat_csdev->csdev, ts_rate_val); + } else + drvcfg->cfg |= BIT(11); + } + return err; +} + +/* set the overall available resource masks for the device */ +static int etm4_cfg_set_res_mask(struct coresight_device *csdev) +{ + struct device *dev = csdev->dev.parent; + struct etmv4_drvdata *drvdata = dev_get_drvdata(dev); + struct etm4_cfg_resources *res; + struct cscfg_res_impl_used *res_impl_used; + + res_impl_used = devm_kzalloc(dev, sizeof(*res_impl_used), GFP_KERNEL); + if (!res_impl_used) + return -ENOMEM; + res = &res_impl_used->impl; + + /* selectors */ + if (drvdata->nr_resource) + res->selectors = GENMASK((drvdata->nr_resource * 2) - 1, 0); + + /* comparators */ + if (drvdata->nr_addr_cmp) + res->addr_cmp = GENMASK(drvdata->nr_addr_cmp - 1, 0); + + if (drvdata->numvmidc) + res->vmid_cmp = GENMASK(drvdata->numvmidc - 1, 0); + + if (drvdata->numcidc) + res->cid_cmp = GENMASK(drvdata->numcidc - 1, 0); + + /* misc resources */ + if (drvdata->nr_cntr) + res->counters = GENMASK(drvdata->nr_cntr - 1, 0); + + if (drvdata->trccci) + res->cycle_cnt = 1; + + if (drvdata->trcbb) + res->branch_broadcast = 1; + + if (drvdata->ctxid_size) + res->ctxt_id = 1; + + if (drvdata->vmid_size) + res->vm_id = 1; + + if (drvdata->nrseqstate) + res->sequencer = 1; + + if (drvdata->retstack) + res->return_stack = 1; + + if (drvdata->ts_size) { + res->timestamp = 1; + if (drvdata->nr_cntr && drvdata->nr_resource) + res->ts_rate = 1; + } + etm4_cfg_dump_res_mask("device impl resources", &res_impl_used->impl); + csdev->cscfg_res_mask = res_impl_used; + return 0; +} + +/* + * reads a descriptor and updates the resource mask structure + * checks resource indexes are valid. + */ +static int etm4_cfg_update_res_from_desc(const struct cscfg_feature_desc *feat_desc, + struct etm4_cfg_resources *res) +{ + struct cscfg_regval_desc *regs_desc = &feat_desc->regs_desc[0]; + u32 res_idx, hw_info; + int i; + + for (i = 0; i < feat_desc->nr_regs; i++) { + if (regs_desc[i].type & CS_CFG_REG_TYPE_RESOURCE) { + res_idx = regs_desc[i].offset; + hw_info = regs_desc[i].hw_info; + switch (hw_info & ETM4_CFG_RES_MASK) { + case ETM4_CFG_RES_CTR: + if (res_idx >= ETMv4_MAX_CNTR) + goto invalid_resource_err; + res->counters |= BIT(res_idx); + break; + + case ETM4_CFG_RES_CMP: + if (res_idx >= ETM_MAX_SINGLE_ADDR_CMP) + goto invalid_resource_err; + res->addr_cmp |= BIT(res_idx); + break; + + case ETM4_CFG_RES_SEL: + if (res_idx >= ETM_MAX_RES_SEL) + goto invalid_resource_err; + res->selectors |= BIT(res_idx); + break; + + case ETM4_CFG_RES_SEQ: + res->sequencer = 1; + break; + + case ETM4_CFG_RES_TS: + res->timestamp = 1; + if (etm4_cfg_feat_is_ts_rate(feat_desc)) + res->ts_rate = 1; + break; + + case ETM4_CFG_RES_BITCTRL: + if (hw_info & ETM4_BITCTRL_BRANCH_BROADCAST) + res->branch_broadcast = 1; + if (hw_info & ETM4_BITCTRL_CYCLE_COUNT) + res->cycle_cnt = 1; + if (hw_info & ETM4_BITCTRL_CTXTID) + res->ctxt_id = 1; + if (hw_info & ETM4_BITCTRL_VMID) + res->vm_id = 1; + if (hw_info & ETM4_BITCTRL_RETSTACK) + res->return_stack = 1; + break; + + case ETM4_CFG_RES_CID_CMP: + if (res_idx >= ETMv4_MAX_CTXID_CMP) + goto invalid_resource_err; + res->cid_cmp |= BIT(res_idx); + break; + + case ETM4_CFG_RES_VID_CMP: + if (res_idx >= ETM_MAX_VMID_CMP) + goto invalid_resource_err; + res->vmid_cmp |= BIT(res_idx); + break; + } + } + } + return 0; + +invalid_resource_err: + pr_err("Error: Invalid resource values in feature %s\n", feat_desc->name); + return -EINVAL; +} +/* + * Check that the device contains the minimum resources required to support the + * described @feat_desc. Return -ENODEV if missing required resources. + */ +static int etm4_cfg_check_feat_res(struct coresight_device *csdev, + struct cscfg_feature_desc *feat_desc) +{ + struct etm4_cfg_resources req_res; + struct cscfg_res_impl_used *dev_res; + int err; + + /* create a resource mask from descriptor and validate */ + memset(&req_res, 0, sizeof(req_res)); + err = etm4_cfg_update_res_from_desc(feat_desc, &req_res); + etm4_cfg_dump_res_mask("check_feat_res", &req_res); + if (!err) { + dev_res = (struct cscfg_res_impl_used *)csdev->cscfg_res_mask; + if (!etm4_cfg_check_impl(&dev_res->impl, &req_res)) + return -ENODEV; + } + return err; +} + +/* + * Allocate resource requirements for the feature before + * it is programmed into the system. Ensures that two or more features in a + * configuration do not try to use the same resources on the device. + * + * At this point we use the absolute programmed resources - we do not attempt + * to find alternate available resources. (e.g. if 2 features use selector 3, + * fail the 2nd feature - do not look for an alternative free selector). + */ +static int etm4_cfg_alloc_feat_res(struct cscfg_feature_csdev *feat_csdev) +{ + struct coresight_device *csdev = feat_csdev->csdev; + struct device *dev = csdev->dev.parent; + struct etm4_cfg_resources *res_feat, *res_inuse; + int err = 0; + + /* one off initialisation of resources required for this feature */ + if (!feat_csdev->res_used) { + res_feat = devm_kzalloc(dev, sizeof(*res_feat), GFP_KERNEL); + if (!res_feat) + return -ENOMEM; + err = etm4_cfg_update_res_from_desc(feat_csdev->feat_desc, res_feat); + if (err) + return err; + feat_csdev->res_used = res_feat; + } else + res_feat = (struct etm4_cfg_resources *)feat_csdev->res_used; + + /* check that the device resources reqiured are not in use */ + res_inuse = &((struct cscfg_res_impl_used *)csdev->cscfg_res_mask)->used; + if (!etm4_cfg_check_set_inuse(res_inuse, res_feat)) + err = -ENOSPC; + + return err; +} + +static void etm4_cfg_clear_feat_res(struct cscfg_feature_csdev *feat_csdev) +{ + struct coresight_device *csdev = feat_csdev->csdev; + struct etm4_cfg_resources *res_feat, *res_inuse; + + res_feat = (struct etm4_cfg_resources *)feat_csdev->res_used; + res_inuse = &((struct cscfg_res_impl_used *)csdev->cscfg_res_mask)->used; + etm4_cfg_clear_inuse(res_inuse, res_feat); +} + /* match information when loading configurations */ #define CS_CFG_ETM4_MATCH_FLAGS (CS_CFG_MATCH_CLASS_SRC_ALL | \ CS_CFG_MATCH_CLASS_SRC_ETM4) @@ -175,8 +578,138 @@ static int etm4_cfg_load_feature(struct coresight_device *csdev, int etm4_cscfg_register(struct coresight_device *csdev) { struct cscfg_csdev_feat_ops ops; + int err = 0; + + err = etm4_cfg_set_res_mask(csdev); + if (err) + return err; ops.load_feat = &etm4_cfg_load_feature; + ops.check_feat_res = &etm4_cfg_check_feat_res; + ops.alloc_feat_res = &etm4_cfg_alloc_feat_res; + ops.clear_feat_res = &etm4_cfg_clear_feat_res; + ops.set_on_enable = &etm4_cfg_on_enable_feat; + ops.clear_on_disable = 0; return cscfg_register_csdev(csdev, CS_CFG_ETM4_MATCH_FLAGS, &ops); } + +/* + * find first available bit in implemented mask @impl, that is not set in @used mask. + * set bit in @used and return. Return -ENOSPC if no available bits. + */ +int etm4_cfg_find_unused_idx(unsigned long *impl, unsigned long *used, int size) +{ + unsigned long end_idx, unused_idx; + + end_idx = find_first_zero_bit(impl, size); + unused_idx = find_first_zero_bit(used, size); + if (unused_idx < end_idx) { + *used |= BIT(unused_idx); + return (int)unused_idx; + } + return -ENOSPC; +} + +/* + * find first available pair of bits in implemented mask @impl, that are not set in + * @used mask. First bit of pair will always be an even index. + * Set bits in @used and return. Return -ENOSPC if no available bits. + */ +int etm4_cfg_find_unused_idx_pair(unsigned long *impl, unsigned long *used, int size) +{ + unsigned long end_idx, first_unused_idx, next_unused_idx; + + end_idx = find_first_zero_bit(impl, size); + first_unused_idx = find_first_zero_bit(used, size); + + /* + * even indexes are the 1st in a pair, look through the comparators + * till a pair found or we are at the end of the list. + */ + while (first_unused_idx < end_idx) { + /* first is an even number, if the next is free we have a pair */ + if (!(first_unused_idx % 2)) { + next_unused_idx = find_next_zero_bit(used, size, first_unused_idx); + if (next_unused_idx == (first_unused_idx + 1)) { + *used |= BIT(first_unused_idx); + *used |= BIT(next_unused_idx); + return (int)first_unused_idx; + } + first_unused_idx = next_unused_idx; + } else + first_unused_idx = find_next_zero_bit(used, size, first_unused_idx); + } + return -ENOSPC; +} + + +/* built in timestamp rate for etm4x */ +static struct cscfg_parameter_desc ts_rate_param[] = { + { + .name = "ts_rate_cycles", + .value = 100. + }, +}; + +static struct cscfg_regval_desc ts_rate_regs[] = { + { + .type = CS_CFG_REG_TYPE_RESOURCE | CS_CFG_REG_TYPE_VAL_PARAM, + .offset = 0, + .hw_info = ETM4_CFG_RES_TS, + .param_idx = 0, + }, +}; + +static struct cscfg_feature_desc ts_rate_etm4x = { + .name = "timestamp-rate", + .description = "Enable timestamps and set rate they appear in the trace.\n" + "Rate value is number of cycles between timestamp requests. Min value 1.\n", + .match_flags = CS_CFG_MATCH_CLASS_SRC_ETM4, + .nr_params = ARRAY_SIZE(ts_rate_param), + .params_desc = ts_rate_param, + .nr_regs = ARRAY_SIZE(ts_rate_regs), + .regs_desc = ts_rate_regs, +}; + +static struct cscfg_feature_desc *etm4x_feats[] = { + &ts_rate_etm4x, + NULL, +}; + +static struct cscfg_config_desc *etm4x_cfgs[] = { + NULL, +}; + +static struct cscfg_load_owner_info etm4x_mod_owner = { + .type = CSCFG_OWNER_MODULE, + .owner_handle = THIS_MODULE, +}; + +/* + * check if incoming feature is ts-rate + */ +static bool etm4_cfg_feat_is_ts_rate(const struct cscfg_feature_desc *feat_desc) +{ + if (!strcmp(feat_desc->name, ts_rate_etm4x.name)) + return true; + return false; +} + +/* load the etm4 builtin ts_rate feature into the system */ +int etm4_cscfg_load_builtin_cfg(void) +{ + int err; + + err = cscfg_load_config_sets(etm4x_cfgs, etm4x_feats, &etm4x_mod_owner); + + /* if currently loaded matching devs ts_rate, still allow to load */ + if (err == -ENODEV) + err = 0; + return err; +} + +void etm4_cscfg_unload_builtin_cfg(void) +{ + cscfg_unload_config_sets(&etm4x_mod_owner); +} diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.h b/drivers/hwtracing/coresight/coresight-etm4x-cfg.h index 32dab34c1dac..dd69a8ef522d 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-cfg.h +++ b/drivers/hwtracing/coresight/coresight-etm4x-cfg.h @@ -13,18 +13,200 @@ /* resource IDs */ +/* + * 12 bit resource ID: + * 3:0 = resource type in use. + * 11:4 = additional resource specific information. + */ #define ETM4_CFG_RES_CTR 0x001 #define ETM4_CFG_RES_CMP 0x002 -#define ETM4_CFG_RES_CMP_PAIR0 0x003 -#define ETM4_CFG_RES_CMP_PAIR1 0x004 -#define ETM4_CFG_RES_SEL 0x005 -#define ETM4_CFG_RES_SEL_PAIR0 0x006 -#define ETM4_CFG_RES_SEL_PAIR1 0x007 -#define ETM4_CFG_RES_SEQ 0x008 -#define ETM4_CFG_RES_TS 0x009 +#define ETM4_CFG_RES_SEL 0x003 +#define ETM4_CFG_RES_SEQ 0x004 +#define ETM4_CFG_RES_TS 0x005 +#define ETM4_CFG_RES_BITCTRL 0x006 +#define ETM4_CFG_RES_CID_CMP 0x007 +#define ETM4_CFG_RES_VID_CMP 0x008 #define ETM4_CFG_RES_MASK 0x00F +/* additional bits to supplement _CFG_RES_CTR */ +#define ETM4_CTR_VAL 0x010 +#define ETM4_CTR_RLD 0x020 +#define ETM4_CTR_CTRL 0x040 + +/* additional bits for address comparators _CFG_RES_CMP */ +#define ETM4_CMP_PAIR0 0x010 +#define ETM4_CMP_PAIR1 0x020 +#define ETM4_CMP_VAL 0x040 +#define ETM4_CMP_CTL 0x080 + +/* additional bits for resource selectors _CFG_RES_SEL */ +#define ETM4_SEL_PAIR0 0x010 +#define ETM4_SEL_PAIR1 0x020 + +/* addtional bits for sequencer _CFG_RES_SEQ */ +#define ETM4_SEQ_STATE_R 0x010 +#define ETM4_SEQ_RESET_R 0x020 + +/* additional bits to supplement _CFG_RES_BITCTRL */ +#define ETM4_BITCTRL_BRANCH_BROADCAST 0x010 +#define ETM4_BITCTRL_CYCLE_COUNT 0x020 +#define ETM4_BITCTRL_CTXTID 0x040 +#define ETM4_BITCTRL_VMID 0x080 +#define ETM4_BITCTRL_RETSTACK 0x100 + +/* error value when calculating resource register offset (max offset = 0xFFC) */ +#define ETM4_RES_OFFSET_ERR 0xFFF + +/* skip value if a bit control that is resolved later */ +#define ETM4_RES_OFFSET_SKIP 0xFFE + +/** + * Masks to indicate resource usage. + * @selectors: The resource selector regs - max 32 off + * @comparators: Comparators - address (16 max), context ID (8 max), VMID (8 max). + * @misc:- bitselected features, sequencer etc. + */ +struct etm4_cfg_resources { + u32 selectors; + u16 addr_cmp; + u8 cid_cmp; + u8 vmid_cmp; + u8 counters; + union { + u32 misc; + struct { + u32 cycle_cnt:1; + u32 branch_broadcast:1; + u32 ctxt_id:1; + u32 vm_id:1; + u32 sequencer:1; + u32 return_stack:1; + u32 timestamp:1; + u32 ts_rate:1; + }; + }; +}; + +/* structure to hold implemented & used resources for the coresight device */ +struct cscfg_res_impl_used { + struct etm4_cfg_resources impl; + struct etm4_cfg_resources used; +}; + +/* resource mask tests */ +/* check implmented - ensure that all bits in @req exist in @impl */ +static inline bool etm4_cfg_check_impl(struct etm4_cfg_resources *impl, + struct etm4_cfg_resources *req) +{ + /* invert impl then and req - anything set is outside impl mask */ + if ((~impl->selectors & req->selectors) || + (~impl->addr_cmp & req->addr_cmp) || + (~impl->cid_cmp & req->cid_cmp) || + (~impl->vmid_cmp & req->vmid_cmp) || + (~impl->counters & req->counters) || + (~impl->misc & req->misc)) + return false; + return true; +} + +/* check @req not @inuse, & set @inuse if free (assumes @req passed the impl check) */ +static inline bool etm4_cfg_check_set_inuse(struct etm4_cfg_resources *inuse, + struct etm4_cfg_resources *req) +{ + /* first check for hits between inuse and requested bits */ + if ((inuse->selectors & req->selectors) || + (inuse->addr_cmp & req->addr_cmp) || + (inuse->cid_cmp & req->cid_cmp) || + (inuse->vmid_cmp & req->vmid_cmp) || + (inuse->counters & req->counters) || + (inuse->misc & req->misc)) + return false; + + /* set all requested bits as inuse */ + inuse->selectors |= req->selectors; + inuse->addr_cmp |= req->addr_cmp; + inuse->cid_cmp |= req->cid_cmp; + inuse->vmid_cmp |= req->vmid_cmp; + inuse->counters |= req->counters; + inuse->misc |= req->misc; + return true; +} + +static inline void etm4_cfg_clear_inuse(struct etm4_cfg_resources *inuse, + struct etm4_cfg_resources *req) +{ + /* clear requested bits from inuse */ + inuse->selectors &= ~req->selectors; + inuse->addr_cmp &= ~req->addr_cmp; + inuse->cid_cmp &= ~req->cid_cmp; + inuse->vmid_cmp &= ~req->vmid_cmp; + inuse->counters &= ~req->counters; + inuse->misc &= ~req->misc; +} + /* ETMv4 specific config functions */ int etm4_cscfg_register(struct coresight_device *csdev); +int etm4_cfg_find_unused_idx(unsigned long *impl, unsigned long *used, int size); +int etm4_cfg_find_unused_idx_pair(unsigned long *impl, unsigned long *used, int size); +void etm4_cfg_set_ts_rate(struct coresight_device *csdev, u32 ts_rate_val); + +/* register etm4x builtins with cscfg on module load */ +int etm4_cscfg_load_builtin_cfg(void); +void etm4_cscfg_unload_builtin_cfg(void); + +/* + * Set of functions to find an available resource from @res->impl, not already marked as used + * in @res->used. + * return index and mark as used in @res->used. return -ENOSPC if nothing available. + */ + +static inline int etm4_res_find_selector(struct cscfg_res_impl_used *res) +{ + unsigned long *impl, *used; + + if (!res->impl.selectors) + return -ENOSPC; + + impl = (unsigned long *)&res->impl.selectors; + used = (unsigned long *)&res->used.selectors; + return etm4_cfg_find_unused_idx(impl, used, ETM_MAX_RES_SEL); +} + +static inline int etm4_res_find_counter(struct cscfg_res_impl_used *res) +{ + unsigned long *impl, *used; + + if (!res->impl.counters) + return -ENOSPC; + + impl = (unsigned long *)&res->impl.counters; + used = (unsigned long *)&res->used.counters; + return etm4_cfg_find_unused_idx(impl, used, ETMv4_MAX_CNTR); +} + +static inline int etm4_res_find_addr_comparator(struct cscfg_res_impl_used *res) +{ + unsigned long *impl, *used; + + if (!res->impl.addr_cmp) + return -ENOSPC; + + impl = (unsigned long *)&res->impl.addr_cmp; + used = (unsigned long *)&res->used.addr_cmp; + return etm4_cfg_find_unused_idx(impl, used, ETM_MAX_SINGLE_ADDR_CMP); +} + + +static inline int etm4_res_find_addr_comp_pair(struct cscfg_res_impl_used *res) +{ + unsigned long *impl, *used; + + if (!res->impl.addr_cmp) + return -ENOSPC; + + impl = (unsigned long *)&res->impl.addr_cmp; + used = (unsigned long *)&res->used.addr_cmp; + return etm4_cfg_find_unused_idx_pair(impl, used, ETM_MAX_SINGLE_ADDR_CMP); +} #endif /* CORESIGHT_ETM4X_CFG_H */ diff --git a/include/linux/coresight.h b/include/linux/coresight.h index a348049ee08b..b513964b9305 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -223,6 +223,7 @@ struct coresight_sysfs_link { * @feature_csdev_list: List of complex feature programming added to the device. * @config_csdev_list: List of system configurations added to the device. * @active_cscfg_ctxt: Context information for current active system configuration. + * @cscfg_res_mask: Available device specific resources usable in features. */ struct coresight_device { struct coresight_platform_data *pdata; @@ -248,6 +249,7 @@ struct coresight_device { struct list_head feature_csdev_list; struct list_head config_csdev_list; void *active_cscfg_ctxt; + void *cscfg_res_mask; }; /* From patchwork Wed May 12 21:17:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12254693 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=-17.4 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,USER_AGENT_GIT 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 D4D4EC433B4 for ; Wed, 12 May 2021 21:22:05 +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 3200C61288 for ; Wed, 12 May 2021 21:22:05 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3200C61288 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:MIME-Version:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:Cc:To :From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=G484YuFlokZ57yAx5qTCYuXn7jqAZkwWhKdbIjm3A2E=; b=nS77IeXo8YF9h8bgBO1P0XVahv /cB6QLV3eh4OnQr7LGgj7y0bGRSLBL6CxU8jx6VePCECx0iyVj63KlfynV4+K6ydcqx6fZ5+4n2Aa wvgEts+mR2FSafO0b5FP7JDVc86JnvnbkAShUeYLYnAIqKkdG0cvj1jhulIIxbq8w+yJxnqY4fbPy ds6l2pPrKi/WFwcGjQYvWJ3tk20eqvmdp2MRqY44TLxfLw5191xvjrTgWBLnlh/QmTQ2kSdAJVysR ZntnqcLxwjv5gT2tQb4y6rR5KUz8BBh3tQElwq+rCz+Cn+5SMusxbC3pabhIhWdiO7gpo71giaqjt jq4tN8sA==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lgwGg-0040r0-Vr; Wed, 12 May 2021 21:19:47 +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 1lgwF9-0040Su-BI for linux-arm-kernel@desiato.infradead.org; Wed, 12 May 2021 21:18:11 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description; bh=wIxegkBmBsJB4GTCQldUaXdObPGVu255MasEW7Ulgzk=; b=e19qNEiFHt21SXoPut6m4WaRFv jhrGzBEDlH/PTV5QeWPtiNXSfl4YeNkjhpzAJV4LjglHwj1X41JIq8fzhLxcS8FT5cJzPNEjZB7kd 5eHc13QMzu9ZmnVaubIHS6HZcsecq+U+WCjFIiwqCBkBQ1c0x5UNeMXuW8osIT5WQ+DrHPWnFHw3b cK/RuE5kQuLsczWq98Cnnk7xO8VZW9ZWJs0WzloYBLhWKq7YpJlGSyhafGbsHdzgOTpwdWYqSuI6I 63/gpDX+uOyqhDLjJbDKBDSOxRKr9ZxAdz2DWb19kok4+ZrD4xZ197VN+f6uIFjY2Zg92xg7Ge5NB Ej/nr/TQ==; Received: from mail-wr1-x429.google.com ([2a00:1450:4864:20::429]) by bombadil.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lgwF5-00ApgK-Fh for linux-arm-kernel@lists.infradead.org; Wed, 12 May 2021 21:18:10 +0000 Received: by mail-wr1-x429.google.com with SMTP id x8so2725184wrq.9 for ; Wed, 12 May 2021 14:18:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=wIxegkBmBsJB4GTCQldUaXdObPGVu255MasEW7Ulgzk=; b=Hdl3HwC4fmEHSKmmhvE6ufm1cxgt2+Uw5fl8ynUG6mq6f4GZ79srrhE6X1/6W1O+el efIL1cPYFpwTHAyaFOZjZYApSr1tOYoJ7tQGxl92h22ufkTmapYugImYQzdVWySb0FCR ApjlUcu4CFDKxQdlxZKhSJ/wtuI/TQ0tH+LyWnv0b3vJs9vZ8JVd3/iOQOHRF+U36eTB XC/f+ms/L+nQ2Gzw/K6W/8p2pogDktXTO7y3S0HZGYotF2YtnVGqcszaZ/W29nT58Kek At87Kd7edAK+0aoZvNGEHGEQQtS9WuiI4JUqiMnzm8YObXrPZeT1v2RNSntoYLAvDKDy TVoQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=wIxegkBmBsJB4GTCQldUaXdObPGVu255MasEW7Ulgzk=; b=nIuQUeam0PoUCdwvKLYRcWOZnPncspbmlZeG97/hgf+W2iKKkvblKN+pVgCWt8aNr6 DceIAYqJice4YX8EKamEgPHpMwJ8e2tkdVkkAhNRW2wbLy8qBPjw6wk2HBYcKJM6Lc5S tuSjPu1lujsu06JV7I/FUajVqSSHWaHua8iMir1V7NlSnUKlRfIVJfzeCO9Z0+8u0vb+ ZMIwBcuJQO0LCCYFNr8qehrMvUt5CT3Klv0A5ULzEFzmNzYML9YKjw3K/Bj789qx5BPO Yj8yEFoZOxuaBf9VGOVLxDG4Dxz3nFB/s0H8P7s/+1vW0Px8320AhtDQ3t9tBHXkMm// TU3g== X-Gm-Message-State: AOAM532DDJ1rnmb0V1iEWpNtZ7J6tJ4R3P738kfw1ylD+024S+PliQNN r87S/sg4PH8UrDVtRLy5oh0EGQ== X-Google-Smtp-Source: ABdhPJytjEhl076ZP6/LhJU9PnsGiFeBT08OWSloNnMYxoSMNFymYJXwNYi+HLGjK8cubhMrXsTr/w== X-Received: by 2002:a5d:5109:: with SMTP id s9mr11580182wrt.231.1620854285757; Wed, 12 May 2021 14:18:05 -0700 (PDT) Received: from linaro.org ([2a00:23c5:6809:2201:3d54:dc15:c65b:180c]) by smtp.gmail.com with ESMTPSA id e10sm908745wrw.20.2021.05.12.14.18.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 May 2021 14:18:05 -0700 (PDT) From: Mike Leach To: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org, mathieu.poirier@linaro.org, suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [RFC PATCH 7/8] coresight: etm4x: Update perf event resource handling. Date: Wed, 12 May 2021 22:17:51 +0100 Message-Id: <20210512211752.4103-8-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210512211752.4103-1-mike.leach@linaro.org> References: <20210512211752.4103-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210512_141807_604576_52DB873C X-CRM114-Status: GOOD ( 36.28 ) 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Modifies current resource handling when parsing the perf event options to ensure that these are correctly allocated according to availability to ensure that configuration selection and other perf command line options can operated correctly together. Signed-off-by: Mike Leach --- .../coresight/coresight-etm4x-core.c | 245 ++++++------------ 1 file changed, 82 insertions(+), 163 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index 2637096c4621..4cc207d42976 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -58,7 +58,8 @@ MODULE_PARM_DESC(pm_save_enable, static struct etmv4_drvdata *etmdrvdata[NR_CPUS]; static void etm4_set_default_config(struct etmv4_config *config); static int etm4_set_event_filters(struct etmv4_drvdata *drvdata, - struct perf_event *event); + struct perf_event *event, + struct coresight_device *csdev); static u64 etm4_get_access_type(struct etmv4_config *config); static enum cpuhp_state hp_online; @@ -478,91 +479,6 @@ static void etm4_enable_hw_smp_call(void *info) arg->rc = etm4_enable_hw(arg->drvdata); } -/* - * The goal of function etm4_config_timestamp_event() is to configure a - * counter that will tell the tracer to emit a timestamp packet when it - * reaches zero. This is done in order to get a more fine grained idea - * of when instructions are executed so that they can be correlated - * with execution on other CPUs. - * - * To do this the counter itself is configured to self reload and - * TRCRSCTLR1 (always true) used to get the counter to decrement. From - * there a resource selector is configured with the counter and the - * timestamp control register to use the resource selector to trigger the - * event that will insert a timestamp packet in the stream. - */ -static int etm4_config_timestamp_event(struct etmv4_drvdata *drvdata) -{ - int ctridx, ret = -EINVAL; - int counter, rselector; - u32 val = 0; - struct etmv4_config *config = &drvdata->config; - - /* No point in trying if we don't have at least one counter */ - if (!drvdata->nr_cntr) - goto out; - - /* Find a counter that hasn't been initialised */ - for (ctridx = 0; ctridx < drvdata->nr_cntr; ctridx++) - if (config->cntr_val[ctridx] == 0) - break; - - /* All the counters have been configured already, bail out */ - if (ctridx == drvdata->nr_cntr) { - pr_debug("%s: no available counter found\n", __func__); - ret = -ENOSPC; - goto out; - } - - /* - * Searching for an available resource selector to use, starting at - * '2' since every implementation has at least 2 resource selector. - * ETMIDR4 gives the number of resource selector _pairs_, - * hence multiply by 2. - */ - for (rselector = 2; rselector < drvdata->nr_resource * 2; rselector++) - if (!config->res_ctrl[rselector]) - break; - - if (rselector == drvdata->nr_resource * 2) { - pr_debug("%s: no available resource selector found\n", - __func__); - ret = -ENOSPC; - goto out; - } - - /* Remember what counter we used */ - counter = 1 << ctridx; - - /* - * Initialise original and reload counter value to the smallest - * possible value in order to get as much precision as we can. - */ - config->cntr_val[ctridx] = 1; - config->cntrldvr[ctridx] = 1; - - /* Set the trace counter control register */ - val = 0x1 << 16 | /* Bit 16, reload counter automatically */ - 0x0 << 7 | /* Select single resource selector */ - 0x1; /* Resource selector 1, i.e always true */ - - config->cntr_ctrl[ctridx] = val; - - val = 0x2 << 16 | /* Group 0b0010 - Counter and sequencers */ - counter << 0; /* Counter to use */ - - config->res_ctrl[rselector] = val; - - val = 0x0 << 7 | /* Select single resource selector */ - rselector; /* Resource selector */ - - config->ts_ctrl = val; - - ret = 0; -out: - return ret; -} - static int etm4_parse_event_config(struct coresight_device *csdev, struct perf_event *event) { @@ -570,6 +486,7 @@ static int etm4_parse_event_config(struct coresight_device *csdev, struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); struct etmv4_config *config = &drvdata->config; struct perf_event_attr *attr = &event->attr; + struct etm4_cfg_resources *res_inuse; unsigned long cfg_hash; int preset; @@ -581,6 +498,10 @@ static int etm4_parse_event_config(struct coresight_device *csdev, /* Clear configuration from previous run */ memset(config, 0, sizeof(struct etmv4_config)); + /* clear any resources still marked as inuse */ + res_inuse = &((struct cscfg_res_impl_used *)csdev->cscfg_res_mask)->used; + memset(res_inuse, 0, sizeof(struct etm4_cfg_resources)); + if (attr->exclude_kernel) config->mode = ETM_MODE_EXCL_KERN; @@ -590,37 +511,51 @@ static int etm4_parse_event_config(struct coresight_device *csdev, /* Always start from the default config */ etm4_set_default_config(config); + /* + * First set any selected configuration and preset. + * + * This extracts the values of PMU_FORMAT_ATTR(configid) and PMU_FORMAT_ATTR(preset) + * in the perf attributes defined in coresight-etm-perf.c. + * configid uses bits 63:32 of attr->config2, preset uses bits 3:0 of attr->config. + * A zero configid means no configuration active, preset = 0 means no preset selected. + */ + if (attr->config2 & GENMASK_ULL(63, 32)) { + cfg_hash = (u32)(attr->config2 >> 32); + preset = attr->config & 0xF; + ret = cscfg_csdev_enable_active_config(csdev, cfg_hash, preset); + if (ret) + goto out; + } + + /* + * once any config is set, then we can add any perf options - + * using resource management to prevent clashes & not set items that + * are currently set. + */ + /* Configure filters specified on the perf cmd line, if any. */ - ret = etm4_set_event_filters(drvdata, event); + ret = etm4_set_event_filters(drvdata, event, csdev); if (ret) - goto out; + goto out_disable_cfg; /* Go from generic option to ETMv4 specifics */ - if (attr->config & BIT(ETM_OPT_CYCACC)) { + if ((attr->config & BIT(ETM_OPT_CYCACC)) && !res_inuse->cycle_cnt) { config->cfg |= BIT(4); /* TRM: Must program this for cycacc to work */ config->ccctlr = ETM_CYC_THRESHOLD_DEFAULT; } - if (attr->config & BIT(ETM_OPT_TS)) { + if ((attr->config & BIT(ETM_OPT_TS)) && !res_inuse->ts_rate) { /* * Configure timestamps to be emitted at regular intervals in * order to correlate instructions executed on different CPUs - * (CPU-wide trace scenarios). + * (CPU-wide trace scenarios). We use the built in ts rate function + * to manage any resource conflicts. Request a rate of 1 to maximise + * freqency of timestamps. */ - ret = etm4_config_timestamp_event(drvdata); - - /* - * No need to go further if timestamp intervals can't - * be configured. - */ - if (ret) - goto out; - - /* bit[11], Global timestamp tracing bit */ - config->cfg |= BIT(11); + etm4_cfg_set_ts_rate(csdev, 1); } - if (attr->config & BIT(ETM_OPT_CTXTID)) + if ((attr->config & BIT(ETM_OPT_CTXTID)) && !res_inuse->ctxt_id) /* bit[6], Context ID tracing bit */ config->cfg |= BIT(ETM4_CFG_BIT_CTXTID); @@ -632,30 +567,20 @@ static int etm4_parse_event_config(struct coresight_device *csdev, if (attr->config & BIT(ETM_OPT_CTXTID2)) { if (!is_kernel_in_hyp_mode()) { ret = -EINVAL; - goto out; + goto out_disable_cfg; } config->cfg |= BIT(ETM4_CFG_BIT_VMID) | BIT(ETM4_CFG_BIT_VMID_OPT); } /* return stack - enable if selected and supported */ - if ((attr->config & BIT(ETM_OPT_RETSTK)) && drvdata->retstack) + if ((attr->config & BIT(ETM_OPT_RETSTK)) && drvdata->retstack && !res_inuse->return_stack) /* bit[12], Return stack enable bit */ config->cfg |= BIT(12); - /* - * Set any selected configuration and preset. - * - * This extracts the values of PMU_FORMAT_ATTR(configid) and PMU_FORMAT_ATTR(preset) - * in the perf attributes defined in coresight-etm-perf.c. - * configid uses bits 63:32 of attr->config2, preset uses bits 3:0 of attr->config. - * A zero configid means no configuration active, preset = 0 means no preset selected. - */ - if (attr->config2 & GENMASK_ULL(63, 32)) { - cfg_hash = (u32)(attr->config2 >> 32); - preset = attr->config & 0xF; - ret = cscfg_csdev_enable_active_config(csdev, cfg_hash, preset); - } + return 0; +out_disable_cfg: + cscfg_csdev_disable_active_config(csdev); out: return ret; } @@ -871,6 +796,8 @@ static void etm4_disable_sysfs(struct coresight_device *csdev) spin_unlock(&drvdata->spinlock); cpus_read_unlock(); + cscfg_csdev_disable_active_config(csdev); + dev_dbg(&csdev->dev, "ETM tracing disabled\n"); } @@ -1375,52 +1302,37 @@ static void etm4_set_default(struct etmv4_config *config) etm4_set_default_filter(config); } -static int etm4_get_next_comparator(struct etmv4_drvdata *drvdata, u32 type) +static int etm4_get_next_comparator_res(struct cscfg_res_impl_used *res, + u32 type) { - int nr_comparator, index = 0; - struct etmv4_config *config = &drvdata->config; - - /* - * nr_addr_cmp holds the number of comparator _pair_, so time 2 - * for the total number of comparators. - */ - nr_comparator = drvdata->nr_addr_cmp * 2; + switch (type) { + case ETM_ADDR_TYPE_RANGE: + return etm4_res_find_addr_comp_pair(res); - /* Go through the tally of comparators looking for a free one. */ - while (index < nr_comparator) { - switch (type) { - case ETM_ADDR_TYPE_RANGE: - if (config->addr_type[index] == ETM_ADDR_TYPE_NONE && - config->addr_type[index + 1] == ETM_ADDR_TYPE_NONE) - return index; - - /* Address range comparators go in pairs */ - index += 2; - break; - case ETM_ADDR_TYPE_START: - case ETM_ADDR_TYPE_STOP: - if (config->addr_type[index] == ETM_ADDR_TYPE_NONE) - return index; - - /* Start/stop address can have odd indexes */ - index += 1; - break; - default: - return -EINVAL; - } + case ETM_ADDR_TYPE_START: + case ETM_ADDR_TYPE_STOP: + return etm4_res_find_addr_comparator(res); } - - /* If we are here all the comparators have been used. */ - return -ENOSPC; + return -EINVAL; } +/* + * Called to set up perf event filters - after any selected configuration. + * This allows the perf command line filters to be used in combination with + * any selected configuration. + * + * Use the config resources to find available comparators - only set default + * filter if no previous configuration has set up filtering. + */ static int etm4_set_event_filters(struct etmv4_drvdata *drvdata, - struct perf_event *event) + struct perf_event *event, + struct coresight_device *csdev) { int i, comparator, ret = 0; u64 address; struct etmv4_config *config = &drvdata->config; struct etm_filters *filters = event->hw.addr_filters; + struct cscfg_res_impl_used *res = (struct cscfg_res_impl_used *)csdev->cscfg_res_mask; if (!filters) goto default_filter; @@ -1440,7 +1352,7 @@ static int etm4_set_event_filters(struct etmv4_drvdata *drvdata, enum etm_addr_type type = filter->type; /* See if a comparator is free. */ - comparator = etm4_get_next_comparator(drvdata, type); + comparator = etm4_get_next_comparator_res(res, type); if (comparator < 0) { ret = comparator; goto out; @@ -1457,10 +1369,8 @@ static int etm4_set_event_filters(struct etmv4_drvdata *drvdata, * in the started state */ config->vinst_ctrl |= BIT(9); - - /* No start-stop filtering for ViewInst */ - config->vissctlr = 0x0; break; + case ETM_ADDR_TYPE_START: case ETM_ADDR_TYPE_STOP: /* Get the right start or stop address */ @@ -1485,10 +1395,8 @@ static int etm4_set_event_filters(struct etmv4_drvdata *drvdata, */ if (filters->ssstatus) config->vinst_ctrl |= BIT(9); - - /* No include/exclude filtering for ViewInst */ - config->viiectlr = 0x0; break; + default: ret = -EINVAL; goto out; @@ -1497,9 +1405,10 @@ static int etm4_set_event_filters(struct etmv4_drvdata *drvdata, goto out; - default_filter: - etm4_set_default_filter(config); + /* if no filtering has been set by any other method - set default here */ + if (!config->viiectlr && !config->vissctlr) + etm4_set_default_filter(config); out: return ret; @@ -2161,10 +2070,19 @@ static int __init etm4x_init(void) } ret = platform_driver_register(&etm4_platform_driver); + if (ret) { + pr_err("Error registering etm4x platform driver\n"); + goto clear_amba; + } + + ret = etm4_cscfg_load_builtin_cfg(); if (!ret) return 0; - pr_err("Error registering etm4x platform driver\n"); + pr_err("Error loading etm4x coresight configurations\n"); + platform_driver_unregister(&etm4_platform_driver); + +clear_amba: amba_driver_unregister(&etm4x_amba_driver); clear_pm: @@ -2174,6 +2092,7 @@ static int __init etm4x_init(void) static void __exit etm4x_exit(void) { + etm4_cscfg_unload_builtin_cfg(); amba_driver_unregister(&etm4x_amba_driver); platform_driver_unregister(&etm4_platform_driver); etm4_pm_clear(); From patchwork Wed May 12 21:17:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Leach X-Patchwork-Id: 12254689 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=-17.4 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,USER_AGENT_GIT 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 7CDD0C433B4 for ; Wed, 12 May 2021 21:21:39 +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 D85A46108D for ; Wed, 12 May 2021 21:21:38 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D85A46108D 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:MIME-Version:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:Cc:To :From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=xyPRZBIOlTxue/Tyx5/XFu/yZ8JGNL6RDvZ2PKCvZpI=; b=Xs9I47RIjjl2wD1ZU2hDv+d8XM EbVXAssWyj0rReKeQJEr5T0hLAQzjsGpeHw8BrKRRSqctW05JJ+1vdkBMWWsT0z/Y/lPWH4zKtS89 WeVAPZUHZfZ6y8ClNQ/EIKjb2WE9UNO+y/eBAjIYKnZ3ZLd9HC7Jg/QBc13LZHmwopapJBA/00ewY ptKk8d3vorHZkqBlxQtruF/Z9lcnBhmnRD/ymIYHD3StT4PdhjOQyVN/10bD5p2JaGHblp9jH1YhY JLSsQkgGbYBNNja2WeKZYkbiXu2wOSRiRl6iWGVY+AKNs3roa14i9l+d/+j906ctHb0PMk6p/8XPQ 1sZNzjCg==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lgwGA-0040hy-Vc; Wed, 12 May 2021 21:19:15 +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 1lgwF8-0040Sq-O2 for linux-arm-kernel@desiato.infradead.org; Wed, 12 May 2021 21:18:11 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description; bh=76IdugtbClFxLj74WNNMpYQI/ftacptYSE6W5nWHEcc=; b=vk8VIs8QRXEhQQEvIOhCSnYuq6 fPQjOZ/M7AaHRjrXtl1rjfxGt64xUIgIwJp1TxSuJAFf1wSWcozW8/4/W5pkzAtqRWKo1BhnvVd+2 YYzTMS9saaaZ72QLMEnDPJN5VTsRISod71hDQdwtm39pY4bvW3JwSAb4WoVsUL/FdMfSvUii9cTXm n3b+++aaie+2RSb/nO+4kOCEByeTmyTkA6k+CCkTCO7bWCudpjvtvZ+75zGGw6v9qp6d5QAzMnajn QqzQ77cUuDhxk57D4kwnnKFeBHJgMaJpwBMzQi4ZzLu+Nm89HAPQUFJU6CLIhxzhW8FPji5ZQ4RBU NSnhT0wA==; Received: from mail-wr1-x42c.google.com ([2a00:1450:4864:20::42c]) by bombadil.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lgwF5-00ApgL-Qw for linux-arm-kernel@lists.infradead.org; Wed, 12 May 2021 21:18:09 +0000 Received: by mail-wr1-x42c.google.com with SMTP id x8so2725204wrq.9 for ; Wed, 12 May 2021 14:18:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=76IdugtbClFxLj74WNNMpYQI/ftacptYSE6W5nWHEcc=; b=EvAbYrfcjZEzlvP/nsxKyYaRxZc6FQIYOelDOXWYxAKxhpHguj9ukDNiozUwc01j5H oiN3Egkp63eZo/eZ75oOS086Mp5vYBiDya/Qr1gEcEuJ0d6pSIqXwfAIbMlFH2ME8IM9 dF84hjmx7jd3mAYMc7cBWwrVGJXnW4+dnNvWBsB5wVFzE9z0ZYdl+634t6RluBgi0cAH rvnLsXxLDmLWiKuvVxUi00HpBcd7ebHJt6jfTvNmbbl4t4RDkL9WDiyi1CcJUEBkqXz5 ojnukM3omiHcm1O8OrYo+TMzYL4wy7sVYy4XaaA9ByOUCGN5iaJc/lGyr0qGdGj6w4xA F/og== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=76IdugtbClFxLj74WNNMpYQI/ftacptYSE6W5nWHEcc=; b=JCfTVCXj23F8Q94fVFXDBq9F0oL6k78LJ9aB/m08VcLXd5AVSOFcYy8hq9wjj0xD0v Lcb2mygEyBXtieCwSAbPlMoiLSeN/Z9BalU9I2uL8/S8D4SPiWUhvHhzaHs72nzZmgFN y1SX9sCzJXndcCQ0+ATrFDaTE7mjb9clnzLB8RobjFqjdcdueYJirowoOYCIv2MvxDDh OzkzWamyCuScCOLA4XtYtG+cSoUGx6wtSvkI5jutWFmvaQyHzgRJEysydlBPXSdTuQCw UWrWjcRR8t3KZuGoGAhHjO4iQB31Z5595FmQlYHuPfcIqfI51OX772jHc5paZ1rx6djx PjDA== X-Gm-Message-State: AOAM533LA7+P/zJmqnyF/3Vuii7aHr50JkDAEhbsRWar9vkxXUOnBn6v CvGNJVGeV4EbhNfdB1C2ASQaPQ== X-Google-Smtp-Source: ABdhPJwKnlbJ4gpNyi4xk/Vv42orcu0jI44ghxbD2ytgRG+DksweHVfAME0KE1tF0F2TJKW6puNYEA== X-Received: by 2002:adf:cc92:: with SMTP id p18mr11384097wrj.87.1620854286367; Wed, 12 May 2021 14:18:06 -0700 (PDT) Received: from linaro.org ([2a00:23c5:6809:2201:3d54:dc15:c65b:180c]) by smtp.gmail.com with ESMTPSA id e10sm908745wrw.20.2021.05.12.14.18.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 May 2021 14:18:06 -0700 (PDT) From: Mike Leach To: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org, mathieu.poirier@linaro.org, suzuki.poulose@arm.com, leo.yan@linaro.org, Mike Leach Subject: [RFC PATCH 8/8] coresight: etm4x: Update configuration example. Date: Wed, 12 May 2021 22:17:52 +0100 Message-Id: <20210512211752.4103-9-mike.leach@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210512211752.4103-1-mike.leach@linaro.org> References: <20210512211752.4103-1-mike.leach@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210512_141807_900279_950DC901 X-CRM114-Status: GOOD ( 12.34 ) 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Update autofdo configuration and etm4 strobing feature example to use new resource allocation methods. Signed-off-by: Mike Leach --- .../hwtracing/coresight/coresight-cfg-afdo.c | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-cfg-afdo.c b/drivers/hwtracing/coresight/coresight-cfg-afdo.c index 84b31184252b..cae142827d44 100644 --- a/drivers/hwtracing/coresight/coresight-cfg-afdo.c +++ b/drivers/hwtracing/coresight/coresight-cfg-afdo.c @@ -30,63 +30,63 @@ static struct cscfg_regval_desc strobe_regs[] = { /* resource selectors */ { .type = CS_CFG_REG_TYPE_RESOURCE, - .offset = TRCRSCTLRn(2), + .offset = 2, .hw_info = ETM4_CFG_RES_SEL, .val32 = 0x20001, }, { .type = CS_CFG_REG_TYPE_RESOURCE, - .offset = TRCRSCTLRn(3), - .hw_info = ETM4_CFG_RES_SEQ, + .offset = 3, + .hw_info = ETM4_CFG_RES_SEL, .val32 = 0x20002, }, /* strobe window counter 0 - reload from param 0 */ { .type = CS_CFG_REG_TYPE_RESOURCE | CS_CFG_REG_TYPE_VAL_SAVE, - .offset = TRCCNTVRn(0), - .hw_info = ETM4_CFG_RES_CTR, + .offset = 0, + .hw_info = ETM4_CFG_RES_CTR | ETM4_CTR_VAL, }, { .type = CS_CFG_REG_TYPE_RESOURCE | CS_CFG_REG_TYPE_VAL_PARAM, - .offset = TRCCNTRLDVRn(0), - .hw_info = ETM4_CFG_RES_CTR, + .offset = 0, + .hw_info = ETM4_CFG_RES_CTR | ETM4_CTR_RLD, .val32 = 0, }, { .type = CS_CFG_REG_TYPE_RESOURCE, - .offset = TRCCNTCTLRn(0), - .hw_info = ETM4_CFG_RES_CTR, + .offset = 0, + .hw_info = ETM4_CFG_RES_CTR | ETM4_CTR_CTRL, .val32 = 0x10001, }, /* strobe period counter 1 - reload from param 1 */ { .type = CS_CFG_REG_TYPE_RESOURCE | CS_CFG_REG_TYPE_VAL_SAVE, - .offset = TRCCNTVRn(1), - .hw_info = ETM4_CFG_RES_CTR, + .offset = 1, + .hw_info = ETM4_CFG_RES_CTR | ETM4_CTR_VAL, }, { .type = CS_CFG_REG_TYPE_RESOURCE | CS_CFG_REG_TYPE_VAL_PARAM, - .offset = TRCCNTRLDVRn(1), - .hw_info = ETM4_CFG_RES_CTR, + .offset = 1, + .hw_info = ETM4_CFG_RES_CTR | ETM4_CTR_RLD, .val32 = 1, }, { .type = CS_CFG_REG_TYPE_RESOURCE, - .offset = TRCCNTCTLRn(1), - .hw_info = ETM4_CFG_RES_CTR, + .offset = 1, + .hw_info = ETM4_CFG_RES_CTR | ETM4_CTR_CTRL, .val32 = 0x8102, }, /* sequencer */ { .type = CS_CFG_REG_TYPE_RESOURCE, - .offset = TRCSEQEVRn(0), - .hw_info = ETM4_CFG_RES_SEQ, + .offset = 0, + .hw_info = ETM4_CFG_RES_SEQ | ETM4_SEQ_STATE_R, .val32 = 0x0081, }, { .type = CS_CFG_REG_TYPE_RESOURCE, - .offset = TRCSEQEVRn(1), - .hw_info = ETM4_CFG_RES_SEQ, + .offset = 1, + .hw_info = ETM4_CFG_RES_SEQ | ETM4_SEQ_STATE_R, .val32 = 0x0000, }, /* view-inst */