]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
PCI: Cache offset of Resizable BAR capability
authorBjorn Helgaas <bhelgaas@google.com>
Sat, 15 Feb 2025 00:03:01 +0000 (18:03 -0600)
committerBjorn Helgaas <bhelgaas@google.com>
Mon, 10 Mar 2025 18:41:47 +0000 (13:41 -0500)
Previously most resizable BAR interfaces (pci_rebar_get_possible_sizes(),
pci_rebar_set_size(), etc) as well as pci_restore_state() searched config
space for a Resizable BAR capability.  Most devices don't have such a
capability, so this is wasted effort, especially for pci_restore_state().

Search for a Resizable BAR capability once at enumeration-time and cache
the offset so we don't have to search every time we need it.  No functional
change intended.

Link: https://lore.kernel.org/r/20250215000301.175097-3-helgaas@kernel.org
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/probe.c
include/linux/pci.h

index 869d204a70a372d240b1a6988a2159a79999e1ca..cda4d9af50b5167cdebac361e9d715d3b32ac9aa 100644 (file)
@@ -1871,7 +1871,7 @@ static void pci_restore_rebar_state(struct pci_dev *pdev)
        unsigned int pos, nbars, i;
        u32 ctrl;
 
-       pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
+       pos = pdev->rebar_cap;
        if (!pos)
                return;
 
@@ -3718,6 +3718,11 @@ void pci_acs_init(struct pci_dev *dev)
        pci_enable_acs(dev);
 }
 
+void pci_rebar_init(struct pci_dev *pdev)
+{
+       pdev->rebar_cap = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
+}
+
 /**
  * pci_rebar_find_pos - find position of resize ctrl reg for BAR
  * @pdev: PCI device
@@ -3732,7 +3737,7 @@ static int pci_rebar_find_pos(struct pci_dev *pdev, int bar)
        unsigned int pos, nbars, i;
        u32 ctrl;
 
-       pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
+       pos = pdev->rebar_cap;
        if (!pos)
                return -ENOTSUPP;
 
index 01e51db8d285af54673db3ea526ceda073c94ec9..d7b46ddfd6d2d356215dc603d8cdef1bb4df463f 100644 (file)
@@ -799,6 +799,7 @@ static inline int acpi_get_rc_resources(struct device *dev, const char *hid,
 }
 #endif
 
+void pci_rebar_init(struct pci_dev *pdev);
 int pci_rebar_get_current_size(struct pci_dev *pdev, int bar);
 int pci_rebar_set_size(struct pci_dev *pdev, int bar, int size);
 static inline u64 pci_rebar_size_to_bytes(int size)
index 0b013b196d0052d9cc20c7b7d4c8d9fb942cc337..5f04b8d9c7368b7a4094436079d4ae33decb440d 100644 (file)
@@ -2566,6 +2566,7 @@ static void pci_init_capabilities(struct pci_dev *dev)
        pci_rcec_init(dev);             /* Root Complex Event Collector */
        pci_doe_init(dev);              /* Data Object Exchange */
        pci_tph_init(dev);              /* TLP Processing Hints */
+       pci_rebar_init(dev);            /* Resizable BAR */
 
        pcie_report_downtraining(dev);
        pci_init_reset_methods(dev);
index 47b31ad724fa5bf7abd7c3dc572947551b0f2148..9e5bbd996c8368f02ab57f09e147f62687684342 100644 (file)
@@ -353,6 +353,7 @@ struct pci_dev {
        struct pci_dev  *rcec;          /* Associated RCEC device */
 #endif
        u32             devcap;         /* PCIe Device Capabilities */
+       u16             rebar_cap;      /* Resizable BAR capability offset */
        u8              pcie_cap;       /* PCIe capability offset */
        u8              msi_cap;        /* MSI capability offset */
        u8              msix_cap;       /* MSI-X capability offset */