[PATCH] perf/x86/intel/uncore: Fix reference leak in discover_upi_topology()
From: Wentao Liang
Date: Thu Jun 25 2026 - 03:55:33 EST
In discover_upi_topology(), pci_get_domain_bus_and_slot() returns a PCI
device with its reference count incremented. The caller must call
pci_dev_put() after use.
However, the inner loop overwrites dev without releasing the previous
reference, causing leaks:
- Between inner loop iterations within the same outer loop iteration.
- Between outer loop iterations (dev from a previous ubox's inner
loop is overwritten at the start of the next inner loop).
- On the normal exit path from the while loop (the last dev is never
put before falling through to err:).
Fix by calling pci_dev_put(dev) and clearing dev after upi_fill_topology()
succeeds, so each reference is released immediately after use. The error
path (goto err) already calls pci_dev_put(dev) and remains correct since
dev is set to NULL after release, making the subsequent put a no-op.
The similar sad_cfg_iio_topology() function does not have this problem
because it uses a single pci_get_device() loop and releases the last
reference correctly in all exit paths.
Cc: stable@xxxxxxxxxxxxxxx
Fixes: fdd041028f22 ("perf/x86/intel/uncore: Factor out topology_gidnid_map()")
Signed-off-by: Wentao Liang <vulab@xxxxxxxxxxx>
---
arch/x86/events/intel/uncore_snbep.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index 215d33e260ed..1561bda43835 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -5499,6 +5499,8 @@ static int discover_upi_topology(struct intel_uncore_type *type, int ubox_did, i
devfn);
if (dev) {
ret = upi_fill_topology(dev, upi, idx);
+ pci_dev_put(dev);
+ dev = NULL;
if (ret)
goto err;
}
--
2.39.5 (Apple Git-154)