* [PATCH v4 0/2] coresight: Fix possible deadlock in coresight_panic_cb @ 2025-09-19 16:06 Sean Anderson 2025-09-19 16:06 ` [PATCH v4 1/2] coresight: Fix fwnode leak in coresight_register error path Sean Anderson 2025-09-19 16:06 ` [PATCH v4 2/2] coresight: Fix possible deadlock in coresight_panic_cb Sean Anderson 0 siblings, 2 replies; 5+ messages in thread From: Sean Anderson @ 2025-09-19 16:06 UTC (permalink / raw) To: Suzuki K Poulose, coresight, linux-arm-kernel Cc: James Clark, Alexander Shishkin, Yeoreum Yun, Leo Yan, Linu Cherian, Mike Leach, linux-kernel, Sean Anderson This time with the notifier in csdev. Changes in v4: - Fix fwnode leak in coresight_register error path - 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 Sean Anderson (2): coresight: Fix fwnode leak in coresight_register error path coresight: Fix possible deadlock in coresight_panic_cb drivers/hwtracing/coresight/coresight-core.c | 69 ++++++++------------ include/linux/coresight.h | 2 + 2 files changed, 28 insertions(+), 43 deletions(-) -- 2.35.1.1320.gc452695387.dirty ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v4 1/2] coresight: Fix fwnode leak in coresight_register error path 2025-09-19 16:06 [PATCH v4 0/2] coresight: Fix possible deadlock in coresight_panic_cb Sean Anderson @ 2025-09-19 16:06 ` Sean Anderson 2025-09-22 10:06 ` Leo Yan 2025-09-19 16:06 ` [PATCH v4 2/2] coresight: Fix possible deadlock in coresight_panic_cb Sean Anderson 1 sibling, 1 reply; 5+ messages in thread From: Sean Anderson @ 2025-09-19 16:06 UTC (permalink / raw) To: Suzuki K Poulose, coresight, linux-arm-kernel Cc: James Clark, Alexander Shishkin, Yeoreum Yun, Leo Yan, Linu Cherian, Mike Leach, linux-kernel, Sean Anderson If registering the CPU map fails, we need to put the fwnode. free_percpu works when called with a NULL pointer, so just use coresight_device_release. Fixes: 5ad628a76176 ("coresight: Use per-sink trace ID maps for Perf sessions") Signed-off-by: Sean Anderson <sean.anderson@linux.dev> --- Changes in v4: - New drivers/hwtracing/coresight/coresight-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index fa758cc21827..022c8384b98d 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -1352,7 +1352,7 @@ struct coresight_device *coresight_register(struct coresight_desc *desc) raw_spin_lock_init(&csdev->perf_sink_id_map.lock); csdev->perf_sink_id_map.cpu_map = alloc_percpu(atomic_t); if (!csdev->perf_sink_id_map.cpu_map) { - kfree(csdev); + coresight_device_release(&csdev->dev); ret = -ENOMEM; goto err_out; } -- 2.35.1.1320.gc452695387.dirty ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v4 1/2] coresight: Fix fwnode leak in coresight_register error path 2025-09-19 16:06 ` [PATCH v4 1/2] coresight: Fix fwnode leak in coresight_register error path Sean Anderson @ 2025-09-22 10:06 ` Leo Yan 0 siblings, 0 replies; 5+ messages in thread From: Leo Yan @ 2025-09-22 10:06 UTC (permalink / raw) To: Sean Anderson Cc: Suzuki K Poulose, coresight, linux-arm-kernel, James Clark, Alexander Shishkin, Yeoreum Yun, Linu Cherian, Mike Leach, linux-kernel On Fri, Sep 19, 2025 at 12:06:52PM -0400, Sean Anderson wrote: > If registering the CPU map fails, we need to put the fwnode. free_percpu > works when called with a NULL pointer, so just use > coresight_device_release. > > Fixes: 5ad628a76176 ("coresight: Use per-sink trace ID maps for Perf sessions") > Signed-off-by: Sean Anderson <sean.anderson@linux.dev> I have a patch that fixes the same issue: https://lore.kernel.org/linux-arm-kernel/20250512154108.23920-2-leo.yan@arm.com/ The difference in my patch is about the sequence: first it allocates the resource, then increases the fw node's reference count. During release, it first decreases the reference count, and then safely releases the resource. After comparing your patch, I still think the above reason is valid. That said, I agree we should put this fixing before the panic notifier fix. This would be friendly for backporting. Thanks, Leo > --- > > Changes in v4: > - New > > drivers/hwtracing/coresight/coresight-core.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c > index fa758cc21827..022c8384b98d 100644 > --- a/drivers/hwtracing/coresight/coresight-core.c > +++ b/drivers/hwtracing/coresight/coresight-core.c > @@ -1352,7 +1352,7 @@ struct coresight_device *coresight_register(struct coresight_desc *desc) > raw_spin_lock_init(&csdev->perf_sink_id_map.lock); > csdev->perf_sink_id_map.cpu_map = alloc_percpu(atomic_t); > if (!csdev->perf_sink_id_map.cpu_map) { > - kfree(csdev); > + coresight_device_release(&csdev->dev); > ret = -ENOMEM; > goto err_out; > } > -- > 2.35.1.1320.gc452695387.dirty > ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v4 2/2] coresight: Fix possible deadlock in coresight_panic_cb 2025-09-19 16:06 [PATCH v4 0/2] coresight: Fix possible deadlock in coresight_panic_cb Sean Anderson 2025-09-19 16:06 ` [PATCH v4 1/2] coresight: Fix fwnode leak in coresight_register error path Sean Anderson @ 2025-09-19 16:06 ` Sean Anderson 2025-09-22 10:34 ` Leo Yan 1 sibling, 1 reply; 5+ messages in thread From: Sean Anderson @ 2025-09-19 16:06 UTC (permalink / raw) To: Suzuki K Poulose, coresight, linux-arm-kernel Cc: James Clark, Alexander Shishkin, Yeoreum Yun, Leo Yan, Linu Cherian, Mike Leach, linux-kernel, Sean Anderson 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 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, 27 insertions(+), 42 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index 022c8384b98d..6dfb1198c16e 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -1046,8 +1046,11 @@ static void coresight_device_release(struct device *dev) { struct coresight_device *csdev = to_coresight_device(dev); - fwnode_handle_put(csdev->dev.fwnode); + 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,16 @@ 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); + + panic_ops(csdev)->sync(csdev); + return NOTIFY_DONE; +} + struct coresight_device *coresight_register(struct coresight_desc *desc) { int ret; @@ -1357,6 +1370,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 +1587,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 +1599,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 +1613,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 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v4 2/2] coresight: Fix possible deadlock in coresight_panic_cb 2025-09-19 16:06 ` [PATCH v4 2/2] coresight: Fix possible deadlock in coresight_panic_cb Sean Anderson @ 2025-09-22 10:34 ` Leo Yan 0 siblings, 0 replies; 5+ messages in thread From: Leo Yan @ 2025-09-22 10:34 UTC (permalink / raw) To: Sean Anderson Cc: Suzuki K Poulose, coresight, linux-arm-kernel, James Clark, Alexander Shishkin, Yeoreum Yun, Linu Cherian, Mike Leach, linux-kernel On Fri, Sep 19, 2025 at 12:06:53PM -0400, Sean Anderson wrote: [...] > diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c > index 022c8384b98d..6dfb1198c16e 100644 > --- a/drivers/hwtracing/coresight/coresight-core.c > +++ b/drivers/hwtracing/coresight/coresight-core.c > @@ -1046,8 +1046,11 @@ static void coresight_device_release(struct device *dev) > { > struct coresight_device *csdev = to_coresight_device(dev); > > - fwnode_handle_put(csdev->dev.fwnode); > + 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); The moving fwnode_handle_put() is irrelvant to panic notifier fix, should be moved out from this patch. > kfree(csdev); > } > > @@ -1315,6 +1318,16 @@ 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); > + Need to check device mode: if (coresight_get_mode(csdev) == CS_MODE_DISABLED) return NOTIFY_DONE; The rest is fine for me. Thanks, Leo > + panic_ops(csdev)->sync(csdev); > + return NOTIFY_DONE; > +} > + > struct coresight_device *coresight_register(struct coresight_desc *desc) > { > int ret; > @@ -1357,6 +1370,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 +1587,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 +1599,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 +1613,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 > ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-09-22 10:34 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-09-19 16:06 [PATCH v4 0/2] coresight: Fix possible deadlock in coresight_panic_cb Sean Anderson 2025-09-19 16:06 ` [PATCH v4 1/2] coresight: Fix fwnode leak in coresight_register error path Sean Anderson 2025-09-22 10:06 ` Leo Yan 2025-09-19 16:06 ` [PATCH v4 2/2] coresight: Fix possible deadlock in coresight_panic_cb Sean Anderson 2025-09-22 10:34 ` Leo Yan
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).