From nobody Wed Dec 17 05:48:46 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 49A60C4332F for ; Tue, 12 Dec 2023 15:55:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376651AbjLLPzK (ORCPT ); Tue, 12 Dec 2023 10:55:10 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50346 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233056AbjLLPzE (ORCPT ); Tue, 12 Dec 2023 10:55:04 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 976C012E for ; Tue, 12 Dec 2023 07:55:09 -0800 (PST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 532C9143D; Tue, 12 Dec 2023 07:55:55 -0800 (PST) Received: from e127643.broadband (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 7F0E53F738; Tue, 12 Dec 2023 07:55:07 -0800 (PST) From: James Clark To: coresight@lists.linaro.org, suzuki.poulose@arm.com Cc: James Clark , Mike Leach , Alexander Shishkin , Maxime Coquelin , Alexandre Torgue , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com Subject: [PATCH 1/8] coresight: Fix issue where a source device's helpers aren't disabled Date: Tue, 12 Dec 2023 15:53:58 +0000 Message-Id: <20231212155407.1429121-2-james.clark@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231212155407.1429121-1-james.clark@arm.com> References: <20231212155407.1429121-1-james.clark@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The linked commit reverts the change that accidentally used some sysfs enable/disable functions from Perf which broke the refcounting, but it also removes the fact that the sysfs disable function disabled the helpers. Add a new wrapper function that does both which is used by both Perf and sysfs, and label the sysfs disable function appropriately. The naming of all of the functions will be tidied up later to avoid this happening again. Fixes: 287e82cf69aa ("coresight: Fix crash when Perf and sysfs modes are us= ed concurrently") Signed-off-by: James Clark --- drivers/hwtracing/coresight/coresight-core.c | 30 ++++++++++++++----- .../hwtracing/coresight/coresight-etm-perf.c | 2 +- drivers/hwtracing/coresight/coresight-priv.h | 2 +- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtraci= ng/coresight/coresight-core.c index d7f0e231feb9..965bb6d4e1bf 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -441,8 +441,26 @@ static void coresight_disable_helpers(struct coresight= _device *csdev) } } =20 +/* + * Helper function to call source_ops(csdev)->disable and also disable the + * helpers. + * + * There is an imbalance between coresight_enable_path() and + * coresight_disable_path(). Enabling also enables the source's helpers as= part + * of the path, but disabling always skips the first item in the path (whi= ch is + * the source), so sources and their helpers don't get disabled as part of= that + * function and we need the extra step here. + */ +void coresight_disable_source(struct coresight_device *csdev, void *data) +{ + if (source_ops(csdev)->disable) + source_ops(csdev)->disable(csdev, data); + coresight_disable_helpers(csdev); +} +EXPORT_SYMBOL_GPL(coresight_disable_source); + /** - * coresight_disable_source - Drop the reference count by 1 and disable + * coresight_disable_source_sysfs - Drop the reference count by 1 and dis= able * the device if there are no users left. * * @csdev: The coresight device to disable @@ -451,17 +469,15 @@ static void coresight_disable_helpers(struct coresigh= t_device *csdev) * * Returns true if the device has been disabled. */ -bool coresight_disable_source(struct coresight_device *csdev, void *data) +static bool coresight_disable_source_sysfs(struct coresight_device *csdev, + void *data) { if (atomic_dec_return(&csdev->refcnt) =3D=3D 0) { - if (source_ops(csdev)->disable) - source_ops(csdev)->disable(csdev, data); - coresight_disable_helpers(csdev); + coresight_disable_source(csdev, data); csdev->enable =3D false; } return !csdev->enable; } -EXPORT_SYMBOL_GPL(coresight_disable_source); =20 /* * coresight_disable_path_from : Disable components in the given path beyo= nd @@ -1204,7 +1220,7 @@ void coresight_disable(struct coresight_device *csdev) if (ret) goto out; =20 - if (!csdev->enable || !coresight_disable_source(csdev, NULL)) + if (!csdev->enable || !coresight_disable_source_sysfs(csdev, NULL)) goto out; =20 switch (csdev->subtype.source_subtype) { diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwt= racing/coresight/coresight-etm-perf.c index a52cfcce25d6..c0c60e6a1703 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.c +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c @@ -589,7 +589,7 @@ static void etm_event_stop(struct perf_event *event, in= t mode) return; =20 /* stop tracer */ - source_ops(csdev)->disable(csdev, event); + coresight_disable_source(csdev, event); =20 /* tell the core */ event->hw.state =3D PERF_HES_STOPPED; diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtraci= ng/coresight/coresight-priv.h index 767076e07970..30c051055e54 100644 --- a/drivers/hwtracing/coresight/coresight-priv.h +++ b/drivers/hwtracing/coresight/coresight-priv.h @@ -233,6 +233,6 @@ void coresight_set_percpu_sink(int cpu, struct coresigh= t_device *csdev); struct coresight_device *coresight_get_percpu_sink(int cpu); int coresight_enable_source(struct coresight_device *csdev, enum cs_mode m= ode, void *data); -bool coresight_disable_source(struct coresight_device *csdev, void *data); +void coresight_disable_source(struct coresight_device *csdev, void *data); =20 #endif --=20 2.34.1 From nobody Wed Dec 17 05:48:46 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B04D7C4167B for ; Tue, 12 Dec 2023 15:55:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376722AbjLLPzM (ORCPT ); Tue, 12 Dec 2023 10:55:12 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50374 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232917AbjLLPzH (ORCPT ); Tue, 12 Dec 2023 10:55:07 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 001F0100 for ; Tue, 12 Dec 2023 07:55:12 -0800 (PST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 22DEA143D; Tue, 12 Dec 2023 07:55:59 -0800 (PST) Received: from e127643.broadband (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 4E8F43F738; Tue, 12 Dec 2023 07:55:11 -0800 (PST) From: James Clark To: coresight@lists.linaro.org, suzuki.poulose@arm.com Cc: James Clark , Mike Leach , Alexander Shishkin , Maxime Coquelin , Alexandre Torgue , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com Subject: [PATCH 2/8] coresight: Make language around "activated" sinks consistent Date: Tue, 12 Dec 2023 15:53:59 +0000 Message-Id: <20231212155407.1429121-3-james.clark@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231212155407.1429121-1-james.clark@arm.com> References: <20231212155407.1429121-1-james.clark@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Activated has the specific meaning of a sink that's selected for use by the user via sysfs. But comments in some code that's shared by Perf use the same word, so in those cases change them to just say "selected" instead. With selected implying either via Perf or "activated" via sysfs. coresight_get_enabled_sink() doesn't actually get an enabled sink, it only gets an activated one, so change that too. And change the activated variable name to include "sysfs" so it can't be confused as a general status. Signed-off-by: James Clark --- drivers/hwtracing/coresight/coresight-core.c | 51 ++++++++------------ drivers/hwtracing/coresight/coresight-priv.h | 2 - include/linux/coresight.h | 14 +++--- 3 files changed, 27 insertions(+), 40 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtraci= ng/coresight/coresight-core.c index 965bb6d4e1bf..f79aa9ff9b64 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -500,7 +500,7 @@ static void coresight_disable_path_from(struct list_hea= d *path, /* * ETF devices are tricky... They can be a link or a sink, * depending on how they are configured. If an ETF has been - * "activated" it will be configured as a sink, otherwise + * selected as a sink it will be configured as a sink, otherwise * go ahead with the link configuration. */ if (type =3D=3D CORESIGHT_DEV_TYPE_LINKSINK) @@ -578,7 +578,7 @@ int coresight_enable_path(struct list_head *path, enum = cs_mode mode, /* * ETF devices are tricky... They can be a link or a sink, * depending on how they are configured. If an ETF has been - * "activated" it will be configured as a sink, otherwise + * selected as a sink it will be configured as a sink, otherwise * go ahead with the link configuration. */ if (type =3D=3D CORESIGHT_DEV_TYPE_LINKSINK) @@ -635,15 +635,21 @@ struct coresight_device *coresight_get_sink(struct li= st_head *path) return csdev; } =20 +/** + * coresight_find_activated_sysfs_sink - returns the first sink activated = via + * sysfs using connection based search starting from the source reference. + * + * @csdev: Coresight source device reference + */ static struct coresight_device * -coresight_find_enabled_sink(struct coresight_device *csdev) +coresight_find_activated_sysfs_sink(struct coresight_device *csdev) { int i; struct coresight_device *sink =3D NULL; =20 if ((csdev->type =3D=3D CORESIGHT_DEV_TYPE_SINK || csdev->type =3D=3D CORESIGHT_DEV_TYPE_LINKSINK) && - csdev->activated) + csdev->sysfs_sink_activated) return csdev; =20 /* @@ -654,7 +660,7 @@ coresight_find_enabled_sink(struct coresight_device *cs= dev) =20 child_dev =3D csdev->pdata->out_conns[i]->dest_dev; if (child_dev) - sink =3D coresight_find_enabled_sink(child_dev); + sink =3D coresight_find_activated_sysfs_sink(child_dev); if (sink) return sink; } @@ -662,21 +668,6 @@ coresight_find_enabled_sink(struct coresight_device *c= sdev) return NULL; } =20 -/** - * coresight_get_enabled_sink - returns the first enabled sink using - * connection based search starting from the source reference - * - * @source: Coresight source device reference - */ -struct coresight_device * -coresight_get_enabled_sink(struct coresight_device *source) -{ - if (!source) - return NULL; - - return coresight_find_enabled_sink(source); -} - static int coresight_sink_by_id(struct device *dev, const void *data) { struct coresight_device *csdev =3D to_coresight_device(dev); @@ -810,11 +801,10 @@ static void coresight_drop_device(struct coresight_de= vice *csdev) * @sink: The final sink we want in this path. * @path: The list to add devices to. * - * The tree of Coresight device is traversed until an activated sink is - * found. From there the sink is added to the list along with all the - * devices that led to that point - the end result is a list from source - * to sink. In that list the source is the first device and the sink the - * last one. + * The tree of Coresight device is traversed until the selected sink is fo= und. + * From there the sink is added to the list along with all the devices tha= t led + * to that point - the end result is a list from source to sink. In that l= ist + * the source is the first device and the sink the last one. */ static int _coresight_build_path(struct coresight_device *csdev, struct coresight_device *sink, @@ -824,7 +814,7 @@ static int _coresight_build_path(struct coresight_devic= e *csdev, bool found =3D false; struct coresight_node *node; =20 - /* An activated sink has been found. Enqueue the element */ + /* The selected sink has been found. Enqueue the element */ if (csdev =3D=3D sink) goto out; =20 @@ -1145,7 +1135,7 @@ int coresight_enable(struct coresight_device *csdev) goto out; } =20 - sink =3D coresight_get_enabled_sink(csdev); + sink =3D coresight_find_activated_sysfs_sink(csdev); if (!sink) { ret =3D -EINVAL; goto out; @@ -1259,7 +1249,7 @@ static ssize_t enable_sink_show(struct device *dev, { struct coresight_device *csdev =3D to_coresight_device(dev); =20 - return scnprintf(buf, PAGE_SIZE, "%u\n", csdev->activated); + return scnprintf(buf, PAGE_SIZE, "%u\n", csdev->sysfs_sink_activated); } =20 static ssize_t enable_sink_store(struct device *dev, @@ -1274,10 +1264,7 @@ static ssize_t enable_sink_store(struct device *dev, if (ret) return ret; =20 - if (val) - csdev->activated =3D true; - else - csdev->activated =3D false; + csdev->sysfs_sink_activated =3D !!val; =20 return size; =20 diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtraci= ng/coresight/coresight-priv.h index 30c051055e54..ced5be05a527 100644 --- a/drivers/hwtracing/coresight/coresight-priv.h +++ b/drivers/hwtracing/coresight/coresight-priv.h @@ -130,8 +130,6 @@ void coresight_disable_path(struct list_head *path); int coresight_enable_path(struct list_head *path, enum cs_mode mode, void *sink_data); struct coresight_device *coresight_get_sink(struct list_head *path); -struct coresight_device * -coresight_get_enabled_sink(struct coresight_device *source); struct coresight_device *coresight_get_sink_by_id(u32 id); struct coresight_device * coresight_find_default_sink(struct coresight_device *csdev); diff --git a/include/linux/coresight.h b/include/linux/coresight.h index a4cb7dd6ca23..65131bfbd904 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -229,10 +229,12 @@ struct coresight_sysfs_link { * @refcnt: keep track of what is in use. * @orphan: true if the component has connections that haven't been linked. * @enable: 'true' if component is currently part of an active path. - * @activated: 'true' only if a _sink_ has been activated. A sink can be - * activated but not yet enabled. Enabling for a _sink_ - * happens when a source has been selected and a path is enabled - * from source to that sink. + * @sysfs_sink_activated: 'true' when a sink has been selected for use via= sysfs + * by writing a 1 to the 'enable_sink' file. A sink can be + * activated but not yet enabled. Enabling for a _sink_ happens + * when a source has been selected and a path is enabled from + * source to that sink. A sink can also become enabled but not + * activated if it's used via Perf. * @ea: Device attribute for sink representation under PMU directory. * @def_sink: cached reference to default sink found for this device. * @nr_links: number of sysfs links created to other components from this @@ -252,9 +254,9 @@ struct coresight_device { struct device dev; atomic_t refcnt; bool orphan; - bool enable; /* true only if configured as part of a path */ + bool enable; /* sink specific fields */ - bool activated; /* true only if a sink is part of a path */ + bool sysfs_sink_activated; struct dev_ext_attribute *ea; struct coresight_device *def_sink; /* sysfs links between components */ --=20 2.34.1 From nobody Wed Dec 17 05:48:46 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 955E9C4332F for ; Tue, 12 Dec 2023 15:55:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235073AbjLLPz0 (ORCPT ); Tue, 12 Dec 2023 10:55:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37110 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1376735AbjLLPzN (ORCPT ); Tue, 12 Dec 2023 10:55:13 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 0D95712F for ; Tue, 12 Dec 2023 07:55:17 -0800 (PST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 05E23143D; Tue, 12 Dec 2023 07:56:03 -0800 (PST) Received: from e127643.broadband (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 322E13F738; Tue, 12 Dec 2023 07:55:15 -0800 (PST) From: James Clark To: coresight@lists.linaro.org, suzuki.poulose@arm.com Cc: James Clark , Mike Leach , Alexander Shishkin , Maxime Coquelin , Alexandre Torgue , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com Subject: [PATCH 3/8] coresight: Remove ops callback checks Date: Tue, 12 Dec 2023 15:54:00 +0000 Message-Id: <20231212155407.1429121-4-james.clark@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231212155407.1429121-1-james.clark@arm.com> References: <20231212155407.1429121-1-james.clark@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The check for the existence of callbacks before using them implies that this happens and is supported. There are no devices without enable/disable callbacks, and it wouldn't be possible to add a new working device without adding them either, so just remove them. Furthermore, there are more callbacks than just enable and disable that are already used unguarded in other places. The comment about new session compatibility doesn't seem to match up to the line of code that it's on so remove it. I think it's alluding to the fact that sinks will check if they were already enabled via sysfs or Perf and fail the enable. But there are more detailed comments at those places, and this one isn't very useful. Signed-off-by: James Clark --- drivers/hwtracing/coresight/coresight-core.c | 51 +++++--------------- 1 file changed, 12 insertions(+), 39 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtraci= ng/coresight/coresight-core.c index f79aa9ff9b64..ab226441e5f4 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -279,16 +279,8 @@ EXPORT_SYMBOL_GPL(coresight_add_helper); static int coresight_enable_sink(struct coresight_device *csdev, enum cs_mode mode, void *data) { - int ret; - - /* - * We need to make sure the "new" session is compatible with the - * existing "mode" of operation. - */ - if (!sink_ops(csdev)->enable) - return -EINVAL; + int ret =3D sink_ops(csdev)->enable(csdev, mode, data); =20 - ret =3D sink_ops(csdev)->enable(csdev, mode, data); if (ret) return ret; =20 @@ -299,12 +291,7 @@ static int coresight_enable_sink(struct coresight_devi= ce *csdev, =20 static void coresight_disable_sink(struct coresight_device *csdev) { - int ret; - - if (!sink_ops(csdev)->disable) - return; - - ret =3D sink_ops(csdev)->disable(csdev); + int ret =3D sink_ops(csdev)->disable(csdev); if (ret) return; csdev->enable =3D false; @@ -330,11 +317,9 @@ static int coresight_enable_link(struct coresight_devi= ce *csdev, if (link_subtype =3D=3D CORESIGHT_DEV_SUBTYPE_LINK_SPLIT && IS_ERR(outcon= n)) return PTR_ERR(outconn); =20 - if (link_ops(csdev)->enable) { - ret =3D link_ops(csdev)->enable(csdev, inconn, outconn); - if (!ret) - csdev->enable =3D true; - } + ret =3D link_ops(csdev)->enable(csdev, inconn, outconn); + if (!ret) + csdev->enable =3D true; =20 return ret; } @@ -354,9 +339,7 @@ static void coresight_disable_link(struct coresight_dev= ice *csdev, outconn =3D coresight_find_out_connection(csdev, child); link_subtype =3D csdev->subtype.link_subtype; =20 - if (link_ops(csdev)->disable) { - link_ops(csdev)->disable(csdev, inconn, outconn); - } + link_ops(csdev)->disable(csdev, inconn, outconn); =20 if (link_subtype =3D=3D CORESIGHT_DEV_SUBTYPE_LINK_MERG) { for (i =3D 0; i < csdev->pdata->nr_inconns; i++) @@ -382,11 +365,9 @@ int coresight_enable_source(struct coresight_device *c= sdev, enum cs_mode mode, int ret; =20 if (!csdev->enable) { - if (source_ops(csdev)->enable) { - ret =3D source_ops(csdev)->enable(csdev, data, mode); - if (ret) - return ret; - } + ret =3D source_ops(csdev)->enable(csdev, data, mode); + if (ret) + return ret; csdev->enable =3D true; } =20 @@ -404,11 +385,8 @@ static bool coresight_is_helper(struct coresight_devic= e *csdev) static int coresight_enable_helper(struct coresight_device *csdev, enum cs_mode mode, void *data) { - int ret; + int ret =3D helper_ops(csdev)->enable(csdev, mode, data); =20 - if (!helper_ops(csdev)->enable) - return 0; - ret =3D helper_ops(csdev)->enable(csdev, mode, data); if (ret) return ret; =20 @@ -418,12 +396,8 @@ static int coresight_enable_helper(struct coresight_de= vice *csdev, =20 static void coresight_disable_helper(struct coresight_device *csdev) { - int ret; - - if (!helper_ops(csdev)->disable) - return; + int ret =3D helper_ops(csdev)->disable(csdev, NULL); =20 - ret =3D helper_ops(csdev)->disable(csdev, NULL); if (ret) return; csdev->enable =3D false; @@ -453,8 +427,7 @@ static void coresight_disable_helpers(struct coresight_= device *csdev) */ void coresight_disable_source(struct coresight_device *csdev, void *data) { - if (source_ops(csdev)->disable) - source_ops(csdev)->disable(csdev, data); + source_ops(csdev)->disable(csdev, data); coresight_disable_helpers(csdev); } EXPORT_SYMBOL_GPL(coresight_disable_source); --=20 2.34.1 From nobody Wed Dec 17 05:48:46 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 353F6C4332F for ; Tue, 12 Dec 2023 16:16:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377205AbjLLP4N (ORCPT ); Tue, 12 Dec 2023 10:56:13 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37358 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1376611AbjLLPzV (ORCPT ); Tue, 12 Dec 2023 10:55:21 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 1A80C181 for ; Tue, 12 Dec 2023 07:55:21 -0800 (PST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 39AB8143D; Tue, 12 Dec 2023 07:56:07 -0800 (PST) Received: from e127643.broadband (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 484433F738; Tue, 12 Dec 2023 07:55:19 -0800 (PST) From: James Clark To: coresight@lists.linaro.org, suzuki.poulose@arm.com Cc: James Clark , Mike Leach , Alexander Shishkin , Maxime Coquelin , Alexandre Torgue , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com Subject: [PATCH 4/8] coresight: Move mode to struct coresight_device Date: Tue, 12 Dec 2023 15:54:01 +0000 Message-Id: <20231212155407.1429121-5-james.clark@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231212155407.1429121-1-james.clark@arm.com> References: <20231212155407.1429121-1-james.clark@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Most devices use mode, so move the mode definition out of the individual devices and up to the Coresight device. This will allow the core code to also know the mode which will be useful in a later commit. This also fixes the inconsistency of the documentation of the mode field on the individual device types. For example ETB10 had "this ETB is being used". Two devices didn't require an atomic mode type, so these usages have been converted to atomic_get() and atomic_set() only to make it compile, but the documentation of the field in struct coresight_device explains this type of usage. In the future, manipulation of the mode could be completely moved out of the individual devices and into the core code because it's almost all duplicate code, and this change is a step towards that. Signed-off-by: James Clark --- drivers/hwtracing/coresight/coresight-etb10.c | 18 ++++++------- drivers/hwtracing/coresight/coresight-etm.h | 2 -- .../coresight/coresight-etm3x-core.c | 13 +++++----- .../coresight/coresight-etm3x-sysfs.c | 4 +-- drivers/hwtracing/coresight/coresight-stm.c | 20 +++++++------- .../hwtracing/coresight/coresight-tmc-core.c | 2 +- .../hwtracing/coresight/coresight-tmc-etf.c | 26 +++++++++---------- .../hwtracing/coresight/coresight-tmc-etr.c | 20 +++++++------- drivers/hwtracing/coresight/coresight-tmc.h | 2 -- drivers/hwtracing/coresight/ultrasoc-smb.c | 13 +++++----- drivers/hwtracing/coresight/ultrasoc-smb.h | 2 -- include/linux/coresight.h | 6 +++++ 12 files changed, 62 insertions(+), 66 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtrac= ing/coresight/coresight-etb10.c index fa80039e0821..08e5bba862db 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -76,7 +76,6 @@ DEFINE_CORESIGHT_DEVLIST(etb_devs, "etb"); * @pid: Process ID of the process being monitored by the session * that is using this component. * @buf: area of memory where ETB buffer content gets sent. - * @mode: this ETB is being used. * @buffer_depth: size of @buf. * @trigger_cntr: amount of words to store after a trigger. */ @@ -89,7 +88,6 @@ struct etb_drvdata { local_t reading; pid_t pid; u8 *buf; - u32 mode; u32 buffer_depth; u32 trigger_cntr; }; @@ -150,17 +148,17 @@ static int etb_enable_sysfs(struct coresight_device *= csdev) spin_lock_irqsave(&drvdata->spinlock, flags); =20 /* Don't messup with perf sessions. */ - if (drvdata->mode =3D=3D CS_MODE_PERF) { + if (local_read(&csdev->mode) =3D=3D CS_MODE_PERF) { ret =3D -EBUSY; goto out; } =20 - if (drvdata->mode =3D=3D CS_MODE_DISABLED) { + if (local_read(&csdev->mode) =3D=3D CS_MODE_DISABLED) { ret =3D etb_enable_hw(drvdata); if (ret) goto out; =20 - drvdata->mode =3D CS_MODE_SYSFS; + local_set(&csdev->mode, CS_MODE_SYSFS); } =20 atomic_inc(&csdev->refcnt); @@ -181,7 +179,7 @@ static int etb_enable_perf(struct coresight_device *csd= ev, void *data) spin_lock_irqsave(&drvdata->spinlock, flags); =20 /* No need to continue if the component is already in used by sysFS. */ - if (drvdata->mode =3D=3D CS_MODE_SYSFS) { + if (local_read(&drvdata->csdev->mode) =3D=3D CS_MODE_SYSFS) { ret =3D -EBUSY; goto out; } @@ -216,7 +214,7 @@ static int etb_enable_perf(struct coresight_device *csd= ev, void *data) if (!ret) { /* Associate with monitored process. */ drvdata->pid =3D pid; - drvdata->mode =3D CS_MODE_PERF; + local_set(&drvdata->csdev->mode, CS_MODE_PERF); atomic_inc(&csdev->refcnt); } =20 @@ -362,11 +360,11 @@ static int etb_disable(struct coresight_device *csdev) } =20 /* Complain if we (somehow) got out of sync */ - WARN_ON_ONCE(drvdata->mode =3D=3D CS_MODE_DISABLED); + WARN_ON_ONCE(local_read(&csdev->mode) =3D=3D CS_MODE_DISABLED); etb_disable_hw(drvdata); /* Dissociate from monitored process. */ drvdata->pid =3D -1; - drvdata->mode =3D CS_MODE_DISABLED; + local_set(&csdev->mode, CS_MODE_DISABLED); spin_unlock_irqrestore(&drvdata->spinlock, flags); =20 dev_dbg(&csdev->dev, "ETB disabled\n"); @@ -589,7 +587,7 @@ static void etb_dump(struct etb_drvdata *drvdata) unsigned long flags; =20 spin_lock_irqsave(&drvdata->spinlock, flags); - if (drvdata->mode =3D=3D CS_MODE_SYSFS) { + if (local_read(&drvdata->csdev->mode) =3D=3D CS_MODE_SYSFS) { __etb_disable_hw(drvdata); etb_dump_hw(drvdata); __etb_enable_hw(drvdata); diff --git a/drivers/hwtracing/coresight/coresight-etm.h b/drivers/hwtracin= g/coresight/coresight-etm.h index 9a0d08b092ae..e02c3ea972c9 100644 --- a/drivers/hwtracing/coresight/coresight-etm.h +++ b/drivers/hwtracing/coresight/coresight-etm.h @@ -215,7 +215,6 @@ struct etm_config { * @port_size: port size as reported by ETMCR bit 4-6 and 21. * @arch: ETM/PTM version number. * @use_cpu14: true if management registers need to be accessed via CP14. - * @mode: this tracer's mode, i.e sysFS, Perf or disabled. * @sticky_enable: true if ETM base configuration has been done. * @boot_enable:true if we should start tracing at boot time. * @os_unlock: true if access to management registers is allowed. @@ -238,7 +237,6 @@ struct etm_drvdata { int port_size; u8 arch; bool use_cp14; - local_t mode; bool sticky_enable; bool boot_enable; bool os_unlock; diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/h= wtracing/coresight/coresight-etm3x-core.c index 116a91d90ac2..29f62dfac673 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c @@ -559,7 +559,7 @@ static int etm_enable(struct coresight_device *csdev, s= truct perf_event *event, u32 val; struct etm_drvdata *drvdata =3D dev_get_drvdata(csdev->dev.parent); =20 - val =3D local_cmpxchg(&drvdata->mode, CS_MODE_DISABLED, mode); + val =3D local_cmpxchg(&drvdata->csdev->mode, CS_MODE_DISABLED, mode); =20 /* Someone is already using the tracer */ if (val) @@ -578,7 +578,7 @@ static int etm_enable(struct coresight_device *csdev, s= truct perf_event *event, =20 /* The tracer didn't start */ if (ret) - local_set(&drvdata->mode, CS_MODE_DISABLED); + local_set(&drvdata->csdev->mode, CS_MODE_DISABLED); =20 return ret; } @@ -672,14 +672,13 @@ static void etm_disable(struct coresight_device *csde= v, struct perf_event *event) { enum cs_mode mode; - struct etm_drvdata *drvdata =3D dev_get_drvdata(csdev->dev.parent); =20 /* * For as long as the tracer isn't disabled another entity can't * change its status. As such we can read the status here without * fearing it will change under us. */ - mode =3D local_read(&drvdata->mode); + mode =3D local_read(&csdev->mode); =20 switch (mode) { case CS_MODE_DISABLED: @@ -696,7 +695,7 @@ static void etm_disable(struct coresight_device *csdev, } =20 if (mode) - local_set(&drvdata->mode, CS_MODE_DISABLED); + local_set(&csdev->mode, CS_MODE_DISABLED); } =20 static const struct coresight_ops_source etm_source_ops =3D { @@ -730,7 +729,7 @@ static int etm_starting_cpu(unsigned int cpu) etmdrvdata[cpu]->os_unlock =3D true; } =20 - if (local_read(&etmdrvdata[cpu]->mode)) + if (local_read(&etmdrvdata[cpu]->csdev->mode)) etm_enable_hw(etmdrvdata[cpu]); spin_unlock(&etmdrvdata[cpu]->spinlock); return 0; @@ -742,7 +741,7 @@ static int etm_dying_cpu(unsigned int cpu) return 0; =20 spin_lock(&etmdrvdata[cpu]->spinlock); - if (local_read(&etmdrvdata[cpu]->mode)) + if (local_read(&etmdrvdata[cpu]->csdev->mode)) etm_disable_hw(etmdrvdata[cpu]); spin_unlock(&etmdrvdata[cpu]->spinlock); return 0; diff --git a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c b/drivers/= hwtracing/coresight/coresight-etm3x-sysfs.c index 2f271b7fb048..6c8429c980b1 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c @@ -722,7 +722,7 @@ static ssize_t cntr_val_show(struct device *dev, struct etm_drvdata *drvdata =3D dev_get_drvdata(dev->parent); struct etm_config *config =3D &drvdata->config; =20 - if (!local_read(&drvdata->mode)) { + if (!local_read(&drvdata->csdev->mode)) { spin_lock(&drvdata->spinlock); for (i =3D 0; i < drvdata->nr_cntr; i++) ret +=3D sprintf(buf, "counter %d: %x\n", @@ -941,7 +941,7 @@ static ssize_t seq_curr_state_show(struct device *dev, struct etm_drvdata *drvdata =3D dev_get_drvdata(dev->parent); struct etm_config *config =3D &drvdata->config; =20 - if (!local_read(&drvdata->mode)) { + if (!local_read(&drvdata->csdev->mode)) { val =3D config->seq_curr_state; goto out; } diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracin= g/coresight/coresight-stm.c index a1c27c901ad1..190ba569b05a 100644 --- a/drivers/hwtracing/coresight/coresight-stm.c +++ b/drivers/hwtracing/coresight/coresight-stm.c @@ -119,7 +119,6 @@ DEFINE_CORESIGHT_DEVLIST(stm_devs, "stm"); * @spinlock: only one at a time pls. * @chs: the channels accociated to this STM. * @stm: structure associated to the generic STM interface. - * @mode: this tracer's mode (enum cs_mode), i.e sysFS, or disabled. * @traceid: value of the current ID for this component. * @write_bytes: Maximus bytes this STM can write at a time. * @stmsper: settings for register STMSPER. @@ -136,7 +135,6 @@ struct stm_drvdata { spinlock_t spinlock; struct channel_space chs; struct stm_data stm; - local_t mode; u8 traceid; u32 write_bytes; u32 stmsper; @@ -201,7 +199,7 @@ static int stm_enable(struct coresight_device *csdev, s= truct perf_event *event, if (mode !=3D CS_MODE_SYSFS) return -EINVAL; =20 - val =3D local_cmpxchg(&drvdata->mode, CS_MODE_DISABLED, mode); + val =3D local_cmpxchg(&csdev->mode, CS_MODE_DISABLED, mode); =20 /* Someone is already using the tracer */ if (val) @@ -266,7 +264,7 @@ static void stm_disable(struct coresight_device *csdev, * change its status. As such we can read the status here without * fearing it will change under us. */ - if (local_read(&drvdata->mode) =3D=3D CS_MODE_SYSFS) { + if (local_read(&csdev->mode) =3D=3D CS_MODE_SYSFS) { spin_lock(&drvdata->spinlock); stm_disable_hw(drvdata); spin_unlock(&drvdata->spinlock); @@ -276,7 +274,7 @@ static void stm_disable(struct coresight_device *csdev, =20 pm_runtime_put(csdev->dev.parent); =20 - local_set(&drvdata->mode, CS_MODE_DISABLED); + local_set(&csdev->mode, CS_MODE_DISABLED); dev_dbg(&csdev->dev, "STM tracing disabled\n"); } } @@ -373,7 +371,7 @@ static long stm_generic_set_options(struct stm_data *st= m_data, { struct stm_drvdata *drvdata =3D container_of(stm_data, struct stm_drvdata, stm); - if (!(drvdata && local_read(&drvdata->mode))) + if (!(drvdata && local_read(&drvdata->csdev->mode))) return -EINVAL; =20 if (channel >=3D drvdata->numsp) @@ -408,7 +406,7 @@ static ssize_t notrace stm_generic_packet(struct stm_da= ta *stm_data, struct stm_drvdata, stm); unsigned int stm_flags; =20 - if (!(drvdata && local_read(&drvdata->mode))) + if (!(drvdata && local_read(&drvdata->csdev->mode))) return -EACCES; =20 if (channel >=3D drvdata->numsp) @@ -515,7 +513,7 @@ static ssize_t port_select_show(struct device *dev, struct stm_drvdata *drvdata =3D dev_get_drvdata(dev->parent); unsigned long val; =20 - if (!local_read(&drvdata->mode)) { + if (!local_read(&drvdata->csdev->mode)) { val =3D drvdata->stmspscr; } else { spin_lock(&drvdata->spinlock); @@ -541,7 +539,7 @@ static ssize_t port_select_store(struct device *dev, spin_lock(&drvdata->spinlock); drvdata->stmspscr =3D val; =20 - if (local_read(&drvdata->mode)) { + if (local_read(&drvdata->csdev->mode)) { CS_UNLOCK(drvdata->base); /* Process as per ARM's TRM recommendation */ stmsper =3D readl_relaxed(drvdata->base + STMSPER); @@ -562,7 +560,7 @@ static ssize_t port_enable_show(struct device *dev, struct stm_drvdata *drvdata =3D dev_get_drvdata(dev->parent); unsigned long val; =20 - if (!local_read(&drvdata->mode)) { + if (!local_read(&drvdata->csdev->mode)) { val =3D drvdata->stmsper; } else { spin_lock(&drvdata->spinlock); @@ -588,7 +586,7 @@ static ssize_t port_enable_store(struct device *dev, spin_lock(&drvdata->spinlock); drvdata->stmsper =3D val; =20 - if (local_read(&drvdata->mode)) { + if (local_read(&drvdata->csdev->mode)) { CS_UNLOCK(drvdata->base); writel_relaxed(drvdata->stmsper, drvdata->base + STMSPER); CS_LOCK(drvdata->base); diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwt= racing/coresight/coresight-tmc-core.c index 7ec5365e2b64..e5d47f61f9f3 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-core.c +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c @@ -558,7 +558,7 @@ static void tmc_shutdown(struct amba_device *adev) =20 spin_lock_irqsave(&drvdata->spinlock, flags); =20 - if (drvdata->mode =3D=3D CS_MODE_DISABLED) + if (local_read(&drvdata->csdev->mode) =3D=3D CS_MODE_DISABLED) goto out; =20 if (drvdata->config_type =3D=3D TMC_CONFIG_TYPE_ETR) diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtr= acing/coresight/coresight-tmc-etf.c index 7406b65e2cdd..2a7e516052a2 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c @@ -89,7 +89,7 @@ static void __tmc_etb_disable_hw(struct tmc_drvdata *drvd= ata) * When operating in sysFS mode the content of the buffer needs to be * read before the TMC is disabled. */ - if (drvdata->mode =3D=3D CS_MODE_SYSFS) + if (local_read(&drvdata->csdev->mode) =3D=3D CS_MODE_SYSFS) tmc_etb_dump_hw(drvdata); tmc_disable_hw(drvdata); =20 @@ -205,7 +205,7 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_d= evice *csdev) * sink is already enabled no memory is needed and the HW need not be * touched. */ - if (drvdata->mode =3D=3D CS_MODE_SYSFS) { + if (local_read(&csdev->mode) =3D=3D CS_MODE_SYSFS) { atomic_inc(&csdev->refcnt); goto out; } @@ -228,7 +228,7 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_d= evice *csdev) =20 ret =3D tmc_etb_enable_hw(drvdata); if (!ret) { - drvdata->mode =3D CS_MODE_SYSFS; + local_set(&csdev->mode, CS_MODE_SYSFS); atomic_inc(&csdev->refcnt); } else { /* Free up the buffer if we failed to enable */ @@ -262,7 +262,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_de= vice *csdev, void *data) * No need to continue if the ETB/ETF is already operated * from sysFS. */ - if (drvdata->mode =3D=3D CS_MODE_SYSFS) { + if (local_read(&csdev->mode) =3D=3D CS_MODE_SYSFS) { ret =3D -EBUSY; break; } @@ -292,7 +292,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_de= vice *csdev, void *data) if (!ret) { /* Associate with monitored process. */ drvdata->pid =3D pid; - drvdata->mode =3D CS_MODE_PERF; + local_set(&csdev->mode, CS_MODE_PERF); atomic_inc(&csdev->refcnt); } } while (0); @@ -344,11 +344,11 @@ static int tmc_disable_etf_sink(struct coresight_devi= ce *csdev) } =20 /* Complain if we (somehow) got out of sync */ - WARN_ON_ONCE(drvdata->mode =3D=3D CS_MODE_DISABLED); + WARN_ON_ONCE(local_read(&csdev->mode) =3D=3D CS_MODE_DISABLED); tmc_etb_disable_hw(drvdata); /* Dissociate from monitored process. */ drvdata->pid =3D -1; - drvdata->mode =3D CS_MODE_DISABLED; + local_set(&csdev->mode, CS_MODE_DISABLED); =20 spin_unlock_irqrestore(&drvdata->spinlock, flags); =20 @@ -374,7 +374,7 @@ static int tmc_enable_etf_link(struct coresight_device = *csdev, if (atomic_read(&csdev->refcnt) =3D=3D 0) { ret =3D tmc_etf_enable_hw(drvdata); if (!ret) { - drvdata->mode =3D CS_MODE_SYSFS; + local_set(&csdev->mode, CS_MODE_SYSFS); first_enable =3D true; } } @@ -403,7 +403,7 @@ static void tmc_disable_etf_link(struct coresight_devic= e *csdev, =20 if (atomic_dec_return(&csdev->refcnt) =3D=3D 0) { tmc_etf_disable_hw(drvdata); - drvdata->mode =3D CS_MODE_DISABLED; + local_set(&csdev->mode, CS_MODE_DISABLED); last_disable =3D true; } spin_unlock_irqrestore(&drvdata->spinlock, flags); @@ -483,7 +483,7 @@ static unsigned long tmc_update_etf_buffer(struct cores= ight_device *csdev, return 0; =20 /* This shouldn't happen */ - if (WARN_ON_ONCE(drvdata->mode !=3D CS_MODE_PERF)) + if (WARN_ON_ONCE(local_read(&csdev->mode) !=3D CS_MODE_PERF)) return 0; =20 spin_lock_irqsave(&drvdata->spinlock, flags); @@ -629,7 +629,7 @@ int tmc_read_prepare_etb(struct tmc_drvdata *drvdata) } =20 /* Don't interfere if operated from Perf */ - if (drvdata->mode =3D=3D CS_MODE_PERF) { + if (local_read(&drvdata->csdev->mode) =3D=3D CS_MODE_PERF) { ret =3D -EINVAL; goto out; } @@ -641,7 +641,7 @@ int tmc_read_prepare_etb(struct tmc_drvdata *drvdata) } =20 /* Disable the TMC if need be */ - if (drvdata->mode =3D=3D CS_MODE_SYSFS) { + if (local_read(&drvdata->csdev->mode) =3D=3D CS_MODE_SYSFS) { /* There is no point in reading a TMC in HW FIFO mode */ mode =3D readl_relaxed(drvdata->base + TMC_MODE); if (mode !=3D TMC_MODE_CIRCULAR_BUFFER) { @@ -673,7 +673,7 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata) spin_lock_irqsave(&drvdata->spinlock, flags); =20 /* Re-enable the TMC if need be */ - if (drvdata->mode =3D=3D CS_MODE_SYSFS) { + if (local_read(&drvdata->csdev->mode) =3D=3D CS_MODE_SYSFS) { /* There is no point in reading a TMC in HW FIFO mode */ mode =3D readl_relaxed(drvdata->base + TMC_MODE); if (mode !=3D TMC_MODE_CIRCULAR_BUFFER) { diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtr= acing/coresight/coresight-tmc-etr.c index af02ba5d5f15..3dc989d4fcab 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -1143,7 +1143,7 @@ static void __tmc_etr_disable_hw(struct tmc_drvdata *= drvdata) * When operating in sysFS mode the content of the buffer needs to be * read before the TMC is disabled. */ - if (drvdata->mode =3D=3D CS_MODE_SYSFS) + if (local_read(&drvdata->csdev->mode) =3D=3D CS_MODE_SYSFS) tmc_etr_sync_sysfs_buf(drvdata); =20 tmc_disable_hw(drvdata); @@ -1189,7 +1189,7 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struc= t coresight_device *csdev) spin_lock_irqsave(&drvdata->spinlock, flags); } =20 - if (drvdata->reading || drvdata->mode =3D=3D CS_MODE_PERF) { + if (drvdata->reading || local_read(&csdev->mode) =3D=3D CS_MODE_PERF) { ret =3D -EBUSY; goto out; } @@ -1230,14 +1230,14 @@ static int tmc_enable_etr_sink_sysfs(struct coresig= ht_device *csdev) * sink is already enabled no memory is needed and the HW need not be * touched, even if the buffer size has changed. */ - if (drvdata->mode =3D=3D CS_MODE_SYSFS) { + if (local_read(&csdev->mode) =3D=3D CS_MODE_SYSFS) { atomic_inc(&csdev->refcnt); goto out; } =20 ret =3D tmc_etr_enable_hw(drvdata, sysfs_buf); if (!ret) { - drvdata->mode =3D CS_MODE_SYSFS; + local_set(&csdev->mode, CS_MODE_SYSFS); atomic_inc(&csdev->refcnt); } =20 @@ -1652,7 +1652,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_= device *csdev, void *data) =20 spin_lock_irqsave(&drvdata->spinlock, flags); /* Don't use this sink if it is already claimed by sysFS */ - if (drvdata->mode =3D=3D CS_MODE_SYSFS) { + if (local_read(&csdev->mode) =3D=3D CS_MODE_SYSFS) { rc =3D -EBUSY; goto unlock_out; } @@ -1684,7 +1684,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_= device *csdev, void *data) if (!rc) { /* Associate with monitored process. */ drvdata->pid =3D pid; - drvdata->mode =3D CS_MODE_PERF; + local_set(&csdev->mode, CS_MODE_PERF); drvdata->perf_buf =3D etr_perf->etr_buf; atomic_inc(&csdev->refcnt); } @@ -1725,11 +1725,11 @@ static int tmc_disable_etr_sink(struct coresight_de= vice *csdev) } =20 /* Complain if we (somehow) got out of sync */ - WARN_ON_ONCE(drvdata->mode =3D=3D CS_MODE_DISABLED); + WARN_ON_ONCE(local_read(&csdev->mode) =3D=3D CS_MODE_DISABLED); tmc_etr_disable_hw(drvdata); /* Dissociate from monitored process. */ drvdata->pid =3D -1; - drvdata->mode =3D CS_MODE_DISABLED; + local_set(&csdev->mode, CS_MODE_DISABLED); /* Reset perf specific data */ drvdata->perf_buf =3D NULL; =20 @@ -1777,7 +1777,7 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata) } =20 /* Disable the TMC if we are trying to read from a running session. */ - if (drvdata->mode =3D=3D CS_MODE_SYSFS) + if (local_read(&drvdata->csdev->mode) =3D=3D CS_MODE_SYSFS) __tmc_etr_disable_hw(drvdata); =20 drvdata->reading =3D true; @@ -1799,7 +1799,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdat= a) spin_lock_irqsave(&drvdata->spinlock, flags); =20 /* RE-enable the TMC if need be */ - if (drvdata->mode =3D=3D CS_MODE_SYSFS) { + if (local_read(&drvdata->csdev->mode) =3D=3D CS_MODE_SYSFS) { /* * The trace run will continue with the same allocated trace * buffer. Since the tracer is still enabled drvdata::buf can't diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracin= g/coresight/coresight-tmc.h index 8dcb426ac3e7..cef979c897e6 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -178,7 +178,6 @@ struct etr_buf { * @size: trace buffer size for this TMC (common for all modes). * @max_burst_size: The maximum burst size that can be initiated by * TMC-ETR on AXI bus. - * @mode: how this TMC is being used. * @config_type: TMC variant, must be of type @tmc_config_type. * @memwidth: width of the memory interface databus, in bytes. * @trigger_cntr: amount of words to store after a trigger. @@ -203,7 +202,6 @@ struct tmc_drvdata { u32 len; u32 size; u32 max_burst_size; - u32 mode; enum tmc_config_type config_type; enum tmc_mem_intf_width memwidth; u32 trigger_cntr; diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.c b/drivers/hwtracing= /coresight/ultrasoc-smb.c index 10e886455b8b..1a8c64645b92 100644 --- a/drivers/hwtracing/coresight/ultrasoc-smb.c +++ b/drivers/hwtracing/coresight/ultrasoc-smb.c @@ -207,11 +207,11 @@ static void smb_enable_sysfs(struct coresight_device = *csdev) { struct smb_drv_data *drvdata =3D dev_get_drvdata(csdev->dev.parent); =20 - if (drvdata->mode !=3D CS_MODE_DISABLED) + if (local_read(&csdev->mode) !=3D CS_MODE_DISABLED) return; =20 smb_enable_hw(drvdata); - drvdata->mode =3D CS_MODE_SYSFS; + local_set(&csdev->mode, CS_MODE_SYSFS); } =20 static int smb_enable_perf(struct coresight_device *csdev, void *data) @@ -234,7 +234,7 @@ static int smb_enable_perf(struct coresight_device *csd= ev, void *data) if (drvdata->pid =3D=3D -1) { smb_enable_hw(drvdata); drvdata->pid =3D pid; - drvdata->mode =3D CS_MODE_PERF; + local_set(&csdev->mode, CS_MODE_PERF); } =20 return 0; @@ -253,7 +253,8 @@ static int smb_enable(struct coresight_device *csdev, e= num cs_mode mode, return -EBUSY; =20 /* Do nothing, the SMB is already enabled as other mode */ - if (drvdata->mode !=3D CS_MODE_DISABLED && drvdata->mode !=3D mode) + if (local_read(&csdev->mode) !=3D CS_MODE_DISABLED && + local_read(&csdev->mode) !=3D mode) return -EBUSY; =20 switch (mode) { @@ -289,13 +290,13 @@ static int smb_disable(struct coresight_device *csdev) return -EBUSY; =20 /* Complain if we (somehow) got out of sync */ - WARN_ON_ONCE(drvdata->mode =3D=3D CS_MODE_DISABLED); + WARN_ON_ONCE(local_read(&csdev->mode) =3D=3D CS_MODE_DISABLED); =20 smb_disable_hw(drvdata); =20 /* Dissociate from the target process. */ drvdata->pid =3D -1; - drvdata->mode =3D CS_MODE_DISABLED; + local_set(&csdev->mode, CS_MODE_DISABLED); dev_dbg(&csdev->dev, "Ultrasoc SMB disabled\n"); =20 return 0; diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.h b/drivers/hwtracing= /coresight/ultrasoc-smb.h index 82a44c14a882..a91d39cfccb8 100644 --- a/drivers/hwtracing/coresight/ultrasoc-smb.h +++ b/drivers/hwtracing/coresight/ultrasoc-smb.h @@ -109,7 +109,6 @@ struct smb_data_buffer { * @reading: Synchronise user space access to SMB buffer. * @pid: Process ID of the process being monitored by the * session that is using this component. - * @mode: How this SMB is being used, perf mode or sysfs mode. */ struct smb_drv_data { void __iomem *base; @@ -119,7 +118,6 @@ struct smb_drv_data { spinlock_t spinlock; bool reading; pid_t pid; - enum cs_mode mode; }; =20 #endif diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 65131bfbd904..ba817f563ff7 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -226,6 +226,11 @@ struct coresight_sysfs_link { * by @coresight_ops. * @access: Device i/o access abstraction for this device. * @dev: The device entity associated to this component. + * @mode: This tracer's mode, i.e sysFS, Perf or disabled. This is + * actually an 'enum cs_mode', but is stored in an atomic type. + * This is always accessed through local_read() and local_set(), + * but wherever it's done from within the Coresight device's lock, + * a non-atomic read would also work. * @refcnt: keep track of what is in use. * @orphan: true if the component has connections that haven't been linked. * @enable: 'true' if component is currently part of an active path. @@ -252,6 +257,7 @@ struct coresight_device { const struct coresight_ops *ops; struct csdev_access access; struct device dev; + local_t mode; atomic_t refcnt; bool orphan; bool enable; --=20 2.34.1 From nobody Wed Dec 17 05:48:46 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 11C59C4332F for ; Tue, 12 Dec 2023 16:16:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232844AbjLLQQm (ORCPT ); Tue, 12 Dec 2023 11:16:42 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50238 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235133AbjLLPzZ (ORCPT ); Tue, 12 Dec 2023 10:55:25 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 5AA33D47 for ; Tue, 12 Dec 2023 07:55:25 -0800 (PST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 28F3F1474; Tue, 12 Dec 2023 07:56:11 -0800 (PST) Received: from e127643.broadband (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 54AAA3F738; Tue, 12 Dec 2023 07:55:23 -0800 (PST) From: James Clark To: coresight@lists.linaro.org, suzuki.poulose@arm.com Cc: James Clark , Mike Leach , Alexander Shishkin , Maxime Coquelin , Alexandre Torgue , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com Subject: [PATCH 5/8] coresight: Remove the 'enable' field. Date: Tue, 12 Dec 2023 15:54:02 +0000 Message-Id: <20231212155407.1429121-6-james.clark@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231212155407.1429121-1-james.clark@arm.com> References: <20231212155407.1429121-1-james.clark@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 'enable', which probably should have been 'enabled', is only ever read in the core code in relation to controlling sources, and specifically only sources in sysfs mode. Confusingly it's not labelled as such and relying on it can be a source of bugs like the one fixed by commit 078dbba3f0c9 ("coresight: Fix crash when Perf and sysfs modes are used concurrently"). Most importantly, it can only be used when the coresight_mutex is held which is only done when enabling and disabling paths in sysfs mode, and not Perf mode. So to prevent its usage spreading and leaking out to other devices, remove it. It's use is equivalent to checking if the mode is currently sysfs, as due to the coresight_mutex lock, mode =3D=3D CS_MODE_SYSFS can only become true or untrue when that lock is held, and when mode =3D=3D CS_MODE_SYSFS the device is both enabled and in sysfs mode. The one place it was used outside of the core code is in TPDA, but that pattern is more appropriately represented using refcounts inside the device's own spinlock. Signed-off-by: James Clark --- drivers/hwtracing/coresight/coresight-core.c | 86 +++++++------------- drivers/hwtracing/coresight/coresight-tpda.c | 12 ++- include/linux/coresight.h | 2 - 3 files changed, 38 insertions(+), 62 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtraci= ng/coresight/coresight-core.c index ab226441e5f4..1d0bd1586590 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -279,29 +279,18 @@ EXPORT_SYMBOL_GPL(coresight_add_helper); static int coresight_enable_sink(struct coresight_device *csdev, enum cs_mode mode, void *data) { - int ret =3D sink_ops(csdev)->enable(csdev, mode, data); - - if (ret) - return ret; - - csdev->enable =3D true; - - return 0; + return sink_ops(csdev)->enable(csdev, mode, data); } =20 static void coresight_disable_sink(struct coresight_device *csdev) { - int ret =3D sink_ops(csdev)->disable(csdev); - if (ret) - return; - csdev->enable =3D false; + sink_ops(csdev)->disable(csdev); } =20 static int coresight_enable_link(struct coresight_device *csdev, struct coresight_device *parent, struct coresight_device *child) { - int ret =3D 0; int link_subtype; struct coresight_connection *inconn, *outconn; =20 @@ -317,19 +306,13 @@ static int coresight_enable_link(struct coresight_dev= ice *csdev, if (link_subtype =3D=3D CORESIGHT_DEV_SUBTYPE_LINK_SPLIT && IS_ERR(outcon= n)) return PTR_ERR(outconn); =20 - ret =3D link_ops(csdev)->enable(csdev, inconn, outconn); - if (!ret) - csdev->enable =3D true; - - return ret; + return link_ops(csdev)->enable(csdev, inconn, outconn); } =20 static void coresight_disable_link(struct coresight_device *csdev, struct coresight_device *parent, struct coresight_device *child) { - int i; - int link_subtype; struct coresight_connection *inconn, *outconn; =20 if (!parent || !child) @@ -337,26 +320,8 @@ static void coresight_disable_link(struct coresight_de= vice *csdev, =20 inconn =3D coresight_find_out_connection(parent, csdev); outconn =3D coresight_find_out_connection(csdev, child); - link_subtype =3D csdev->subtype.link_subtype; =20 link_ops(csdev)->disable(csdev, inconn, outconn); - - if (link_subtype =3D=3D CORESIGHT_DEV_SUBTYPE_LINK_MERG) { - for (i =3D 0; i < csdev->pdata->nr_inconns; i++) - if (atomic_read(&csdev->pdata->in_conns[i]->dest_refcnt) !=3D - 0) - return; - } else if (link_subtype =3D=3D CORESIGHT_DEV_SUBTYPE_LINK_SPLIT) { - for (i =3D 0; i < csdev->pdata->nr_outconns; i++) - if (atomic_read(&csdev->pdata->out_conns[i]->src_refcnt) !=3D - 0) - return; - } else { - if (atomic_read(&csdev->refcnt) !=3D 0) - return; - } - - csdev->enable =3D false; } =20 int coresight_enable_source(struct coresight_device *csdev, enum cs_mode m= ode, @@ -364,11 +329,16 @@ int coresight_enable_source(struct coresight_device *= csdev, enum cs_mode mode, { int ret; =20 - if (!csdev->enable) { + /* + * Comparison with CS_MODE_SYSFS works without taking any device + * specific spinlock because the truthyness of that comparison can only + * change with coresight_mutex held, which we already have here. + */ + lockdep_assert_held(&coresight_mutex); + if (local_read(&csdev->mode) !=3D CS_MODE_SYSFS) { ret =3D source_ops(csdev)->enable(csdev, data, mode); if (ret) return ret; - csdev->enable =3D true; } =20 atomic_inc(&csdev->refcnt); @@ -385,22 +355,12 @@ static bool coresight_is_helper(struct coresight_devi= ce *csdev) static int coresight_enable_helper(struct coresight_device *csdev, enum cs_mode mode, void *data) { - int ret =3D helper_ops(csdev)->enable(csdev, mode, data); - - if (ret) - return ret; - - csdev->enable =3D true; - return 0; + return helper_ops(csdev)->enable(csdev, mode, data); } =20 static void coresight_disable_helper(struct coresight_device *csdev) { - int ret =3D helper_ops(csdev)->disable(csdev, NULL); - - if (ret) - return; - csdev->enable =3D false; + helper_ops(csdev)->disable(csdev, NULL); } =20 static void coresight_disable_helpers(struct coresight_device *csdev) @@ -445,11 +405,15 @@ EXPORT_SYMBOL_GPL(coresight_disable_source); static bool coresight_disable_source_sysfs(struct coresight_device *csdev, void *data) { + lockdep_assert_held(&coresight_mutex); + if (local_read(&csdev->mode) !=3D CS_MODE_SYSFS) + return false; + if (atomic_dec_return(&csdev->refcnt) =3D=3D 0) { coresight_disable_source(csdev, data); - csdev->enable =3D false; + return true; } - return !csdev->enable; + return false; } =20 /* @@ -1097,7 +1061,13 @@ int coresight_enable(struct coresight_device *csdev) if (ret) goto out; =20 - if (csdev->enable) { + /* + * mode =3D=3D SYSFS implies that it's already enabled. Don't look at the + * refcount to determine this because we don't claim the source until + * coresight_enable_source() so can still race with Perf mode which + * doesn't hold coresight_mutex. + */ + if (local_read(&csdev->mode) =3D=3D CS_MODE_SYSFS) { /* * There could be multiple applications driving the software * source. So keep the refcount for each such user when the @@ -1183,7 +1153,7 @@ void coresight_disable(struct coresight_device *csdev) if (ret) goto out; =20 - if (!csdev->enable || !coresight_disable_source_sysfs(csdev, NULL)) + if (!coresight_disable_source_sysfs(csdev, NULL)) goto out; =20 switch (csdev->subtype.source_subtype) { @@ -1249,7 +1219,9 @@ static ssize_t enable_source_show(struct device *dev, { struct coresight_device *csdev =3D to_coresight_device(dev); =20 - return scnprintf(buf, PAGE_SIZE, "%u\n", csdev->enable); + guard(mutex)(&coresight_mutex); + return scnprintf(buf, PAGE_SIZE, "%u\n", + local_read(&csdev->mode) =3D=3D CS_MODE_SYSFS); } =20 static ssize_t enable_source_store(struct device *dev, diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtraci= ng/coresight/coresight-tpda.c index 5f82737c37bb..65c70995ab00 100644 --- a/drivers/hwtracing/coresight/coresight-tpda.c +++ b/drivers/hwtracing/coresight/coresight-tpda.c @@ -148,7 +148,11 @@ static int __tpda_enable(struct tpda_drvdata *drvdata,= int port) =20 CS_UNLOCK(drvdata->base); =20 - if (!drvdata->csdev->enable) + /* + * Only do pre-port enable for first port that calls enable when the + * device's main refcount is still 0 + */ + if (!atomic_read(&drvdata->csdev->refcnt)) tpda_enable_pre_port(drvdata); =20 ret =3D tpda_enable_port(drvdata, port); @@ -169,6 +173,7 @@ static int tpda_enable(struct coresight_device *csdev, ret =3D __tpda_enable(drvdata, in->dest_port); if (!ret) { atomic_inc(&in->dest_refcnt); + atomic_inc(&csdev->refcnt); dev_dbg(drvdata->dev, "TPDA inport %d enabled.\n", in->dest_port); } } @@ -197,9 +202,10 @@ static void tpda_disable(struct coresight_device *csde= v, struct tpda_drvdata *drvdata =3D dev_get_drvdata(csdev->dev.parent); =20 spin_lock(&drvdata->spinlock); - if (atomic_dec_return(&in->dest_refcnt) =3D=3D 0) + if (atomic_dec_return(&in->dest_refcnt) =3D=3D 0) { __tpda_disable(drvdata, in->dest_port); - + atomic_dec(&csdev->refcnt); + } spin_unlock(&drvdata->spinlock); =20 dev_dbg(drvdata->dev, "TPDA inport %d disabled\n", in->dest_port); diff --git a/include/linux/coresight.h b/include/linux/coresight.h index ba817f563ff7..46e6667f72ce 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -233,7 +233,6 @@ struct coresight_sysfs_link { * a non-atomic read would also work. * @refcnt: keep track of what is in use. * @orphan: true if the component has connections that haven't been linked. - * @enable: 'true' if component is currently part of an active path. * @sysfs_sink_activated: 'true' when a sink has been selected for use via= sysfs * by writing a 1 to the 'enable_sink' file. A sink can be * activated but not yet enabled. Enabling for a _sink_ happens @@ -260,7 +259,6 @@ struct coresight_device { local_t mode; atomic_t refcnt; bool orphan; - bool enable; /* sink specific fields */ bool sysfs_sink_activated; struct dev_ext_attribute *ea; --=20 2.34.1 From nobody Wed Dec 17 05:48:46 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 859FEC4167D for ; Tue, 12 Dec 2023 16:16:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376655AbjLLP4Y (ORCPT ); Tue, 12 Dec 2023 10:56:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37024 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235111AbjLLPzg (ORCPT ); Tue, 12 Dec 2023 10:55:36 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 48BAB124 for ; Tue, 12 Dec 2023 07:55:29 -0800 (PST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 68F98143D; Tue, 12 Dec 2023 07:56:15 -0800 (PST) Received: from e127643.broadband (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 77E793F738; Tue, 12 Dec 2023 07:55:27 -0800 (PST) From: James Clark To: coresight@lists.linaro.org, suzuki.poulose@arm.com Cc: James Clark , Mike Leach , Alexander Shishkin , Maxime Coquelin , Alexandre Torgue , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com Subject: [PATCH 6/8] coresight: Move all sysfs code to sysfs file Date: Tue, 12 Dec 2023 15:54:03 +0000 Message-Id: <20231212155407.1429121-7-james.clark@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231212155407.1429121-1-james.clark@arm.com> References: <20231212155407.1429121-1-james.clark@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" At the moment the core file contains both sysfs functionality and core functionality, while the Perf mode is in a separate file in coresight-etm-perf.c Many of the functions have ambiguous names like coresight_enable_source() which actually only work in relation to the sysfs mode. To avoid further confusion, move everything that isn't core functionality into the sysfs file and append _sysfs to the ambiguous functions. Signed-off-by: James Clark --- drivers/hwtracing/coresight/coresight-core.c | 394 +----------------- .../coresight/coresight-etm3x-core.c | 4 +- .../coresight/coresight-etm4x-core.c | 4 +- drivers/hwtracing/coresight/coresight-priv.h | 5 +- drivers/hwtracing/coresight/coresight-stm.c | 4 +- drivers/hwtracing/coresight/coresight-sysfs.c | 390 +++++++++++++++++ include/linux/coresight.h | 8 +- 7 files changed, 407 insertions(+), 402 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtraci= ng/coresight/coresight-core.c index 1d0bd1586590..eb72cdd1a273 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -25,15 +24,12 @@ #include "coresight-priv.h" #include "coresight-syscfg.h" =20 -static DEFINE_MUTEX(coresight_mutex); -static DEFINE_PER_CPU(struct coresight_device *, csdev_sink); - /* - * Use IDR to map the hash of the source's device name - * to the pointer of path for the source. The idr is for - * the sources which aren't associated with CPU. + * Mutex used to lock all sysfs enable and disable actions and loading and + * unloading devices by the Coresight core. */ -static DEFINE_IDR(path_idr); +DEFINE_MUTEX(coresight_mutex); +static DEFINE_PER_CPU(struct coresight_device *, csdev_sink); =20 /** * struct coresight_node - elements of a path, from source to sink @@ -45,12 +41,6 @@ struct coresight_node { struct list_head link; }; =20 -/* - * When operating Coresight drivers from the sysFS interface, only a single - * path can exist from a tracer (associated to a CPU) to a sink. - */ -static DEFINE_PER_CPU(struct list_head *, tracer_path); - /* * When losing synchronisation a new barrier packet needs to be inserted a= t the * beginning of the data collected in a buffer. That way the decoder know= s that @@ -61,34 +51,6 @@ EXPORT_SYMBOL_GPL(coresight_barrier_pkt); =20 static const struct cti_assoc_op *cti_assoc_ops; =20 -ssize_t coresight_simple_show_pair(struct device *_dev, - struct device_attribute *attr, char *buf) -{ - struct coresight_device *csdev =3D container_of(_dev, struct coresight_de= vice, dev); - struct cs_pair_attribute *cs_attr =3D container_of(attr, struct cs_pair_a= ttribute, attr); - u64 val; - - pm_runtime_get_sync(_dev->parent); - val =3D csdev_access_relaxed_read_pair(&csdev->access, cs_attr->lo_off, c= s_attr->hi_off); - pm_runtime_put_sync(_dev->parent); - return sysfs_emit(buf, "0x%llx\n", val); -} -EXPORT_SYMBOL_GPL(coresight_simple_show_pair); - -ssize_t coresight_simple_show32(struct device *_dev, - struct device_attribute *attr, char *buf) -{ - struct coresight_device *csdev =3D container_of(_dev, struct coresight_de= vice, dev); - struct cs_off_attribute *cs_attr =3D container_of(attr, struct cs_off_att= ribute, attr); - u64 val; - - pm_runtime_get_sync(_dev->parent); - val =3D csdev_access_relaxed_read32(&csdev->access, cs_attr->off); - pm_runtime_put_sync(_dev->parent); - return sysfs_emit(buf, "0x%llx\n", val); -} -EXPORT_SYMBOL_GPL(coresight_simple_show32); - void coresight_set_cti_ops(const struct cti_assoc_op *cti_op) { cti_assoc_ops =3D cti_op; @@ -324,29 +286,6 @@ static void coresight_disable_link(struct coresight_de= vice *csdev, link_ops(csdev)->disable(csdev, inconn, outconn); } =20 -int coresight_enable_source(struct coresight_device *csdev, enum cs_mode m= ode, - void *data) -{ - int ret; - - /* - * Comparison with CS_MODE_SYSFS works without taking any device - * specific spinlock because the truthyness of that comparison can only - * change with coresight_mutex held, which we already have here. - */ - lockdep_assert_held(&coresight_mutex); - if (local_read(&csdev->mode) !=3D CS_MODE_SYSFS) { - ret =3D source_ops(csdev)->enable(csdev, data, mode); - if (ret) - return ret; - } - - atomic_inc(&csdev->refcnt); - - return 0; -} -EXPORT_SYMBOL_GPL(coresight_enable_source); - static bool coresight_is_helper(struct coresight_device *csdev) { return csdev->type =3D=3D CORESIGHT_DEV_TYPE_HELPER; @@ -392,30 +331,6 @@ void coresight_disable_source(struct coresight_device = *csdev, void *data) } EXPORT_SYMBOL_GPL(coresight_disable_source); =20 -/** - * coresight_disable_source_sysfs - Drop the reference count by 1 and dis= able - * the device if there are no users left. - * - * @csdev: The coresight device to disable - * @data: Opaque data to pass on to the disable function of the source de= vice. - * For example in perf mode this is a pointer to the struct perf_e= vent. - * - * Returns true if the device has been disabled. - */ -static bool coresight_disable_source_sysfs(struct coresight_device *csdev, - void *data) -{ - lockdep_assert_held(&coresight_mutex); - if (local_read(&csdev->mode) !=3D CS_MODE_SYSFS) - return false; - - if (atomic_dec_return(&csdev->refcnt) =3D=3D 0) { - coresight_disable_source(csdev, data); - return true; - } - return false; -} - /* * coresight_disable_path_from : Disable components in the given path beyo= nd * @nd in the list. If @nd is NULL, all the components, except the SOURCE = are @@ -572,39 +487,6 @@ struct coresight_device *coresight_get_sink(struct lis= t_head *path) return csdev; } =20 -/** - * coresight_find_activated_sysfs_sink - returns the first sink activated = via - * sysfs using connection based search starting from the source reference. - * - * @csdev: Coresight source device reference - */ -static struct coresight_device * -coresight_find_activated_sysfs_sink(struct coresight_device *csdev) -{ - int i; - struct coresight_device *sink =3D NULL; - - if ((csdev->type =3D=3D CORESIGHT_DEV_TYPE_SINK || - csdev->type =3D=3D CORESIGHT_DEV_TYPE_LINKSINK) && - csdev->sysfs_sink_activated) - return csdev; - - /* - * Recursively explore each port found on this element. - */ - for (i =3D 0; i < csdev->pdata->nr_outconns; i++) { - struct coresight_device *child_dev; - - child_dev =3D csdev->pdata->out_conns[i]->dest_dev; - if (child_dev) - sink =3D coresight_find_activated_sysfs_sink(child_dev); - if (sink) - return sink; - } - - return NULL; -} - static int coresight_sink_by_id(struct device *dev, const void *data) { struct coresight_device *csdev =3D to_coresight_device(dev); @@ -1015,274 +897,6 @@ static void coresight_clear_default_sink(struct core= sight_device *csdev) } } =20 -/** coresight_validate_source - make sure a source has the right credentia= ls - * @csdev: the device structure for a source. - * @function: the function this was called from. - * - * Assumes the coresight_mutex is held. - */ -static int coresight_validate_source(struct coresight_device *csdev, - const char *function) -{ - u32 type, subtype; - - type =3D csdev->type; - subtype =3D csdev->subtype.source_subtype; - - if (type !=3D CORESIGHT_DEV_TYPE_SOURCE) { - dev_err(&csdev->dev, "wrong device type in %s\n", function); - return -EINVAL; - } - - if (subtype !=3D CORESIGHT_DEV_SUBTYPE_SOURCE_PROC && - subtype !=3D CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE && - subtype !=3D CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM && - subtype !=3D CORESIGHT_DEV_SUBTYPE_SOURCE_OTHERS) { - dev_err(&csdev->dev, "wrong device subtype in %s\n", function); - return -EINVAL; - } - - return 0; -} - -int coresight_enable(struct coresight_device *csdev) -{ - int cpu, ret =3D 0; - struct coresight_device *sink; - struct list_head *path; - enum coresight_dev_subtype_source subtype; - u32 hash; - - subtype =3D csdev->subtype.source_subtype; - - mutex_lock(&coresight_mutex); - - ret =3D coresight_validate_source(csdev, __func__); - if (ret) - goto out; - - /* - * mode =3D=3D SYSFS implies that it's already enabled. Don't look at the - * refcount to determine this because we don't claim the source until - * coresight_enable_source() so can still race with Perf mode which - * doesn't hold coresight_mutex. - */ - if (local_read(&csdev->mode) =3D=3D CS_MODE_SYSFS) { - /* - * There could be multiple applications driving the software - * source. So keep the refcount for each such user when the - * source is already enabled. - */ - if (subtype =3D=3D CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE) - atomic_inc(&csdev->refcnt); - goto out; - } - - sink =3D coresight_find_activated_sysfs_sink(csdev); - if (!sink) { - ret =3D -EINVAL; - goto out; - } - - path =3D coresight_build_path(csdev, sink); - if (IS_ERR(path)) { - pr_err("building path(s) failed\n"); - ret =3D PTR_ERR(path); - goto out; - } - - ret =3D coresight_enable_path(path, CS_MODE_SYSFS, NULL); - if (ret) - goto err_path; - - ret =3D coresight_enable_source(csdev, CS_MODE_SYSFS, NULL); - if (ret) - goto err_source; - - switch (subtype) { - case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC: - /* - * When working from sysFS it is important to keep track - * of the paths that were created so that they can be - * undone in 'coresight_disable()'. Since there can only - * be a single session per tracer (when working from sysFS) - * a per-cpu variable will do just fine. - */ - cpu =3D source_ops(csdev)->cpu_id(csdev); - per_cpu(tracer_path, cpu) =3D path; - break; - case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE: - case CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM: - case CORESIGHT_DEV_SUBTYPE_SOURCE_OTHERS: - /* - * Use the hash of source's device name as ID - * and map the ID to the pointer of the path. - */ - hash =3D hashlen_hash(hashlen_string(NULL, dev_name(&csdev->dev))); - ret =3D idr_alloc_u32(&path_idr, path, &hash, hash, GFP_KERNEL); - if (ret) - goto err_source; - break; - default: - /* We can't be here */ - break; - } - -out: - mutex_unlock(&coresight_mutex); - return ret; - -err_source: - coresight_disable_path(path); - -err_path: - coresight_release_path(path); - goto out; -} -EXPORT_SYMBOL_GPL(coresight_enable); - -void coresight_disable(struct coresight_device *csdev) -{ - int cpu, ret; - struct list_head *path =3D NULL; - u32 hash; - - mutex_lock(&coresight_mutex); - - ret =3D coresight_validate_source(csdev, __func__); - if (ret) - goto out; - - if (!coresight_disable_source_sysfs(csdev, NULL)) - goto out; - - switch (csdev->subtype.source_subtype) { - case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC: - cpu =3D source_ops(csdev)->cpu_id(csdev); - path =3D per_cpu(tracer_path, cpu); - per_cpu(tracer_path, cpu) =3D NULL; - break; - case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE: - case CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM: - case CORESIGHT_DEV_SUBTYPE_SOURCE_OTHERS: - hash =3D hashlen_hash(hashlen_string(NULL, dev_name(&csdev->dev))); - /* Find the path by the hash. */ - path =3D idr_find(&path_idr, hash); - if (path =3D=3D NULL) { - pr_err("Path is not found for %s\n", dev_name(&csdev->dev)); - goto out; - } - idr_remove(&path_idr, hash); - break; - default: - /* We can't be here */ - break; - } - - coresight_disable_path(path); - coresight_release_path(path); - -out: - mutex_unlock(&coresight_mutex); -} -EXPORT_SYMBOL_GPL(coresight_disable); - -static ssize_t enable_sink_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct coresight_device *csdev =3D to_coresight_device(dev); - - return scnprintf(buf, PAGE_SIZE, "%u\n", csdev->sysfs_sink_activated); -} - -static ssize_t enable_sink_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t size) -{ - int ret; - unsigned long val; - struct coresight_device *csdev =3D to_coresight_device(dev); - - ret =3D kstrtoul(buf, 10, &val); - if (ret) - return ret; - - csdev->sysfs_sink_activated =3D !!val; - - return size; - -} -static DEVICE_ATTR_RW(enable_sink); - -static ssize_t enable_source_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct coresight_device *csdev =3D to_coresight_device(dev); - - guard(mutex)(&coresight_mutex); - return scnprintf(buf, PAGE_SIZE, "%u\n", - local_read(&csdev->mode) =3D=3D CS_MODE_SYSFS); -} - -static ssize_t enable_source_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t size) -{ - int ret =3D 0; - unsigned long val; - struct coresight_device *csdev =3D to_coresight_device(dev); - - ret =3D kstrtoul(buf, 10, &val); - if (ret) - return ret; - - if (val) { - ret =3D coresight_enable(csdev); - if (ret) - return ret; - } else { - coresight_disable(csdev); - } - - return size; -} -static DEVICE_ATTR_RW(enable_source); - -static struct attribute *coresight_sink_attrs[] =3D { - &dev_attr_enable_sink.attr, - NULL, -}; -ATTRIBUTE_GROUPS(coresight_sink); - -static struct attribute *coresight_source_attrs[] =3D { - &dev_attr_enable_source.attr, - NULL, -}; -ATTRIBUTE_GROUPS(coresight_source); - -static struct device_type coresight_dev_type[] =3D { - { - .name =3D "sink", - .groups =3D coresight_sink_groups, - }, - { - .name =3D "link", - }, - { - .name =3D "linksink", - .groups =3D coresight_sink_groups, - }, - { - .name =3D "source", - .groups =3D coresight_source_groups, - }, - { - .name =3D "helper", - } -}; -/* Ensure the enum matches the names and groups */ -static_assert(ARRAY_SIZE(coresight_dev_type) =3D=3D CORESIGHT_DEV_TYPE_MAX= ); - static void coresight_device_release(struct device *dev) { struct coresight_device *csdev =3D to_coresight_device(dev); diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/h= wtracing/coresight/coresight-etm3x-core.c index 29f62dfac673..a8be115636f0 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c @@ -714,7 +714,7 @@ static int etm_online_cpu(unsigned int cpu) return 0; =20 if (etmdrvdata[cpu]->boot_enable && !etmdrvdata[cpu]->sticky_enable) - coresight_enable(etmdrvdata[cpu]->csdev); + coresight_enable_sysfs(etmdrvdata[cpu]->csdev); return 0; } =20 @@ -924,7 +924,7 @@ static int etm_probe(struct amba_device *adev, const st= ruct amba_id *id) dev_info(&drvdata->csdev->dev, "%s initialized\n", (char *)coresight_get_uci_data(id)); if (boot_enable) { - coresight_enable(drvdata->csdev); + coresight_enable_sysfs(drvdata->csdev); drvdata->boot_enable =3D true; } =20 diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/h= wtracing/coresight/coresight-etm4x-core.c index ce1995a2827f..cbb4ac8be133 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -1650,7 +1650,7 @@ static int etm4_online_cpu(unsigned int cpu) return etm4_probe_cpu(cpu); =20 if (etmdrvdata[cpu]->boot_enable && !etmdrvdata[cpu]->sticky_enable) - coresight_enable(etmdrvdata[cpu]->csdev); + coresight_enable_sysfs(etmdrvdata[cpu]->csdev); return 0; } =20 @@ -2098,7 +2098,7 @@ static int etm4_add_coresight_dev(struct etm4_init_ar= g *init_arg) drvdata->cpu, type_name, major, minor); =20 if (boot_enable) { - coresight_enable(drvdata->csdev); + coresight_enable_sysfs(drvdata->csdev); drvdata->boot_enable =3D true; } =20 diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtraci= ng/coresight/coresight-priv.h index ced5be05a527..eb365236f9a9 100644 --- a/drivers/hwtracing/coresight/coresight-priv.h +++ b/drivers/hwtracing/coresight/coresight-priv.h @@ -12,6 +12,9 @@ #include #include =20 +extern struct mutex coresight_mutex; +extern struct device_type coresight_dev_type[]; + /* * Coresight management registers (0xf00-0xfcc) * 0xfa0 - 0xfa4: Management registers in PFTv1.0 @@ -229,8 +232,6 @@ void coresight_add_helper(struct coresight_device *csde= v, =20 void coresight_set_percpu_sink(int cpu, struct coresight_device *csdev); struct coresight_device *coresight_get_percpu_sink(int cpu); -int coresight_enable_source(struct coresight_device *csdev, enum cs_mode m= ode, - void *data); void coresight_disable_source(struct coresight_device *csdev, void *data); =20 #endif diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracin= g/coresight/coresight-stm.c index 190ba569b05a..af9b21224246 100644 --- a/drivers/hwtracing/coresight/coresight-stm.c +++ b/drivers/hwtracing/coresight/coresight-stm.c @@ -332,7 +332,7 @@ static int stm_generic_link(struct stm_data *stm_data, if (!drvdata || !drvdata->csdev) return -EINVAL; =20 - return coresight_enable(drvdata->csdev); + return coresight_enable_sysfs(drvdata->csdev); } =20 static void stm_generic_unlink(struct stm_data *stm_data, @@ -343,7 +343,7 @@ static void stm_generic_unlink(struct stm_data *stm_dat= a, if (!drvdata || !drvdata->csdev) return; =20 - coresight_disable(drvdata->csdev); + coresight_disable_sysfs(drvdata->csdev); } =20 static phys_addr_t diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c b/drivers/hwtrac= ing/coresight/coresight-sysfs.c index dd78e9fcfc4d..92cdf8139f23 100644 --- a/drivers/hwtracing/coresight/coresight-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-sysfs.c @@ -5,10 +5,400 @@ */ =20 #include +#include #include =20 #include "coresight-priv.h" =20 +/* + * Use IDR to map the hash of the source's device name + * to the pointer of path for the source. The idr is for + * the sources which aren't associated with CPU. + */ +static DEFINE_IDR(path_idr); + +/* + * When operating Coresight drivers from the sysFS interface, only a single + * path can exist from a tracer (associated to a CPU) to a sink. + */ +static DEFINE_PER_CPU(struct list_head *, tracer_path); + +ssize_t coresight_simple_show_pair(struct device *_dev, + struct device_attribute *attr, char *buf) +{ + struct coresight_device *csdev =3D container_of(_dev, struct coresight_de= vice, dev); + struct cs_pair_attribute *cs_attr =3D container_of(attr, struct cs_pair_a= ttribute, attr); + u64 val; + + pm_runtime_get_sync(_dev->parent); + val =3D csdev_access_relaxed_read_pair(&csdev->access, cs_attr->lo_off, c= s_attr->hi_off); + pm_runtime_put_sync(_dev->parent); + return sysfs_emit(buf, "0x%llx\n", val); +} +EXPORT_SYMBOL_GPL(coresight_simple_show_pair); + +ssize_t coresight_simple_show32(struct device *_dev, + struct device_attribute *attr, char *buf) +{ + struct coresight_device *csdev =3D container_of(_dev, struct coresight_de= vice, dev); + struct cs_off_attribute *cs_attr =3D container_of(attr, struct cs_off_att= ribute, attr); + u64 val; + + pm_runtime_get_sync(_dev->parent); + val =3D csdev_access_relaxed_read32(&csdev->access, cs_attr->off); + pm_runtime_put_sync(_dev->parent); + return sysfs_emit(buf, "0x%llx\n", val); +} +EXPORT_SYMBOL_GPL(coresight_simple_show32); + +static int coresight_enable_source_sysfs(struct coresight_device *csdev, + enum cs_mode mode, void *data) +{ + int ret; + + /* + * Comparison with CS_MODE_SYSFS works without taking any device + * specific spinlock because the truthyness of that comparison can only + * change with coresight_mutex held, which we already have here. + */ + lockdep_assert_held(&coresight_mutex); + if (local_read(&csdev->mode) !=3D CS_MODE_SYSFS) { + ret =3D source_ops(csdev)->enable(csdev, data, mode); + if (ret) + return ret; + } + + atomic_inc(&csdev->refcnt); + + return 0; +} + +/** + * coresight_disable_source_sysfs - Drop the reference count by 1 and dis= able + * the device if there are no users left. + * + * @csdev: The coresight device to disable + * @data: Opaque data to pass on to the disable function of the source de= vice. + * For example in perf mode this is a pointer to the struct perf_e= vent. + * + * Returns true if the device has been disabled. + */ +static bool coresight_disable_source_sysfs(struct coresight_device *csdev, + void *data) +{ + lockdep_assert_held(&coresight_mutex); + if (local_read(&csdev->mode) !=3D CS_MODE_SYSFS) + return false; + + if (atomic_dec_return(&csdev->refcnt) =3D=3D 0) { + coresight_disable_source(csdev, data); + return true; + } + return false; +} + +/** + * coresight_find_activated_sysfs_sink - returns the first sink activated = via + * sysfs using connection based search starting from the source reference. + * + * @csdev: Coresight source device reference + */ +static struct coresight_device * +coresight_find_activated_sysfs_sink(struct coresight_device *csdev) +{ + int i; + struct coresight_device *sink =3D NULL; + + if ((csdev->type =3D=3D CORESIGHT_DEV_TYPE_SINK || + csdev->type =3D=3D CORESIGHT_DEV_TYPE_LINKSINK) && + csdev->sysfs_sink_activated) + return csdev; + + /* + * Recursively explore each port found on this element. + */ + for (i =3D 0; i < csdev->pdata->nr_outconns; i++) { + struct coresight_device *child_dev; + + child_dev =3D csdev->pdata->out_conns[i]->dest_dev; + if (child_dev) + sink =3D coresight_find_activated_sysfs_sink(child_dev); + if (sink) + return sink; + } + + return NULL; +} + +/** coresight_validate_source - make sure a source has the right credentia= ls to + * be used via sysfs. + * @csdev: the device structure for a source. + * @function: the function this was called from. + * + * Assumes the coresight_mutex is held. + */ +static int coresight_validate_source_sysfs(struct coresight_device *csdev, + const char *function) +{ + u32 type, subtype; + + type =3D csdev->type; + subtype =3D csdev->subtype.source_subtype; + + if (type !=3D CORESIGHT_DEV_TYPE_SOURCE) { + dev_err(&csdev->dev, "wrong device type in %s\n", function); + return -EINVAL; + } + + if (subtype !=3D CORESIGHT_DEV_SUBTYPE_SOURCE_PROC && + subtype !=3D CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE && + subtype !=3D CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM && + subtype !=3D CORESIGHT_DEV_SUBTYPE_SOURCE_OTHERS) { + dev_err(&csdev->dev, "wrong device subtype in %s\n", function); + return -EINVAL; + } + + return 0; +} + +int coresight_enable_sysfs(struct coresight_device *csdev) +{ + int cpu, ret =3D 0; + struct coresight_device *sink; + struct list_head *path; + enum coresight_dev_subtype_source subtype; + u32 hash; + + subtype =3D csdev->subtype.source_subtype; + + mutex_lock(&coresight_mutex); + + ret =3D coresight_validate_source_sysfs(csdev, __func__); + if (ret) + goto out; + + /* + * mode =3D=3D SYSFS implies that it's already enabled. Don't look at the + * refcount to determine this because we don't claim the source until + * coresight_enable_source() so can still race with Perf mode which + * doesn't hold coresight_mutex. + */ + if (local_read(&csdev->mode) =3D=3D CS_MODE_SYSFS) { + /* + * There could be multiple applications driving the software + * source. So keep the refcount for each such user when the + * source is already enabled. + */ + if (subtype =3D=3D CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE) + atomic_inc(&csdev->refcnt); + goto out; + } + + sink =3D coresight_find_activated_sysfs_sink(csdev); + if (!sink) { + ret =3D -EINVAL; + goto out; + } + + path =3D coresight_build_path(csdev, sink); + if (IS_ERR(path)) { + pr_err("building path(s) failed\n"); + ret =3D PTR_ERR(path); + goto out; + } + + ret =3D coresight_enable_path(path, CS_MODE_SYSFS, NULL); + if (ret) + goto err_path; + + ret =3D coresight_enable_source_sysfs(csdev, CS_MODE_SYSFS, NULL); + if (ret) + goto err_source; + + switch (subtype) { + case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC: + /* + * When working from sysFS it is important to keep track + * of the paths that were created so that they can be + * undone in 'coresight_disable()'. Since there can only + * be a single session per tracer (when working from sysFS) + * a per-cpu variable will do just fine. + */ + cpu =3D source_ops(csdev)->cpu_id(csdev); + per_cpu(tracer_path, cpu) =3D path; + break; + case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE: + case CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM: + case CORESIGHT_DEV_SUBTYPE_SOURCE_OTHERS: + /* + * Use the hash of source's device name as ID + * and map the ID to the pointer of the path. + */ + hash =3D hashlen_hash(hashlen_string(NULL, dev_name(&csdev->dev))); + ret =3D idr_alloc_u32(&path_idr, path, &hash, hash, GFP_KERNEL); + if (ret) + goto err_source; + break; + default: + /* We can't be here */ + break; + } + +out: + mutex_unlock(&coresight_mutex); + return ret; + +err_source: + coresight_disable_path(path); + +err_path: + coresight_release_path(path); + goto out; +} +EXPORT_SYMBOL_GPL(coresight_enable_sysfs); + +void coresight_disable_sysfs(struct coresight_device *csdev) +{ + int cpu, ret; + struct list_head *path =3D NULL; + u32 hash; + + mutex_lock(&coresight_mutex); + + ret =3D coresight_validate_source_sysfs(csdev, __func__); + if (ret) + goto out; + + if (!coresight_disable_source_sysfs(csdev, NULL)) + goto out; + + switch (csdev->subtype.source_subtype) { + case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC: + cpu =3D source_ops(csdev)->cpu_id(csdev); + path =3D per_cpu(tracer_path, cpu); + per_cpu(tracer_path, cpu) =3D NULL; + break; + case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE: + case CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM: + case CORESIGHT_DEV_SUBTYPE_SOURCE_OTHERS: + hash =3D hashlen_hash(hashlen_string(NULL, dev_name(&csdev->dev))); + /* Find the path by the hash. */ + path =3D idr_find(&path_idr, hash); + if (path =3D=3D NULL) { + pr_err("Path is not found for %s\n", dev_name(&csdev->dev)); + goto out; + } + idr_remove(&path_idr, hash); + break; + default: + /* We can't be here */ + break; + } + + coresight_disable_path(path); + coresight_release_path(path); + +out: + mutex_unlock(&coresight_mutex); +} +EXPORT_SYMBOL_GPL(coresight_disable_sysfs); + +static ssize_t enable_sink_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct coresight_device *csdev =3D to_coresight_device(dev); + + return scnprintf(buf, PAGE_SIZE, "%u\n", csdev->sysfs_sink_activated); +} + +static ssize_t enable_sink_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + unsigned long val; + struct coresight_device *csdev =3D to_coresight_device(dev); + + ret =3D kstrtoul(buf, 10, &val); + if (ret) + return ret; + + csdev->sysfs_sink_activated =3D !!val; + + return size; + +} +static DEVICE_ATTR_RW(enable_sink); + +static ssize_t enable_source_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct coresight_device *csdev =3D to_coresight_device(dev); + + guard(mutex)(&coresight_mutex); + return scnprintf(buf, PAGE_SIZE, "%u\n", + local_read(&csdev->mode) =3D=3D CS_MODE_SYSFS); +} + +static ssize_t enable_source_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret =3D 0; + unsigned long val; + struct coresight_device *csdev =3D to_coresight_device(dev); + + ret =3D kstrtoul(buf, 10, &val); + if (ret) + return ret; + + if (val) { + ret =3D coresight_enable_sysfs(csdev); + if (ret) + return ret; + } else { + coresight_disable_sysfs(csdev); + } + + return size; +} +static DEVICE_ATTR_RW(enable_source); + +static struct attribute *coresight_sink_attrs[] =3D { + &dev_attr_enable_sink.attr, + NULL, +}; +ATTRIBUTE_GROUPS(coresight_sink); + +static struct attribute *coresight_source_attrs[] =3D { + &dev_attr_enable_source.attr, + NULL, +}; +ATTRIBUTE_GROUPS(coresight_source); + +struct device_type coresight_dev_type[] =3D { + { + .name =3D "sink", + .groups =3D coresight_sink_groups, + }, + { + .name =3D "link", + }, + { + .name =3D "linksink", + .groups =3D coresight_sink_groups, + }, + { + .name =3D "source", + .groups =3D coresight_source_groups, + }, + { + .name =3D "helper", + } +}; +/* Ensure the enum matches the names and groups */ +static_assert(ARRAY_SIZE(coresight_dev_type) =3D=3D CORESIGHT_DEV_TYPE_MAX= ); + /* * Connections group - links attribute. * Count of created links between coresight components in the group. diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 46e6667f72ce..e8dd0df98881 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -578,8 +578,8 @@ static inline bool coresight_is_percpu_sink(struct core= sight_device *csdev) extern struct coresight_device * coresight_register(struct coresight_desc *desc); extern void coresight_unregister(struct coresight_device *csdev); -extern int coresight_enable(struct coresight_device *csdev); -extern void coresight_disable(struct coresight_device *csdev); +extern int coresight_enable_sysfs(struct coresight_device *csdev); +extern void coresight_disable_sysfs(struct coresight_device *csdev); extern int coresight_timeout(struct csdev_access *csa, u32 offset, int position, int value); =20 @@ -609,8 +609,8 @@ static inline struct coresight_device * coresight_register(struct coresight_desc *desc) { return NULL; } static inline void coresight_unregister(struct coresight_device *csdev) {} static inline int -coresight_enable(struct coresight_device *csdev) { return -ENOSYS; } -static inline void coresight_disable(struct coresight_device *csdev) {} +coresight_enable_sysfs(struct coresight_device *csdev) { return -ENOSYS; } +static inline void coresight_disable_sysfs(struct coresight_device *csdev)= {} =20 static inline int coresight_timeout(struct csdev_access *csa, u32 offset, int position, int value) --=20 2.34.1 From nobody Wed Dec 17 05:48:46 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9ADCBC4167B for ; Tue, 12 Dec 2023 16:16:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376761AbjLLP40 (ORCPT ); Tue, 12 Dec 2023 10:56:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37110 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235216AbjLLPzm (ORCPT ); Tue, 12 Dec 2023 10:55:42 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 3D185115 for ; Tue, 12 Dec 2023 07:55:33 -0800 (PST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 5A2DC1474; Tue, 12 Dec 2023 07:56:19 -0800 (PST) Received: from e127643.broadband (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 862AC3F738; Tue, 12 Dec 2023 07:55:31 -0800 (PST) From: James Clark To: coresight@lists.linaro.org, suzuki.poulose@arm.com Cc: James Clark , Mike Leach , Alexander Shishkin , Maxime Coquelin , Alexandre Torgue , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com Subject: [PATCH 7/8] coresight: Remove atomic type from refcnt Date: Tue, 12 Dec 2023 15:54:04 +0000 Message-Id: <20231212155407.1429121-8-james.clark@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231212155407.1429121-1-james.clark@arm.com> References: <20231212155407.1429121-1-james.clark@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Refcnt is only ever accessed from either inside the coresight_mutex, or the device's spinlock, making the atomic type and atomic_dec_return() calls confusing and unnecessary. The only point of synchronisation outside of these two types of locks is already done with a compare and swap on 'mode', which a comment has been added for. There was one instance of refcnt being used outside of a lock in TPIU, but that can easily be fixed by making it the same as all the other devices and adding a spinlock. Potentially in the future all the refcounting and locking can be moved up into the core code, and all the mostly duplicate code from the individual devices can be removed. Signed-off-by: James Clark --- drivers/hwtracing/coresight/coresight-etb10.c | 11 +++++----- drivers/hwtracing/coresight/coresight-sysfs.c | 7 ++++--- .../hwtracing/coresight/coresight-tmc-etf.c | 20 ++++++++++--------- .../hwtracing/coresight/coresight-tmc-etr.c | 13 ++++++------ drivers/hwtracing/coresight/coresight-tpda.c | 7 ++++--- drivers/hwtracing/coresight/coresight-tpiu.c | 14 +++++++++++-- drivers/hwtracing/coresight/ultrasoc-smb.c | 9 +++++---- include/linux/coresight.h | 13 +++++++++--- 8 files changed, 59 insertions(+), 35 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtrac= ing/coresight/coresight-etb10.c index 08e5bba862db..5f2bb95955b7 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -161,7 +161,7 @@ static int etb_enable_sysfs(struct coresight_device *cs= dev) local_set(&csdev->mode, CS_MODE_SYSFS); } =20 - atomic_inc(&csdev->refcnt); + csdev->refcnt++; out: spin_unlock_irqrestore(&drvdata->spinlock, flags); return ret; @@ -197,7 +197,7 @@ static int etb_enable_perf(struct coresight_device *csd= ev, void *data) * use for this session. */ if (drvdata->pid =3D=3D pid) { - atomic_inc(&csdev->refcnt); + csdev->refcnt++; goto out; } =20 @@ -215,7 +215,7 @@ static int etb_enable_perf(struct coresight_device *csd= ev, void *data) /* Associate with monitored process. */ drvdata->pid =3D pid; local_set(&drvdata->csdev->mode, CS_MODE_PERF); - atomic_inc(&csdev->refcnt); + csdev->refcnt++; } =20 out: @@ -354,7 +354,8 @@ static int etb_disable(struct coresight_device *csdev) =20 spin_lock_irqsave(&drvdata->spinlock, flags); =20 - if (atomic_dec_return(&csdev->refcnt)) { + csdev->refcnt--; + if (csdev->refcnt) { spin_unlock_irqrestore(&drvdata->spinlock, flags); return -EBUSY; } @@ -445,7 +446,7 @@ static unsigned long etb_update_buffer(struct coresight= _device *csdev, spin_lock_irqsave(&drvdata->spinlock, flags); =20 /* Don't do anything if another tracer is using this sink */ - if (atomic_read(&csdev->refcnt) !=3D 1) + if (csdev->refcnt !=3D 1) goto out; =20 __etb_disable_hw(drvdata); diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c b/drivers/hwtrac= ing/coresight/coresight-sysfs.c index 92cdf8139f23..5992f2c2200a 100644 --- a/drivers/hwtracing/coresight/coresight-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-sysfs.c @@ -68,7 +68,7 @@ static int coresight_enable_source_sysfs(struct coresight= _device *csdev, return ret; } =20 - atomic_inc(&csdev->refcnt); + csdev->refcnt++; =20 return 0; } @@ -90,7 +90,8 @@ static bool coresight_disable_source_sysfs(struct coresig= ht_device *csdev, if (local_read(&csdev->mode) !=3D CS_MODE_SYSFS) return false; =20 - if (atomic_dec_return(&csdev->refcnt) =3D=3D 0) { + csdev->refcnt--; + if (csdev->refcnt =3D=3D 0) { coresight_disable_source(csdev, data); return true; } @@ -190,7 +191,7 @@ int coresight_enable_sysfs(struct coresight_device *csd= ev) * source is already enabled. */ if (subtype =3D=3D CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE) - atomic_inc(&csdev->refcnt); + csdev->refcnt++; goto out; } =20 diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtr= acing/coresight/coresight-tmc-etf.c index 2a7e516052a2..f3281c958a57 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c @@ -206,7 +206,7 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_d= evice *csdev) * touched. */ if (local_read(&csdev->mode) =3D=3D CS_MODE_SYSFS) { - atomic_inc(&csdev->refcnt); + csdev->refcnt++; goto out; } =20 @@ -229,7 +229,7 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_d= evice *csdev) ret =3D tmc_etb_enable_hw(drvdata); if (!ret) { local_set(&csdev->mode, CS_MODE_SYSFS); - atomic_inc(&csdev->refcnt); + csdev->refcnt++; } else { /* Free up the buffer if we failed to enable */ used =3D false; @@ -284,7 +284,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_de= vice *csdev, void *data) * use for this session. */ if (drvdata->pid =3D=3D pid) { - atomic_inc(&csdev->refcnt); + csdev->refcnt++; break; } =20 @@ -293,7 +293,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_de= vice *csdev, void *data) /* Associate with monitored process. */ drvdata->pid =3D pid; local_set(&csdev->mode, CS_MODE_PERF); - atomic_inc(&csdev->refcnt); + csdev->refcnt++; } } while (0); spin_unlock_irqrestore(&drvdata->spinlock, flags); @@ -338,7 +338,8 @@ static int tmc_disable_etf_sink(struct coresight_device= *csdev) return -EBUSY; } =20 - if (atomic_dec_return(&csdev->refcnt)) { + csdev->refcnt--; + if (csdev->refcnt) { spin_unlock_irqrestore(&drvdata->spinlock, flags); return -EBUSY; } @@ -371,7 +372,7 @@ static int tmc_enable_etf_link(struct coresight_device = *csdev, return -EBUSY; } =20 - if (atomic_read(&csdev->refcnt) =3D=3D 0) { + if (csdev->refcnt =3D=3D 0) { ret =3D tmc_etf_enable_hw(drvdata); if (!ret) { local_set(&csdev->mode, CS_MODE_SYSFS); @@ -379,7 +380,7 @@ static int tmc_enable_etf_link(struct coresight_device = *csdev, } } if (!ret) - atomic_inc(&csdev->refcnt); + csdev->refcnt++; spin_unlock_irqrestore(&drvdata->spinlock, flags); =20 if (first_enable) @@ -401,7 +402,8 @@ static void tmc_disable_etf_link(struct coresight_devic= e *csdev, return; } =20 - if (atomic_dec_return(&csdev->refcnt) =3D=3D 0) { + csdev->refcnt--; + if (csdev->refcnt =3D=3D 0) { tmc_etf_disable_hw(drvdata); local_set(&csdev->mode, CS_MODE_DISABLED); last_disable =3D true; @@ -489,7 +491,7 @@ static unsigned long tmc_update_etf_buffer(struct cores= ight_device *csdev, spin_lock_irqsave(&drvdata->spinlock, flags); =20 /* Don't do anything if another tracer is using this sink */ - if (atomic_read(&csdev->refcnt) !=3D 1) + if (csdev->refcnt !=3D 1) goto out; =20 CS_UNLOCK(drvdata->base); diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtr= acing/coresight/coresight-tmc-etr.c index 3dc989d4fcab..88a0fc375b4d 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -1231,14 +1231,14 @@ static int tmc_enable_etr_sink_sysfs(struct coresig= ht_device *csdev) * touched, even if the buffer size has changed. */ if (local_read(&csdev->mode) =3D=3D CS_MODE_SYSFS) { - atomic_inc(&csdev->refcnt); + csdev->refcnt++; goto out; } =20 ret =3D tmc_etr_enable_hw(drvdata, sysfs_buf); if (!ret) { local_set(&csdev->mode, CS_MODE_SYSFS); - atomic_inc(&csdev->refcnt); + csdev->refcnt++; } =20 out: @@ -1564,7 +1564,7 @@ tmc_update_etr_buffer(struct coresight_device *csdev, spin_lock_irqsave(&drvdata->spinlock, flags); =20 /* Don't do anything if another tracer is using this sink */ - if (atomic_read(&csdev->refcnt) !=3D 1) { + if (csdev->refcnt !=3D 1) { spin_unlock_irqrestore(&drvdata->spinlock, flags); goto out; } @@ -1676,7 +1676,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_= device *csdev, void *data) * use for this session. */ if (drvdata->pid =3D=3D pid) { - atomic_inc(&csdev->refcnt); + csdev->refcnt++; goto unlock_out; } =20 @@ -1686,7 +1686,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_= device *csdev, void *data) drvdata->pid =3D pid; local_set(&csdev->mode, CS_MODE_PERF); drvdata->perf_buf =3D etr_perf->etr_buf; - atomic_inc(&csdev->refcnt); + csdev->refcnt++; } =20 unlock_out: @@ -1719,7 +1719,8 @@ static int tmc_disable_etr_sink(struct coresight_devi= ce *csdev) return -EBUSY; } =20 - if (atomic_dec_return(&csdev->refcnt)) { + csdev->refcnt--; + if (csdev->refcnt) { spin_unlock_irqrestore(&drvdata->spinlock, flags); return -EBUSY; } diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtraci= ng/coresight/coresight-tpda.c index 65c70995ab00..135a89654c4c 100644 --- a/drivers/hwtracing/coresight/coresight-tpda.c +++ b/drivers/hwtracing/coresight/coresight-tpda.c @@ -152,7 +152,8 @@ static int __tpda_enable(struct tpda_drvdata *drvdata, = int port) * Only do pre-port enable for first port that calls enable when the * device's main refcount is still 0 */ - if (!atomic_read(&drvdata->csdev->refcnt)) + lockdep_assert_held(&drvdata->spinlock); + if (!drvdata->csdev->refcnt) tpda_enable_pre_port(drvdata); =20 ret =3D tpda_enable_port(drvdata, port); @@ -173,7 +174,7 @@ static int tpda_enable(struct coresight_device *csdev, ret =3D __tpda_enable(drvdata, in->dest_port); if (!ret) { atomic_inc(&in->dest_refcnt); - atomic_inc(&csdev->refcnt); + csdev->refcnt++; dev_dbg(drvdata->dev, "TPDA inport %d enabled.\n", in->dest_port); } } @@ -204,7 +205,7 @@ static void tpda_disable(struct coresight_device *csdev, spin_lock(&drvdata->spinlock); if (atomic_dec_return(&in->dest_refcnt) =3D=3D 0) { __tpda_disable(drvdata, in->dest_port); - atomic_dec(&csdev->refcnt); + csdev->refcnt--; } spin_unlock(&drvdata->spinlock); =20 diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtraci= ng/coresight/coresight-tpiu.c index 59eac93fd6bb..c23a6b9b41fe 100644 --- a/drivers/hwtracing/coresight/coresight-tpiu.c +++ b/drivers/hwtracing/coresight/coresight-tpiu.c @@ -58,6 +58,7 @@ struct tpiu_drvdata { void __iomem *base; struct clk *atclk; struct coresight_device *csdev; + spinlock_t spinlock; }; =20 static void tpiu_enable_hw(struct csdev_access *csa) @@ -72,8 +73,11 @@ static void tpiu_enable_hw(struct csdev_access *csa) static int tpiu_enable(struct coresight_device *csdev, enum cs_mode mode, void *__unused) { + struct tpiu_drvdata *drvdata =3D dev_get_drvdata(csdev->dev.parent); + + guard(spinlock)(&drvdata->spinlock); tpiu_enable_hw(&csdev->access); - atomic_inc(&csdev->refcnt); + csdev->refcnt++; dev_dbg(&csdev->dev, "TPIU enabled\n"); return 0; } @@ -96,7 +100,11 @@ static void tpiu_disable_hw(struct csdev_access *csa) =20 static int tpiu_disable(struct coresight_device *csdev) { - if (atomic_dec_return(&csdev->refcnt)) + struct tpiu_drvdata *drvdata =3D dev_get_drvdata(csdev->dev.parent); + + guard(spinlock)(&drvdata->spinlock); + csdev->refcnt--; + if (csdev->refcnt) return -EBUSY; =20 tpiu_disable_hw(&csdev->access); @@ -132,6 +140,8 @@ static int tpiu_probe(struct amba_device *adev, const s= truct amba_id *id) if (!drvdata) return -ENOMEM; =20 + spin_lock_init(&drvdata->spinlock); + drvdata->atclk =3D devm_clk_get(&adev->dev, "atclk"); /* optional */ if (!IS_ERR(drvdata->atclk)) { ret =3D clk_prepare_enable(drvdata->atclk); diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.c b/drivers/hwtracing= /coresight/ultrasoc-smb.c index 1a8c64645b92..1146584a1745 100644 --- a/drivers/hwtracing/coresight/ultrasoc-smb.c +++ b/drivers/hwtracing/coresight/ultrasoc-smb.c @@ -103,7 +103,7 @@ static int smb_open(struct inode *inode, struct file *f= ile) if (drvdata->reading) return -EBUSY; =20 - if (atomic_read(&drvdata->csdev->refcnt)) + if (drvdata->csdev->refcnt) return -EBUSY; =20 smb_update_data_size(drvdata); @@ -271,7 +271,7 @@ static int smb_enable(struct coresight_device *csdev, e= num cs_mode mode, if (ret) return ret; =20 - atomic_inc(&csdev->refcnt); + csdev->refcnt++; dev_dbg(&csdev->dev, "Ultrasoc SMB enabled\n"); =20 return ret; @@ -286,7 +286,8 @@ static int smb_disable(struct coresight_device *csdev) if (drvdata->reading) return -EBUSY; =20 - if (atomic_dec_return(&csdev->refcnt)) + csdev->refcnt--; + if (csdev->refcnt) return -EBUSY; =20 /* Complain if we (somehow) got out of sync */ @@ -381,7 +382,7 @@ static unsigned long smb_update_buffer(struct coresight= _device *csdev, guard(spinlock)(&drvdata->spinlock); =20 /* Don't do anything if another tracer is using this sink. */ - if (atomic_read(&csdev->refcnt) !=3D 1) + if (csdev->refcnt !=3D 1) return 0; =20 smb_disable_hw(drvdata); diff --git a/include/linux/coresight.h b/include/linux/coresight.h index e8dd0df98881..4400d554a16b 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -230,8 +230,15 @@ struct coresight_sysfs_link { * actually an 'enum cs_mode', but is stored in an atomic type. * This is always accessed through local_read() and local_set(), * but wherever it's done from within the Coresight device's lock, - * a non-atomic read would also work. - * @refcnt: keep track of what is in use. + * a non-atomic read would also work. This is the main point of + * synchronisation between code happening inside the sysfs mode's + * coresight_mutex and outside when running in Perf mode. A compare + * and exchange swap is done to atomically claim one mode or the + * other. + * @refcnt: keep track of what is in use. Only access this outside of the + * device's spinlock when the coresight_mutex held and mode =3D=3D + * CS_MODE_SYSFS. Otherwise it must be accessed from inside the + * spinlock. * @orphan: true if the component has connections that haven't been linked. * @sysfs_sink_activated: 'true' when a sink has been selected for use via= sysfs * by writing a 1 to the 'enable_sink' file. A sink can be @@ -257,7 +264,7 @@ struct coresight_device { struct csdev_access access; struct device dev; local_t mode; - atomic_t refcnt; + int refcnt; bool orphan; /* sink specific fields */ bool sysfs_sink_activated; --=20 2.34.1 From nobody Wed Dec 17 05:48:46 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id ABAA9C41535 for ; Tue, 12 Dec 2023 16:16:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377008AbjLLP42 (ORCPT ); Tue, 12 Dec 2023 10:56:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32816 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235226AbjLLPzn (ORCPT ); Tue, 12 Dec 2023 10:55:43 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 42E5CD7F for ; Tue, 12 Dec 2023 07:55:37 -0800 (PST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 37A2B1516; Tue, 12 Dec 2023 07:56:23 -0800 (PST) Received: from e127643.broadband (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 62DE23F738; Tue, 12 Dec 2023 07:55:35 -0800 (PST) From: James Clark To: coresight@lists.linaro.org, suzuki.poulose@arm.com Cc: James Clark , Mike Leach , Alexander Shishkin , Maxime Coquelin , Alexandre Torgue , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com Subject: [PATCH 8/8] coresight: Remove unused stubs Date: Tue, 12 Dec 2023 15:54:05 +0000 Message-Id: <20231212155407.1429121-9-james.clark@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231212155407.1429121-1-james.clark@arm.com> References: <20231212155407.1429121-1-james.clark@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" These are a bit annoying to keep up to date when the function signatures change. But if CONFIG_CORESIGHT isn't enabled, then they're not used anyway so just delete them. Signed-off-by: James Clark --- include/linux/coresight.h | 79 --------------------------------------- 1 file changed, 79 deletions(-) diff --git a/include/linux/coresight.h b/include/linux/coresight.h index 4400d554a16b..c5be46d7f85c 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -391,8 +391,6 @@ struct coresight_ops { const struct coresight_ops_helper *helper_ops; }; =20 -#if IS_ENABLED(CONFIG_CORESIGHT) - static inline u32 csdev_access_relaxed_read32(struct csdev_access *csa, u32 offset) { @@ -611,83 +609,6 @@ void coresight_relaxed_write64(struct coresight_device= *csdev, u64 val, u32 offset); void coresight_write64(struct coresight_device *csdev, u64 val, u32 offset= ); =20 -#else -static inline struct coresight_device * -coresight_register(struct coresight_desc *desc) { return NULL; } -static inline void coresight_unregister(struct coresight_device *csdev) {} -static inline int -coresight_enable_sysfs(struct coresight_device *csdev) { return -ENOSYS; } -static inline void coresight_disable_sysfs(struct coresight_device *csdev)= {} - -static inline int coresight_timeout(struct csdev_access *csa, u32 offset, - int position, int value) -{ - return 1; -} - -static inline int coresight_claim_device_unlocked(struct coresight_device = *csdev) -{ - return -EINVAL; -} - -static inline int coresight_claim_device(struct coresight_device *csdev) -{ - return -EINVAL; -} - -static inline void coresight_disclaim_device(struct coresight_device *csde= v) {} -static inline void coresight_disclaim_device_unlocked(struct coresight_dev= ice *csdev) {} - -static inline bool coresight_loses_context_with_cpu(struct device *dev) -{ - return false; -} - -static inline u32 coresight_relaxed_read32(struct coresight_device *csdev,= u32 offset) -{ - WARN_ON_ONCE(1); - return 0; -} - -static inline u32 coresight_read32(struct coresight_device *csdev, u32 off= set) -{ - WARN_ON_ONCE(1); - return 0; -} - -static inline void coresight_write32(struct coresight_device *csdev, u32 v= al, u32 offset) -{ -} - -static inline void coresight_relaxed_write32(struct coresight_device *csde= v, - u32 val, u32 offset) -{ -} - -static inline u64 coresight_relaxed_read64(struct coresight_device *csdev, - u32 offset) -{ - WARN_ON_ONCE(1); - return 0; -} - -static inline u64 coresight_read64(struct coresight_device *csdev, u32 off= set) -{ - WARN_ON_ONCE(1); - return 0; -} - -static inline void coresight_relaxed_write64(struct coresight_device *csde= v, - u64 val, u32 offset) -{ -} - -static inline void coresight_write64(struct coresight_device *csdev, u64 v= al, u32 offset) -{ -} - -#endif /* IS_ENABLED(CONFIG_CORESIGHT) */ - extern int coresight_get_cpu(struct device *dev); =20 struct coresight_platform_data *coresight_get_platform_data(struct device = *dev); --=20 2.34.1