From: Ira Weiny <ira.weiny@xxxxxxxxx> commit ced085ef369af7a2b6da962ec2fbd01339f60693 upstream. The "goto error" pattern is notorious for introducing subtle resource leaks. Use the new cleanup.h helpers for PCI device reference counts. Similar to the new put_device() cleanup helper, __free(put_device), define the same for PCI devices, __free(pci_dev_put). These helpers eliminate the need for "goto free;" patterns. For example, a 'struct pci_dev *' instance declared as: struct pci_dev *pdev __free(pci_dev_put) = NULL; ...will automatically call pci_dev_put() if @pdev is non-NULL when @pdev goes out of scope (automatic variable scope). If a function wants to invoke pci_dev_put() on error, but return @pdev on success, it can do: return no_free_ptr(pdev); ...or: return_ptr(pdev); For potential cleanup opportunity there are 587 open-coded calls to pci_dev_put() in the kernel with 65 instances within 10 lines of a goto statement with the CXL driver threatening to add another one. Cc: Bjorn Helgaas <bhelgaas@xxxxxxxxxx> Signed-off-by: Ira Weiny <ira.weiny@xxxxxxxxx> Link: https://lore.kernel.org/r/20231220-cxl-cper-v5-8-1bb8a4ca2c7a@xxxxxxxxx [djbw: rewrite changelog] Acked-by: Bjorn Helgaas <bhelgaas@xxxxxxxxxx> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@xxxxxxxxxx> Acked-by: Ard Biesheuvel <ardb@xxxxxxxxxx> Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx> [lukas: drop DEFINE_GUARD() helper as pci_dev_lock() doesn't exist in v5.10] Signed-off-by: Lukas Wunner <lukas@xxxxxxxxx> --- include/linux/pci.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/pci.h b/include/linux/pci.h index 30bc462fb196..f497aaf1d032 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1069,6 +1069,7 @@ int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge); u8 pci_common_swizzle(struct pci_dev *dev, u8 *pinp); struct pci_dev *pci_dev_get(struct pci_dev *dev); void pci_dev_put(struct pci_dev *dev); +DEFINE_FREE(pci_dev_put, struct pci_dev *, if (_T) pci_dev_put(_T)) void pci_remove_bus(struct pci_bus *b); void pci_stop_and_remove_bus_device(struct pci_dev *dev); void pci_stop_and_remove_bus_device_locked(struct pci_dev *dev); -- 2.43.0