aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordingtianhong <dingtianhong@huawei.com>2017-08-14 23:23:23 -0400
committerDavid S. Miller <davem@davemloft.net>2017-08-15 01:14:50 -0400
commita99b646afa8a02571ea298bedca6592d818229cd (patch)
tree7664769a93cc5315a227b310ffa05ff641ae1c66
parent59a361bc6f6e91d57f25ff0aebb0e646beb3b41d (diff)
PCI: Disable PCIe Relaxed Ordering if unsupported
When bit4 is set in the PCIe Device Control register, it indicates whether the device is permitted to use relaxed ordering. On some platforms using relaxed ordering can have performance issues or due to erratum can cause data-corruption. In such cases devices must avoid using relaxed ordering. The patch adds a new flag PCI_DEV_FLAGS_NO_RELAXED_ORDERING to indicate that Relaxed Ordering (RO) attribute should not be used for Transaction Layer Packets (TLP) targeted towards these affected root complexes. This patch checks if there is any node in the hierarchy that indicates that using relaxed ordering is not safe. In such cases the patch turns off the relaxed ordering by clearing the capability for this device. Signed-off-by: Casey Leedom <leedom@chelsio.com> Signed-off-by: Ding Tianhong <dingtianhong@huawei.com> Acked-by: Ashok Raj <ashok.raj@intel.com> Acked-by: Alexander Duyck <alexander.h.duyck@intel.com> Acked-by: Casey Leedom <leedom@chelsio.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/pci/probe.c43
-rw-r--r--drivers/pci/quirks.c11
-rw-r--r--include/linux/pci.h3
3 files changed, 57 insertions, 0 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index c31310db0404..e6a917b4acd3 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1762,6 +1762,48 @@ static void pci_configure_extended_tags(struct pci_dev *dev)
1762 PCI_EXP_DEVCTL_EXT_TAG); 1762 PCI_EXP_DEVCTL_EXT_TAG);
1763} 1763}
1764 1764
1765/**
1766 * pcie_relaxed_ordering_enabled - Probe for PCIe relaxed ordering enable
1767 * @dev: PCI device to query
1768 *
1769 * Returns true if the device has enabled relaxed ordering attribute.
1770 */
1771bool pcie_relaxed_ordering_enabled(struct pci_dev *dev)
1772{
1773 u16 v;
1774
1775 pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &v);
1776
1777 return !!(v & PCI_EXP_DEVCTL_RELAX_EN);
1778}
1779EXPORT_SYMBOL(pcie_relaxed_ordering_enabled);
1780
1781static void pci_configure_relaxed_ordering(struct pci_dev *dev)
1782{
1783 struct pci_dev *root;
1784
1785 /* PCI_EXP_DEVICE_RELAX_EN is RsvdP in VFs */
1786 if (dev->is_virtfn)
1787 return;
1788
1789 if (!pcie_relaxed_ordering_enabled(dev))
1790 return;
1791
1792 /*
1793 * For now, we only deal with Relaxed Ordering issues with Root
1794 * Ports. Peer-to-Peer DMA is another can of worms.
1795 */
1796 root = pci_find_pcie_root_port(dev);
1797 if (!root)
1798 return;
1799
1800 if (root->dev_flags & PCI_DEV_FLAGS_NO_RELAXED_ORDERING) {
1801 pcie_capability_clear_word(dev, PCI_EXP_DEVCTL,
1802 PCI_EXP_DEVCTL_RELAX_EN);
1803 dev_info(&dev->dev, "Disable Relaxed Ordering because the Root Port didn't support it\n");
1804 }
1805}
1806
1765static void pci_configure_device(struct pci_dev *dev) 1807static void pci_configure_device(struct pci_dev *dev)
1766{ 1808{
1767 struct hotplug_params hpp; 1809 struct hotplug_params hpp;
@@ -1769,6 +1811,7 @@ static void pci_configure_device(struct pci_dev *dev)
1769 1811
1770 pci_configure_mps(dev); 1812 pci_configure_mps(dev);
1771 pci_configure_extended_tags(dev); 1813 pci_configure_extended_tags(dev);
1814 pci_configure_relaxed_ordering(dev);
1772 1815
1773 memset(&hpp, 0, sizeof(hpp)); 1816 memset(&hpp, 0, sizeof(hpp));
1774 ret = pci_get_hp_params(dev, &hpp); 1817 ret = pci_get_hp_params(dev, &hpp);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 6967c6b4cf6b..61b59bfa7bfc 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -4016,6 +4016,17 @@ DECLARE_PCI_FIXUP_CLASS_EARLY(0x1797, 0x6869, PCI_CLASS_NOT_DEFINED, 8,
4016 quirk_tw686x_class); 4016 quirk_tw686x_class);
4017 4017
4018/* 4018/*
4019 * Some devices have problems with Transaction Layer Packets with the Relaxed
4020 * Ordering Attribute set. Such devices should mark themselves and other
4021 * Device Drivers should check before sending TLPs with RO set.
4022 */
4023static void quirk_relaxedordering_disable(struct pci_dev *dev)
4024{
4025 dev->dev_flags |= PCI_DEV_FLAGS_NO_RELAXED_ORDERING;
4026 dev_info(&dev->dev, "Disable Relaxed Ordering Attributes to avoid PCIe Completion erratum\n");
4027}
4028
4029/*
4019 * Per PCIe r3.0, sec 2.2.9, "Completion headers must supply the same 4030 * Per PCIe r3.0, sec 2.2.9, "Completion headers must supply the same
4020 * values for the Attribute as were supplied in the header of the 4031 * values for the Attribute as were supplied in the header of the
4021 * corresponding Request, except as explicitly allowed when IDO is used." 4032 * corresponding Request, except as explicitly allowed when IDO is used."
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 4869e66dd659..29606fb89464 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -188,6 +188,8 @@ enum pci_dev_flags {
188 * the direct_complete optimization. 188 * the direct_complete optimization.
189 */ 189 */
190 PCI_DEV_FLAGS_NEEDS_RESUME = (__force pci_dev_flags_t) (1 << 11), 190 PCI_DEV_FLAGS_NEEDS_RESUME = (__force pci_dev_flags_t) (1 << 11),
191 /* Don't use Relaxed Ordering for TLPs directed at this device */
192 PCI_DEV_FLAGS_NO_RELAXED_ORDERING = (__force pci_dev_flags_t) (1 << 12),
191}; 193};
192 194
193enum pci_irq_reroute_variant { 195enum pci_irq_reroute_variant {
@@ -1125,6 +1127,7 @@ bool pci_check_pme_status(struct pci_dev *dev);
1125void pci_pme_wakeup_bus(struct pci_bus *bus); 1127void pci_pme_wakeup_bus(struct pci_bus *bus);
1126void pci_d3cold_enable(struct pci_dev *dev); 1128void pci_d3cold_enable(struct pci_dev *dev);
1127void pci_d3cold_disable(struct pci_dev *dev); 1129void pci_d3cold_disable(struct pci_dev *dev);
1130bool pcie_relaxed_ordering_enabled(struct pci_dev *dev);
1128 1131
1129/* PCI Virtual Channel */ 1132/* PCI Virtual Channel */
1130int pci_save_vc_state(struct pci_dev *dev); 1133int pci_save_vc_state(struct pci_dev *dev);