* [PATCH v2 0/2] perf/dwc_pcie: Fix lockdep warnings in device and event setup
@ 2026-08-11 13:17 Zhanpeng Zhang
2026-08-11 16:06 ` [PATCH v2 1/2] perf/dwc_pcie: Avoid nested bus notifier locking Zhanpeng Zhang
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Zhanpeng Zhang @ 2026-08-11 13:17 UTC (permalink / raw)
To: Shuai Xue, Jing Zhang
Cc: Will Deacon, Mark Rutland, Yicong Yang, Baolin Wang,
Jonathan Cameron, linux-arm-kernel, linux-perf-users,
linux-kernel, Zhanpeng Zhang
The DWC PCIe PMU driver creates a synthetic platform device for each Root
Port from its PCI bus notifier. If a PCI host bridge is registered during
late init, platform device registration enters the platform bus notifier
chain while the PCI bus notifier lock remains held, and lockdep reports
possible recursive locking. Patch 1 moves platform device reconciliation
out of the notifier callback.
The event initialization path has a separate locking issue. It walks a new
group leader's sibling list even though perf does not hold the event context
lock required by for_each_sibling_event(). Patch 2 skips those walks for
group leaders while preserving validation for group members.
The series was tested on a RISC-V system with CONFIG_KASAN,
CONFIG_PROVE_LOCKING, CONFIG_DEBUG_LOCK_ALLOC and CONFIG_LOCKDEP enabled.
Late PCI discovery and a system-wide DWC PCIe PMU perf stat complete without
lockdep reports, and the kernel remains untainted.
Zhanpeng Zhang (2):
perf/dwc_pcie: Avoid nested bus notifier locking
perf/dwc_pcie: Skip sibling walks for new group leaders
drivers/perf/dwc_pcie_pmu.c | 161 +++++++++++++++++++++++++++---------
1 file changed, 122 insertions(+), 39 deletions(-)
--
2.50.1 (Apple Git-155)
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 1/2] perf/dwc_pcie: Avoid nested bus notifier locking
2026-08-11 13:17 [PATCH v2 0/2] perf/dwc_pcie: Fix lockdep warnings in device and event setup Zhanpeng Zhang
@ 2026-08-11 16:06 ` Zhanpeng Zhang
2026-08-13 6:04 ` Yicong Yang
2026-08-11 16:07 ` [PATCH v2 2/2] perf/dwc_pcie: Skip sibling walks for new group leaders Zhanpeng Zhang
2026-10-04 17:15 ` [PATCH v2 0/2] perf/dwc_pcie: Fix lockdep warnings in device and event setup Will Deacon
2 siblings, 1 reply; 6+ messages in thread
From: Zhanpeng Zhang @ 2026-08-11 16:06 UTC (permalink / raw)
To: Shuai Xue, Jing Zhang
Cc: Will Deacon, Mark Rutland, Yicong Yang, Baolin Wang,
Jonathan Cameron, linux-arm-kernel, linux-perf-users,
linux-kernel, Zhanpeng Zhang
dwc_pcie_pmu_notifier() registers a synthetic platform device directly from
the BUS_NOTIFY_ADD_DEVICE callback. Bus notifier callbacks run with the
bus_notifier rwsem held, so platform_device_register_data() enters the
platform bus notifier chain before the PCI bus notifier returns. When PCI
host bridges are registered during late init, lockdep reports this as
possible recursive locking.
Move platform device reconciliation to a work item that runs after the PCI
notifier returns. Serialize it with PCI rescan and removal, and parent each
synthetic device to its Root Port so their lifetimes remain coupled.
During removal, unregister the perf PMU and its CPU hotplug instance before
PCI resources disappear, then defer only platform device destruction.
Disable manual bind controls to preserve that ordering.
Fixes: af9597adc2f1 ("drivers/perf: add DesignWare PCIe PMU driver")
Signed-off-by: Zhanpeng Zhang <zhangzhanpeng.jasper@bytedance.com>
---
Tested on a RISC-V system with CONFIG_KASAN, CONFIG_PROVE_LOCKING,
CONFIG_DEBUG_LOCK_ALLOC and CONFIG_LOCKDEP enabled. Late-init PCI discovery
no longer triggers the nested bus notifier warning.
drivers/perf/dwc_pcie_pmu.c | 149 +++++++++++++++++++++++++++---------
1 file changed, 113 insertions(+), 36 deletions(-)
diff --git a/drivers/perf/dwc_pcie_pmu.c b/drivers/perf/dwc_pcie_pmu.c
index 5385401fa9cf..7b2e28aade73 100644
--- a/drivers/perf/dwc_pcie_pmu.c
+++ b/drivers/perf/dwc_pcie_pmu.c
@@ -13,6 +13,7 @@
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/list.h>
+#include <linux/mutex.h>
#include <linux/pcie-dwc.h>
#include <linux/perf_event.h>
#include <linux/pci.h>
@@ -20,6 +21,7 @@
#include <linux/smp.h>
#include <linux/sysfs.h>
#include <linux/types.h>
+#include <linux/workqueue.h>
#define DWC_PCIE_EVENT_CNT_CTL 0x8
@@ -103,12 +105,15 @@ struct dwc_pcie_pmu {
static int dwc_pcie_pmu_hp_state;
static struct list_head dwc_pcie_dev_info_head =
LIST_HEAD_INIT(dwc_pcie_dev_info_head);
+static DEFINE_MUTEX(dwc_pcie_dev_info_lock);
+static struct work_struct dwc_pcie_pmu_work;
static bool notify;
struct dwc_pcie_dev_info {
struct platform_device *plat_dev;
struct pci_dev *pdev;
struct list_head dev_node;
+ bool removed;
};
static ssize_t cpumask_show(struct device *dev,
@@ -593,6 +598,8 @@ static struct dwc_pcie_dev_info *dwc_pcie_find_dev_info(struct pci_dev *pdev)
{
struct dwc_pcie_dev_info *dev_info;
+ lockdep_assert_held(&dwc_pcie_dev_info_lock);
+
list_for_each_entry(dev_info, &dwc_pcie_dev_info_head, dev_node)
if (dev_info->pdev == pdev)
return dev_info;
@@ -634,7 +641,6 @@ static u16 dwc_pcie_des_cap(struct pci_dev *pdev)
static void dwc_pcie_unregister_dev(struct dwc_pcie_dev_info *dev_info)
{
platform_device_unregister(dev_info->plat_dev);
- list_del(&dev_info->dev_node);
kfree(dev_info);
}
@@ -644,25 +650,92 @@ static int dwc_pcie_register_dev(struct pci_dev *pdev)
struct dwc_pcie_dev_info *dev_info;
u32 sbdf;
- sbdf = (pci_domain_nr(pdev->bus) << 16) | PCI_DEVID(pdev->bus->number, pdev->devfn);
- plat_dev = platform_device_register_simple("dwc_pcie_pmu", sbdf, NULL, 0);
- if (IS_ERR(plat_dev))
- return PTR_ERR(plat_dev);
-
dev_info = kzalloc_obj(*dev_info);
- if (!dev_info) {
- platform_device_unregister(plat_dev);
+ if (!dev_info)
return -ENOMEM;
- }
- /* Cache platform device to handle pci device hotplug */
+ sbdf = (pci_domain_nr(pdev->bus) << 16) |
+ PCI_DEVID(pdev->bus->number, pdev->devfn);
+ plat_dev = platform_device_register_data(&pdev->dev, "dwc_pcie_pmu",
+ sbdf, NULL, 0);
+ if (IS_ERR(plat_dev)) {
+ kfree(dev_info);
+ return PTR_ERR(plat_dev);
+ }
dev_info->plat_dev = plat_dev;
dev_info->pdev = pdev;
- list_add(&dev_info->dev_node, &dwc_pcie_dev_info_head);
+
+ mutex_lock(&dwc_pcie_dev_info_lock);
+ list_add_tail(&dev_info->dev_node, &dwc_pcie_dev_info_head);
+ mutex_unlock(&dwc_pcie_dev_info_lock);
return 0;
}
+static void dwc_pcie_quiesce_dev(struct dwc_pcie_dev_info *dev_info)
+{
+ struct dwc_pcie_pmu *pcie_pmu;
+
+ pcie_pmu = platform_get_drvdata(dev_info->plat_dev);
+ if (!pcie_pmu)
+ return;
+
+ /* Stop config-space accesses before PCI host resources are released. */
+ platform_set_drvdata(dev_info->plat_dev, NULL);
+ devm_release_action(&dev_info->plat_dev->dev, dwc_pcie_unregister_pmu,
+ pcie_pmu);
+ devm_release_action(&dev_info->plat_dev->dev,
+ dwc_pcie_pmu_remove_cpuhp_instance,
+ &pcie_pmu->cpuhp_node);
+}
+
+static int dwc_pcie_reconcile_devices(void)
+{
+ LIST_HEAD(removed_devices);
+ struct dwc_pcie_dev_info *dev_info, *tmp;
+ struct pci_dev *pdev = NULL;
+ int error = 0;
+ int ret;
+
+ pci_lock_rescan_remove();
+ mutex_lock(&dwc_pcie_dev_info_lock);
+ list_for_each_entry_safe(dev_info, tmp, &dwc_pcie_dev_info_head, dev_node)
+ if (dev_info->removed)
+ list_move_tail(&dev_info->dev_node, &removed_devices);
+ mutex_unlock(&dwc_pcie_dev_info_lock);
+
+ list_for_each_entry_safe(dev_info, tmp, &removed_devices, dev_node) {
+ list_del(&dev_info->dev_node);
+ dwc_pcie_unregister_dev(dev_info);
+ }
+
+ for_each_pci_dev(pdev) {
+ if (!dwc_pcie_des_cap(pdev))
+ continue;
+
+ mutex_lock(&dwc_pcie_dev_info_lock);
+ dev_info = dwc_pcie_find_dev_info(pdev);
+ mutex_unlock(&dwc_pcie_dev_info_lock);
+ if (dev_info)
+ continue;
+
+ ret = dwc_pcie_register_dev(pdev);
+ if (ret) {
+ pci_warn(pdev, "failed to register DWC PCIe PMU: %d\n", ret);
+ if (!error)
+ error = ret;
+ }
+ }
+ pci_unlock_rescan_remove();
+
+ return error;
+}
+
+static void dwc_pcie_update_devices(struct work_struct *work)
+{
+ dwc_pcie_reconcile_devices();
+}
+
static int dwc_pcie_pmu_notifier(struct notifier_block *nb,
unsigned long action, void *data)
{
@@ -674,14 +747,19 @@ static int dwc_pcie_pmu_notifier(struct notifier_block *nb,
case BUS_NOTIFY_ADD_DEVICE:
if (!dwc_pcie_des_cap(pdev))
return NOTIFY_DONE;
- if (dwc_pcie_register_dev(pdev))
- return NOTIFY_BAD;
+ schedule_work(&dwc_pcie_pmu_work);
break;
case BUS_NOTIFY_DEL_DEVICE:
+ mutex_lock(&dwc_pcie_dev_info_lock);
dev_info = dwc_pcie_find_dev_info(pdev);
+ if (dev_info) {
+ dwc_pcie_quiesce_dev(dev_info);
+ dev_info->removed = true;
+ }
+ mutex_unlock(&dwc_pcie_dev_info_lock);
if (!dev_info)
return NOTIFY_DONE;
- dwc_pcie_unregister_dev(dev_info);
+ schedule_work(&dwc_pcie_pmu_work);
break;
}
@@ -702,18 +780,14 @@ static int dwc_pcie_pmu_probe(struct platform_device *plat_dev)
int ret;
sbdf = plat_dev->id;
- pdev = pci_get_domain_bus_and_slot(sbdf >> 16, PCI_BUS_NUM(sbdf & 0xffff),
- sbdf & 0xff);
- if (!pdev) {
- pr_err("No pdev found for the sbdf 0x%x\n", sbdf);
+ if (!plat_dev->dev.parent || plat_dev->dev.parent->bus != &pci_bus_type)
return -ENODEV;
- }
+ pdev = to_pci_dev(plat_dev->dev.parent);
vsec = dwc_pcie_des_cap(pdev);
if (!vsec)
return -ENODEV;
- pci_dev_put(pdev);
name = devm_kasprintf(&plat_dev->dev, GFP_KERNEL, "dwc_rootport_%x", sbdf);
if (!name)
return -ENOMEM;
@@ -766,6 +840,8 @@ static int dwc_pcie_pmu_probe(struct platform_device *plat_dev)
if (ret)
return ret;
+ platform_set_drvdata(plat_dev, pcie_pmu);
+
return 0;
}
@@ -815,7 +891,11 @@ static int dwc_pcie_pmu_offline_cpu(unsigned int cpu, struct hlist_node *cpuhp_n
static struct platform_driver dwc_pcie_pmu_driver = {
.probe = dwc_pcie_pmu_probe,
- .driver = {.name = "dwc_pcie_pmu",},
+ .driver = {
+ .name = "dwc_pcie_pmu",
+ .probe_type = PROBE_FORCE_SYNCHRONOUS,
+ .suppress_bind_attrs = true,
+ },
};
static void dwc_pcie_cleanup_devices(void)
@@ -823,32 +903,21 @@ static void dwc_pcie_cleanup_devices(void)
struct dwc_pcie_dev_info *dev_info, *tmp;
list_for_each_entry_safe(dev_info, tmp, &dwc_pcie_dev_info_head, dev_node) {
+ list_del(&dev_info->dev_node);
dwc_pcie_unregister_dev(dev_info);
}
}
static int __init dwc_pcie_pmu_init(void)
{
- struct pci_dev *pdev = NULL;
int ret;
- for_each_pci_dev(pdev) {
- if (!dwc_pcie_des_cap(pdev))
- continue;
-
- ret = dwc_pcie_register_dev(pdev);
- if (ret) {
- pci_dev_put(pdev);
- goto err_cleanup;
- }
- }
-
ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
"perf/dwc_pcie_pmu:online",
dwc_pcie_pmu_online_cpu,
dwc_pcie_pmu_offline_cpu);
if (ret < 0)
- goto err_cleanup;
+ return ret;
dwc_pcie_pmu_hp_state = ret;
@@ -856,19 +925,26 @@ static int __init dwc_pcie_pmu_init(void)
if (ret)
goto err_remove_cpuhp;
+ INIT_WORK(&dwc_pcie_pmu_work, dwc_pcie_update_devices);
ret = bus_register_notifier(&pci_bus_type, &dwc_pcie_pmu_nb);
if (ret)
goto err_unregister_driver;
notify = true;
+ ret = dwc_pcie_reconcile_devices();
+ if (ret)
+ goto err_unregister_notifier;
return 0;
+err_unregister_notifier:
+ bus_unregister_notifier(&pci_bus_type, &dwc_pcie_pmu_nb);
+ notify = false;
+ cancel_work_sync(&dwc_pcie_pmu_work);
+ dwc_pcie_cleanup_devices();
err_unregister_driver:
platform_driver_unregister(&dwc_pcie_pmu_driver);
err_remove_cpuhp:
cpuhp_remove_multi_state(dwc_pcie_pmu_hp_state);
-err_cleanup:
- dwc_pcie_cleanup_devices();
return ret;
}
@@ -876,6 +952,7 @@ static void __exit dwc_pcie_pmu_exit(void)
{
if (notify)
bus_unregister_notifier(&pci_bus_type, &dwc_pcie_pmu_nb);
+ cancel_work_sync(&dwc_pcie_pmu_work);
dwc_pcie_cleanup_devices();
platform_driver_unregister(&dwc_pcie_pmu_driver);
cpuhp_remove_multi_state(dwc_pcie_pmu_hp_state);
--
2.50.1 (Apple Git-155)
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 2/2] perf/dwc_pcie: Skip sibling walks for new group leaders
2026-08-11 13:17 [PATCH v2 0/2] perf/dwc_pcie: Fix lockdep warnings in device and event setup Zhanpeng Zhang
2026-08-11 16:06 ` [PATCH v2 1/2] perf/dwc_pcie: Avoid nested bus notifier locking Zhanpeng Zhang
@ 2026-08-11 16:07 ` Zhanpeng Zhang
2026-08-13 6:15 ` Yicong Yang
2026-10-04 17:15 ` [PATCH v2 0/2] perf/dwc_pcie: Fix lockdep warnings in device and event setup Will Deacon
2 siblings, 1 reply; 6+ messages in thread
From: Zhanpeng Zhang @ 2026-08-11 16:07 UTC (permalink / raw)
To: Shuai Xue, Jing Zhang
Cc: Will Deacon, Mark Rutland, Yicong Yang, Baolin Wang,
Jonathan Cameron, linux-arm-kernel, linux-perf-users,
linux-kernel, Zhanpeng Zhang
for_each_sibling_event() requires the event context lock to be held.
perf_try_init_event() only takes that lock when initializing a group
member.
The DWC PCIe PMU walks the sibling list twice for every event, including a
new group leader whose event_init() method runs without the lock. Although
the leader cannot have siblings yet, the lock assertion is evaluated before
the empty list is walked and produces two lockdep warnings.
Skip both sibling walks while initializing a group leader. Group member
validation is unchanged and continues to run with the event context mutex
held.
Fixes: af9597adc2f1 ("drivers/perf: add DesignWare PCIe PMU driver")
Signed-off-by: Zhanpeng Zhang <zhangzhanpeng.jasper@bytedance.com>
---
A system-wide DWC PCIe PMU perf stat completed successfully with the same
debug configuration, without lockdep reports or kernel taint.
drivers/perf/dwc_pcie_pmu.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/perf/dwc_pcie_pmu.c b/drivers/perf/dwc_pcie_pmu.c
index 7b2e28aade73..a6667ac19a99 100644
--- a/drivers/perf/dwc_pcie_pmu.c
+++ b/drivers/perf/dwc_pcie_pmu.c
@@ -417,6 +417,10 @@ static int dwc_pcie_pmu_validate_group(struct perf_event *event)
if (dwc_pcie_pmu_validate_add_lane_event(leader, val_lane_events))
return -ENOSPC;
+ /* A new group leader cannot have any siblings yet. */
+ if (event == leader)
+ return 0;
+
for_each_sibling_event(sibling, leader) {
type = DWC_PCIE_EVENT_TYPE(sibling);
if (type == DWC_PCIE_TIME_BASE_EVENT) {
@@ -452,9 +456,11 @@ static int dwc_pcie_pmu_event_init(struct perf_event *event)
if (event->cpu < 0 || event->attach_state & PERF_ATTACH_TASK)
return -EINVAL;
- for_each_sibling_event(sibling, event->group_leader) {
- if (sibling->pmu != event->pmu && !is_software_event(sibling))
- return -EINVAL;
+ if (event != event->group_leader) {
+ for_each_sibling_event(sibling, event->group_leader) {
+ if (sibling->pmu != event->pmu && !is_software_event(sibling))
+ return -EINVAL;
+ }
}
if (type < 0 || type >= DWC_PCIE_EVENT_TYPE_MAX)
--
2.50.1 (Apple Git-155)
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] perf/dwc_pcie: Avoid nested bus notifier locking
2026-08-11 16:06 ` [PATCH v2 1/2] perf/dwc_pcie: Avoid nested bus notifier locking Zhanpeng Zhang
@ 2026-08-13 6:04 ` Yicong Yang
0 siblings, 0 replies; 6+ messages in thread
From: Yicong Yang @ 2026-08-13 6:04 UTC (permalink / raw)
To: Zhanpeng Zhang
Cc: Shuai Xue, Jing Zhang, yang.yicong, Will Deacon, Mark Rutland,
Baolin Wang, Jonathan Cameron, linux-arm-kernel,
linux-perf-users, linux-kernel
On 8/12/26 12:06 AM, Zhanpeng Zhang wrote:
> dwc_pcie_pmu_notifier() registers a synthetic platform device directly from
> the BUS_NOTIFY_ADD_DEVICE callback. Bus notifier callbacks run with the
> bus_notifier rwsem held, so platform_device_register_data() enters the
> platform bus notifier chain before the PCI bus notifier returns. When PCI
> host bridges are registered during late init, lockdep reports this as
> possible recursive locking.
>
> Move platform device reconciliation to a work item that runs after the PCI
> notifier returns. Serialize it with PCI rescan and removal, and parent each
> synthetic device to its Root Port so their lifetimes remain coupled.
>
> During removal, unregister the perf PMU and its CPU hotplug instance before
> PCI resources disappear, then defer only platform device destruction.
> Disable manual bind controls to preserve that ordering.
>
> Fixes: af9597adc2f1 ("drivers/perf: add DesignWare PCIe PMU driver")
> Signed-off-by: Zhanpeng Zhang <zhangzhanpeng.jasper@bytedance.com>
please attach the lockdep warning/trace in the commit for better
understanding the issue..
> ---
> Tested on a RISC-V system with CONFIG_KASAN, CONFIG_PROVE_LOCKING,
> CONFIG_DEBUG_LOCK_ALLOC and CONFIG_LOCKDEP enabled. Late-init PCI discovery
> no longer triggers the nested bus notifier warning.
>
> drivers/perf/dwc_pcie_pmu.c | 149 +++++++++++++++++++++++++++---------
> 1 file changed, 113 insertions(+), 36 deletions(-)
>
[...]
>
> @@ -815,7 +891,11 @@ static int dwc_pcie_pmu_offline_cpu(unsigned int cpu, struct hlist_node *cpuhp_n
>
> static struct platform_driver dwc_pcie_pmu_driver = {
> .probe = dwc_pcie_pmu_probe,
> - .driver = {.name = "dwc_pcie_pmu",},
> + .driver = {
> + .name = "dwc_pcie_pmu",
> + .probe_type = PROBE_FORCE_SYNCHRONOUS,
this looks irrelevant to the issue to resolve. need description here.
I suppose this issue is because both the PMU and the PCIe controller
are on the platform bus, right? If we switch the PMU to the faux device
interface [1] this could be solved?
thanks.
[1] https://lore.kernel.org/all/20260708084507.98242-4-yang.yicong@picoheart.com/
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] perf/dwc_pcie: Skip sibling walks for new group leaders
2026-08-11 16:07 ` [PATCH v2 2/2] perf/dwc_pcie: Skip sibling walks for new group leaders Zhanpeng Zhang
@ 2026-08-13 6:15 ` Yicong Yang
0 siblings, 0 replies; 6+ messages in thread
From: Yicong Yang @ 2026-08-13 6:15 UTC (permalink / raw)
To: Zhanpeng Zhang
Cc: Shuai Xue, Jing Zhang, yang.yicong, Will Deacon, Mark Rutland,
Yicong Yang, Baolin Wang, Jonathan Cameron, linux-arm-kernel,
linux-perf-users, linux-kernel
On 8/12/26 12:07 AM, Zhanpeng Zhang wrote:
> for_each_sibling_event() requires the event context lock to be held.
> perf_try_init_event() only takes that lock when initializing a group
> member.
newline here for a new paragraph.
> The DWC PCIe PMU walks the sibling list twice for every event, including a
> new group leader whose event_init() method runs without the lock. Although
> the leader cannot have siblings yet, the lock assertion is evaluated before
> the empty list is walked and produces two lockdep warnings.
>
> Skip both sibling walks while initializing a group leader. Group member
> validation is unchanged and continues to run with the event context mutex
> held.
>
> Fixes: af9597adc2f1 ("drivers/perf: add DesignWare PCIe PMU driver")
> Signed-off-by: Zhanpeng Zhang <zhangzhanpeng.jasper@bytedance.com>
looks good to me.
Reviewed-by: Yicong Yang <yang.yicong@picoheart.com>
> ---
> A system-wide DWC PCIe PMU perf stat completed successfully with the same
> debug configuration, without lockdep reports or kernel taint.
>
> drivers/perf/dwc_pcie_pmu.c | 12 +++++++++---
> 1 file changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/perf/dwc_pcie_pmu.c b/drivers/perf/dwc_pcie_pmu.c
> index 7b2e28aade73..a6667ac19a99 100644
> --- a/drivers/perf/dwc_pcie_pmu.c
> +++ b/drivers/perf/dwc_pcie_pmu.c
> @@ -417,6 +417,10 @@ static int dwc_pcie_pmu_validate_group(struct perf_event *event)
> if (dwc_pcie_pmu_validate_add_lane_event(leader, val_lane_events))
> return -ENOSPC;
>
> + /* A new group leader cannot have any siblings yet. */
> + if (event == leader)
> + return 0;
> +
> for_each_sibling_event(sibling, leader) {
> type = DWC_PCIE_EVENT_TYPE(sibling);
> if (type == DWC_PCIE_TIME_BASE_EVENT) {
> @@ -452,9 +456,11 @@ static int dwc_pcie_pmu_event_init(struct perf_event *event)
> if (event->cpu < 0 || event->attach_state & PERF_ATTACH_TASK)
> return -EINVAL;
>
> - for_each_sibling_event(sibling, event->group_leader) {
> - if (sibling->pmu != event->pmu && !is_software_event(sibling))
> - return -EINVAL;
> + if (event != event->group_leader) {
> + for_each_sibling_event(sibling, event->group_leader) {
> + if (sibling->pmu != event->pmu && !is_software_event(sibling))
> + return -EINVAL;
> + }
personally feel better to make this check into dwc_pcie_pmu_validate_group().
thanks.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 0/2] perf/dwc_pcie: Fix lockdep warnings in device and event setup
2026-08-11 13:17 [PATCH v2 0/2] perf/dwc_pcie: Fix lockdep warnings in device and event setup Zhanpeng Zhang
2026-08-11 16:06 ` [PATCH v2 1/2] perf/dwc_pcie: Avoid nested bus notifier locking Zhanpeng Zhang
2026-08-11 16:07 ` [PATCH v2 2/2] perf/dwc_pcie: Skip sibling walks for new group leaders Zhanpeng Zhang
@ 2026-10-04 17:15 ` Will Deacon
2 siblings, 0 replies; 6+ messages in thread
From: Will Deacon @ 2026-10-04 17:15 UTC (permalink / raw)
To: Zhanpeng Zhang
Cc: Shuai Xue, Jing Zhang, Mark Rutland, Yicong Yang, Baolin Wang,
Jonathan Cameron, linux-arm-kernel, linux-perf-users,
linux-kernel
On Tue, Aug 11, 2026 at 09:17:12PM +0800, Zhanpeng Zhang wrote:
> The DWC PCIe PMU driver creates a synthetic platform device for each Root
> Port from its PCI bus notifier. If a PCI host bridge is registered during
> late init, platform device registration enters the platform bus notifier
> chain while the PCI bus notifier lock remains held, and lockdep reports
> possible recursive locking. Patch 1 moves platform device reconciliation
> out of the notifier callback.
>
> The event initialization path has a separate locking issue. It walks a new
> group leader's sibling list even though perf does not hold the event context
> lock required by for_each_sibling_event(). Patch 2 skips those walks for
> group leaders while preserving validation for group members.
>
> The series was tested on a RISC-V system with CONFIG_KASAN,
> CONFIG_PROVE_LOCKING, CONFIG_DEBUG_LOCK_ALLOC and CONFIG_LOCKDEP enabled.
> Late PCI discovery and a system-wide DWC PCIe PMU perf stat complete without
> lockdep reports, and the kernel remains untainted.
>
> Zhanpeng Zhang (2):
> perf/dwc_pcie: Avoid nested bus notifier locking
> perf/dwc_pcie: Skip sibling walks for new group leaders
>
> drivers/perf/dwc_pcie_pmu.c | 161 +++++++++++++++++++++++++++---------
> 1 file changed, 122 insertions(+), 39 deletions(-)
This doesn't seem to apply. Please can you send an updated version?
Will
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-10-04 17:15 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-11 13:17 [PATCH v2 0/2] perf/dwc_pcie: Fix lockdep warnings in device and event setup Zhanpeng Zhang
2026-08-11 16:06 ` [PATCH v2 1/2] perf/dwc_pcie: Avoid nested bus notifier locking Zhanpeng Zhang
2026-08-13 6:04 ` Yicong Yang
2026-08-11 16:07 ` [PATCH v2 2/2] perf/dwc_pcie: Skip sibling walks for new group leaders Zhanpeng Zhang
2026-08-13 6:15 ` Yicong Yang
2026-10-04 17:15 ` [PATCH v2 0/2] perf/dwc_pcie: Fix lockdep warnings in device and event setup Will Deacon
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®