Skip to content

Commit

Permalink
PCI: Cache offset of Resizable BAR capability
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Bjorn Helgaas committed Mar 10, 2025
1 parent 3f8c495 commit a7eb912
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 2 deletions.
9 changes: 7 additions & 2 deletions drivers/pci/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand All @@ -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;

Expand Down
1 change: 1 addition & 0 deletions drivers/pci/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions drivers/pci/probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions include/linux/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down

0 comments on commit a7eb912

Please sign in to comment.