From: Sean Anderson <sean.anderson@linux.dev>
To: Suzuki K Poulose <suzuki.poulose@arm.com>,
coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org
Cc: Leo Yan <leo.yan@arm.com>, Yeoreum Yun <yeoreum.yun@arm.com>,
Linu Cherian <lcherian@marvell.com>,
Mike Leach <mike.leach@linaro.org>,
linux-kernel@vger.kernel.org,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
James Clark <james.clark@linaro.org>,
Sean Anderson <sean.anderson@linux.dev>
Subject: [PATCH v5 3/3] coresight: Fix possible deadlock in coresight_panic_cb
Date: Thu, 25 Sep 2025 11:03:42 -0400 [thread overview]
Message-ID: <20250925150342.1845615-4-sean.anderson@linux.dev> (raw)
In-Reply-To: <20250925150342.1845615-1-sean.anderson@linux.dev>
Panics can occur at any time, so taking locks may cause a deadlock (such
as if the panicking CPU held the lock). coresight_panic_cb uses
bus_for_each_dev, but that calls bus_to_subsys which takes
bus_kset->list_lock.
Instead of registering a single panic notifier and iterating over
coresight devices, register a panic notifier for each coresight device
that requires it (letting the atomic notifier list handle iteration).
atomic_notifier_chain_unregister will just return -ENOENT if a notifier
block isn't on the list, so it's safe to call when we haven't registered
a notifier.
Fixes: 46006ceb5d02 ("coresight: core: Add provision for panic callbacks")
Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
---
Changes in v5:
- Check csdev mode before calling sync()
Changes in v4:
- Move the panic notifier into csdev and restore the panic sync API
Changes in v3:
- Rewrite patch to remove the panic sync API entirely
Changes in v2:
- Add a comment describing csdev_lock/list
- Consolidate list removal in coresight_device_release
drivers/hwtracing/coresight/coresight-core.c | 67 ++++++++------------
include/linux/coresight.h | 2 +
2 files changed, 28 insertions(+), 41 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index 305b1773cfbe..01303348fc0e 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -1046,6 +1046,9 @@ static void coresight_device_release(struct device *dev)
{
struct coresight_device *csdev = to_coresight_device(dev);
+ if (panic_ops(csdev))
+ atomic_notifier_chain_unregister(&panic_notifier_list,
+ &csdev->panic_notifier);
free_percpu(csdev->perf_sink_id_map.cpu_map);
fwnode_handle_put(csdev->dev.fwnode);
kfree(csdev);
@@ -1315,6 +1318,18 @@ void coresight_release_platform_data(struct coresight_device *csdev,
coresight_remove_conns_sysfs_group(csdev);
}
+static int coresight_panic_notifier(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct coresight_device *csdev =
+ container_of(nb, struct coresight_device, panic_notifier);
+ int mode = coresight_get_mode(csdev);
+
+ if (mode == CS_MODE_SYSFS || mode == CS_MODE_PERF)
+ panic_ops(csdev)->sync(csdev);
+ return NOTIFY_DONE;
+}
+
struct coresight_device *coresight_register(struct coresight_desc *desc)
{
int ret;
@@ -1357,6 +1372,17 @@ struct coresight_device *coresight_register(struct coresight_desc *desc)
goto err_out;
}
}
+
+ if (panic_ops(csdev)) {
+ csdev->panic_notifier.notifier_call = coresight_panic_notifier;
+ ret = atomic_notifier_chain_register(&panic_notifier_list,
+ &csdev->panic_notifier);
+ if (ret) {
+ coresight_device_release(&csdev->dev);
+ goto err_out;
+ }
+ }
+
/*
* Make sure the device registration and the connection fixup
* are synchronised, so that we don't see uninitialised devices
@@ -1563,36 +1589,6 @@ const struct bus_type coresight_bustype = {
.name = "coresight",
};
-static int coresight_panic_sync(struct device *dev, void *data)
-{
- int mode;
- struct coresight_device *csdev;
-
- /* Run through panic sync handlers for all enabled devices */
- csdev = container_of(dev, struct coresight_device, dev);
- mode = coresight_get_mode(csdev);
-
- if ((mode == CS_MODE_SYSFS) || (mode == CS_MODE_PERF)) {
- if (panic_ops(csdev))
- panic_ops(csdev)->sync(csdev);
- }
-
- return 0;
-}
-
-static int coresight_panic_cb(struct notifier_block *self,
- unsigned long v, void *p)
-{
- bus_for_each_dev(&coresight_bustype, NULL, NULL,
- coresight_panic_sync);
-
- return 0;
-}
-
-static struct notifier_block coresight_notifier = {
- .notifier_call = coresight_panic_cb,
-};
-
static int __init coresight_init(void)
{
int ret;
@@ -1605,20 +1601,11 @@ static int __init coresight_init(void)
if (ret)
goto exit_bus_unregister;
- /* Register function to be called for panic */
- ret = atomic_notifier_chain_register(&panic_notifier_list,
- &coresight_notifier);
- if (ret)
- goto exit_perf;
-
/* initialise the coresight syscfg API */
ret = cscfg_init();
if (!ret)
return 0;
- atomic_notifier_chain_unregister(&panic_notifier_list,
- &coresight_notifier);
-exit_perf:
etm_perf_exit();
exit_bus_unregister:
bus_unregister(&coresight_bustype);
@@ -1628,8 +1615,6 @@ static int __init coresight_init(void)
static void __exit coresight_exit(void)
{
cscfg_exit();
- atomic_notifier_chain_unregister(&panic_notifier_list,
- &coresight_notifier);
etm_perf_exit();
bus_unregister(&coresight_bustype);
}
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 4ac65c68bbf4..a7aaf9d3d01d 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -280,6 +280,7 @@ struct coresight_trace_id_map {
* @config_csdev_list: List of system configurations added to the device.
* @cscfg_csdev_lock: Protect the lists of configurations and features.
* @active_cscfg_ctxt: Context information for current active system configuration.
+ * @panic_notifier: Notifier block used to clean up during a panic
*/
struct coresight_device {
struct coresight_platform_data *pdata;
@@ -304,6 +305,7 @@ struct coresight_device {
struct list_head config_csdev_list;
raw_spinlock_t cscfg_csdev_lock;
void *active_cscfg_ctxt;
+ struct notifier_block panic_notifier;
};
/*
--
2.35.1.1320.gc452695387.dirty
next prev parent reply other threads:[~2025-09-25 15:05 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-25 15:03 [PATCH v5 0/3] coresight: Fix possible deadlock in coresight_panic_cb Sean Anderson
2025-09-25 15:03 ` [PATCH v5 1/3] coresight: Fix fwnode leak in coresight_register error path Sean Anderson
2025-09-26 10:16 ` Mike Leach
2025-09-25 15:03 ` [PATCH v5 2/3] coresight: Reorder coresight_device_release to match coresight_register Sean Anderson
2025-09-26 10:21 ` Mike Leach
2025-09-25 15:03 ` Sean Anderson [this message]
2025-09-25 16:22 ` [PATCH v5 3/3] coresight: Fix possible deadlock in coresight_panic_cb Leo Yan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250925150342.1845615-4-sean.anderson@linux.dev \
--to=sean.anderson@linux.dev \
--cc=alexander.shishkin@linux.intel.com \
--cc=coresight@lists.linaro.org \
--cc=james.clark@linaro.org \
--cc=lcherian@marvell.com \
--cc=leo.yan@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mike.leach@linaro.org \
--cc=suzuki.poulose@arm.com \
--cc=yeoreum.yun@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.