Skip to content

Commit

Permalink
PCI/ATS: Cache PRI Capability offset
Browse files Browse the repository at this point in the history
Previously each PRI interface searched for the PRI Capability.  Cache the
capability offset the first time we use it instead of searching each time.

[bhelgaas: commit log, reorder patch to later, call pci_pri_init() from
pci_init_capabilities()]
Link: https://lore.kernel.org/r/0c5495d376faf6dbb8eb2165204c474438aaae65.156
7029860.git.sathyanarayanan.kuppuswamy@linux.intel.com
Link: https://lore.kernel.org/r/20190905193146.90250-5-helgaas@kernel.org
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
  • Loading branch information
Kuppuswamy Sathyanarayanan authored and Bjorn Helgaas committed Oct 15, 2019
1 parent 3ad6219 commit c065190
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 25 deletions.
51 changes: 26 additions & 25 deletions drivers/pci/ats.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ int pci_ats_page_aligned(struct pci_dev *pdev)
EXPORT_SYMBOL_GPL(pci_ats_page_aligned);

#ifdef CONFIG_PCI_PRI
void pci_pri_init(struct pci_dev *pdev)
{
pdev->pri_cap = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
}

/**
* pci_enable_pri - Enable PRI capability
* @ pdev: PCI device structure
Expand All @@ -169,7 +174,7 @@ int pci_enable_pri(struct pci_dev *pdev, u32 reqs)
{
u16 control, status;
u32 max_requests;
int pos;
int pri = pdev->pri_cap;

/*
* VFs must not implement the PRI Capability. If their PF
Expand All @@ -185,21 +190,20 @@ int pci_enable_pri(struct pci_dev *pdev, u32 reqs)
if (WARN_ON(pdev->pri_enabled))
return -EBUSY;

pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
if (!pos)
if (!pri)
return -EINVAL;

pci_read_config_word(pdev, pos + PCI_PRI_STATUS, &status);
pci_read_config_word(pdev, pri + PCI_PRI_STATUS, &status);
if (!(status & PCI_PRI_STATUS_STOPPED))
return -EBUSY;

pci_read_config_dword(pdev, pos + PCI_PRI_MAX_REQ, &max_requests);
pci_read_config_dword(pdev, pri + PCI_PRI_MAX_REQ, &max_requests);
reqs = min(max_requests, reqs);
pdev->pri_reqs_alloc = reqs;
pci_write_config_dword(pdev, pos + PCI_PRI_ALLOC_REQ, reqs);
pci_write_config_dword(pdev, pri + PCI_PRI_ALLOC_REQ, reqs);

control = PCI_PRI_CTRL_ENABLE;
pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);
pci_write_config_word(pdev, pri + PCI_PRI_CTRL, control);

pdev->pri_enabled = 1;

Expand All @@ -216,7 +220,7 @@ EXPORT_SYMBOL_GPL(pci_enable_pri);
void pci_disable_pri(struct pci_dev *pdev)
{
u16 control;
int pos;
int pri = pdev->pri_cap;

/* VFs share the PF PRI */
if (pdev->is_virtfn)
Expand All @@ -225,13 +229,12 @@ void pci_disable_pri(struct pci_dev *pdev)
if (WARN_ON(!pdev->pri_enabled))
return;

pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
if (!pos)
if (!pri)
return;

pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control);
pci_read_config_word(pdev, pri + PCI_PRI_CTRL, &control);
control &= ~PCI_PRI_CTRL_ENABLE;
pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);
pci_write_config_word(pdev, pri + PCI_PRI_CTRL, control);

pdev->pri_enabled = 0;
}
Expand All @@ -245,20 +248,19 @@ void pci_restore_pri_state(struct pci_dev *pdev)
{
u16 control = PCI_PRI_CTRL_ENABLE;
u32 reqs = pdev->pri_reqs_alloc;
int pos;
int pri = pdev->pri_cap;

if (pdev->is_virtfn)
return;

if (!pdev->pri_enabled)
return;

pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
if (!pos)
if (!pri)
return;

pci_write_config_dword(pdev, pos + PCI_PRI_ALLOC_REQ, reqs);
pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);
pci_write_config_dword(pdev, pri + PCI_PRI_ALLOC_REQ, reqs);
pci_write_config_word(pdev, pri + PCI_PRI_CTRL, control);
}
EXPORT_SYMBOL_GPL(pci_restore_pri_state);

Expand All @@ -272,20 +274,19 @@ EXPORT_SYMBOL_GPL(pci_restore_pri_state);
int pci_reset_pri(struct pci_dev *pdev)
{
u16 control;
int pos;
int pri = pdev->pri_cap;

if (pdev->is_virtfn)
return 0;

if (WARN_ON(pdev->pri_enabled))
return -EBUSY;

pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
if (!pos)
if (!pri)
return -EINVAL;

control = PCI_PRI_CTRL_RESET;
pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);
pci_write_config_word(pdev, pri + PCI_PRI_CTRL, control);

return 0;
}
Expand All @@ -301,16 +302,16 @@ EXPORT_SYMBOL_GPL(pci_reset_pri);
int pci_prg_resp_pasid_required(struct pci_dev *pdev)
{
u16 status;
int pos;
int pri;

if (pdev->is_virtfn)
pdev = pci_physfn(pdev);

pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
if (!pos)
pri = pdev->pri_cap;
if (!pri)
return 0;

pci_read_config_word(pdev, pos + PCI_PRI_STATUS, &status);
pci_read_config_word(pdev, pri + PCI_PRI_STATUS, &status);

if (status & PCI_PRI_STATUS_PASID)
return 1;
Expand Down
6 changes: 6 additions & 0 deletions drivers/pci/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,12 @@ static inline void pci_ats_init(struct pci_dev *d) { }
static inline void pci_restore_ats_state(struct pci_dev *dev) { }
#endif /* CONFIG_PCI_ATS */

#ifdef CONFIG_PCI_PRI
void pci_pri_init(struct pci_dev *dev);
#else
static inline void pci_pri_init(struct pci_dev *dev) { }
#endif

#ifdef CONFIG_PCI_IOV
int pci_iov_init(struct pci_dev *dev);
void pci_iov_release(struct pci_dev *dev);
Expand Down
3 changes: 3 additions & 0 deletions drivers/pci/probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -2324,6 +2324,9 @@ static void pci_init_capabilities(struct pci_dev *dev)
/* Address Translation Services */
pci_ats_init(dev);

/* Page Request Interface */
pci_pri_init(dev);

/* Enable ACS P2P upstream forwarding */
pci_enable_acs(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 @@ -454,6 +454,7 @@ struct pci_dev {
u8 ats_stu; /* ATS Smallest Translation Unit */
#endif
#ifdef CONFIG_PCI_PRI
u16 pri_cap; /* PRI Capability offset */
u32 pri_reqs_alloc; /* Number of PRI requests allocated */
#endif
#ifdef CONFIG_PCI_PASID
Expand Down

0 comments on commit c065190

Please sign in to comment.