]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
perf/x86/intel/uncore: Fix PCI device refcount leak in UPI discovery
authorZide Chen <zide.chen@intel.com>
Tue, 2 Jun 2026 14:49:04 +0000 (07:49 -0700)
committerPeter Zijlstra <peterz@infradead.org>
Thu, 4 Jun 2026 09:38:37 +0000 (11:38 +0200)
pci_get_domain_bus_and_slot() increments the reference count of the
returned PCI device and therefore requires a matching pci_dev_put().

In skx_upi_topology_cb() and discover_upi_topology(), the lookup is
performed inside a loop, but pci_dev_put() is only called once after
the loop. As a result, references from all previous iterations are
leaked.

Move pci_dev_put(dev) into the if (dev) block immediately after
upi_fill_topology() returns.

Opportunistically, fix uninitialized variable in skx_upi_topology_cb().

Fixes: 4cfce57fa42d ("perf/x86/intel/uncore: Enable UPI topology discovery for Skylake Server")
Fixes: f680b6e6062e ("perf/x86/intel/uncore: Enable UPI topology discovery for Icelake Server")
Signed-off-by: Zide Chen <zide.chen@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20260602144908.263680-4-zide.chen@intel.com
arch/x86/events/intel/uncore_snbep.c

index 215d33e260ede795a49831e9bdf045901355d47f..c9ce206fcbb6e76098f562074bb9f7adab79c4bf 100644 (file)
@@ -4261,7 +4261,7 @@ err:
 static int skx_upi_topology_cb(struct intel_uncore_type *type, int segment,
                                int die, u64 cpu_bus_msr)
 {
-       int idx, ret;
+       int idx, ret = 0;
        struct intel_uncore_topology *upi;
        unsigned int devfn;
        struct pci_dev *dev = NULL;
@@ -4274,12 +4274,12 @@ static int skx_upi_topology_cb(struct intel_uncore_type *type, int segment,
                dev = pci_get_domain_bus_and_slot(segment, bus, devfn);
                if (dev) {
                        ret = upi_fill_topology(dev, upi, idx);
+                       pci_dev_put(dev);
                        if (ret)
                                break;
                }
        }
 
-       pci_dev_put(dev);
        return ret;
 }
 
@@ -5499,6 +5499,7 @@ 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);
                                if (ret)
                                        goto err;
                        }
@@ -5506,7 +5507,6 @@ static int discover_upi_topology(struct intel_uncore_type *type, int ubox_did, i
        }
 err:
        pci_dev_put(ubox);
-       pci_dev_put(dev);
        return ret;
 }