]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
PCI/ATS: Cache PRI Capability offset
authorKuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Thu, 5 Sep 2019 19:31:45 +0000 (14:31 -0500)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 15 Oct 2019 21:39:09 +0000 (16:39 -0500)
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>
drivers/pci/ats.c
drivers/pci/pci.h
drivers/pci/probe.c
include/linux/pci.h

index a708ed4146ca2e6de91400c6a90c60242b57d570..c97e862b538a0e6899c186fbe6df1cea105fb48c 100644 (file)
@@ -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
@@ -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
@@ -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;
 
@@ -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)
@@ -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;
 }
@@ -245,7 +248,7 @@ 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;
@@ -253,12 +256,11 @@ void pci_restore_pri_state(struct pci_dev *pdev)
        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);
 
@@ -272,7 +274,7 @@ 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;
@@ -280,12 +282,11 @@ int pci_reset_pri(struct pci_dev *pdev)
        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;
 }
@@ -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;
index 3f6947ee3324a9854ff275501732441d045ab581..aa08cd35bf87b00d6919d2c075a866b707859b67 100644 (file)
@@ -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);
index 3d5271a7a849dbffb8ea80f515f87dbf7e33f04f..d145165c799ce21ee0993b6571a4030f23053f34 100644 (file)
@@ -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);
 
index c028883c8460c407089180ce984246c595f4123d..e7770d990c4687cbe882739ffb74f23df20c13ba 100644 (file)
@@ -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