Thread (5 messages) 5 messages, 2 authors, 2024-07-30
STALE715d REVIEWED: 11 (11M)

[PATCH 5.10-stable 2/3] PCI: Introduce cleanup helper for device reference counts

From: Lukas Wunner <lukas@wunner.de>
Date: 2024-07-30 09:32:27
Also in: linux-pci
Subsystem: pci subsystem, the rest · Maintainers: Bjorn Helgaas, Linus Torvalds

From: Ira Weiny <redacted>

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@google.com>
Signed-off-by: Ira Weiny <redacted>
Link: https://lore.kernel.org/r/20231220-cxl-cper-v5-8-1bb8a4ca2c7a@intel.com (local)
[djbw: rewrite changelog]
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Dan Williams <redacted>
[lukas: drop DEFINE_GUARD() helper as pci_dev_lock() doesn't exist in v5.10]
Signed-off-by: Lukas Wunner <lukas@wunner.de>
---
 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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help