PCI/ATS: Cache PRI Capability offset

commit c065190bbc upstream.

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>
Signed-off-by: Chen Zhuo <sagazchen@tencent.com>
Signed-off-by: Xinghui Li <korantli@tencent.com>
This commit is contained in:
Kuppuswamy Sathyanarayanan 2019-09-05 14:31:45 -05:00 committed by Jianping Liu
parent bb83178d2c
commit 1d2f0a0e30
4 changed files with 36 additions and 25 deletions

View File

@ -186,6 +186,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
@ -196,26 +201,25 @@ int pci_enable_pri(struct pci_dev *pdev, u32 reqs)
{
u16 control, status;
u32 max_requests;
int pos;
int pri = pdev->pri_cap;
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;
@ -232,18 +236,17 @@ EXPORT_SYMBOL_GPL(pci_enable_pri);
void pci_disable_pri(struct pci_dev *pdev)
{
u16 control;
int pos;
int pri = pdev->pri_cap;
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;
}
@ -257,17 +260,16 @@ 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->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);
@ -281,17 +283,16 @@ 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 (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;
}
@ -441,13 +442,13 @@ EXPORT_SYMBOL_GPL(pci_pasid_features);
int pci_prg_resp_pasid_required(struct pci_dev *pdev)
{
u16 status;
int pos;
int pri;
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;

View File

@ -466,6 +466,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);

View File

@ -2371,6 +2371,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);

View File

@ -463,6 +463,7 @@ struct pci_dev {
atomic_t ats_ref_cnt; /* Number of VFs with ATS enabled */
#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