Some devices have problems with Transaction Layer Packets with the Relaxed
Ordering Attribute set. This patch set adds a new PCIe Device Flag,
PCI_DEV_FLAGS_NO_RELAXED_ORDERING, a set of PCI Quirks to catch some known
devices with Relaxed Ordering issues, and a use of this new flag by the
cxgb4 driver to avoid using Relaxed Ordering with problematic Root Complex
Ports.
It's been years since I've submitted kernel.org patches, I appolgise for the
almost certain submission errors.
v2: Alexander point out that the v1 was only a part of the whole solution,
some platform which has some issues could use the new flag to indicate
that it is not safe to enable relaxed ordering attribute, then we need
to clear the relaxed ordering enable bits in the PCI configuration when
initializing the device. So add a new second patch to modify the PCI
initialization code to clear the relaxed ordering enable bit in the
event that the root complex doesn't want relaxed ordering enabled.
The third patch was base on the v1's second patch and only be changed
to query the relaxed ordering enable bit in the PCI configuration space
to allow the Chelsio NIC to send TLPs with the relaxed ordering attributes
set.
This version didn't plan to drop the defines for Intel Drivers to use the
new checking way to enable relaxed ordering because it is not the hardest
part of the moment, we could fix it in next patchset when this patches
reach the goal.
v3: Redesigned the logic for pci_configure_relaxed_ordering when configuration,
If a PCIe device didn't enable the relaxed ordering attribute default,
we should not do anything in the PCIe configuration, otherwise we
should check if any of the devices above us do not support relaxed
ordering by the PCI_DEV_FLAGS_NO_RELAXED_ORDERING flag, then base on
the result if we get a return that indicate that the relaxed ordering
is not supported we should update our device to disable relaxed ordering
in configuration space. If the device above us doesn't exist or isn't
the PCIe device, we shouldn't do anything and skip updating relaxed ordering
because we are probably running in a guest.
Casey Leedom (2):
PCI: Add new PCIe Fabric End Node flag,
PCI_DEV_FLAGS_NO_RELAXED_ORDERING
net/cxgb4: Use new PCI_DEV_FLAGS_NO_RELAXED_ORDERING flag
Ding Tianhong (1):
PCI: Enable PCIe Relaxed Ordering if supported
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 1 +
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 17 ++++++++++
drivers/net/ethernet/chelsio/cxgb4/sge.c | 5 +--
drivers/pci/pci.c | 29 +++++++++++++++++
drivers/pci/probe.c | 43 +++++++++++++++++++++++++
drivers/pci/quirks.c | 38 ++++++++++++++++++++++
include/linux/pci.h | 4 +++
7 files changed, 135 insertions(+), 2 deletions(-)
--
1.9.0
The PCIe Device Control Register use the bit 4 to indicate that
whether the device is permitted to enable relaxed ordering or not.
But relaxed ordering is not safe for some platform which could only
use strong write ordering, so devices are allowed (but not required)
to enable relaxed ordering bit by default.
If a PCIe device didn't enable the relaxed ordering attribute default,
we should not do anything in the PCIe configuration, otherwise we
should check if any of the devices above us do not support relaxed
ordering by the PCI_DEV_FLAGS_NO_RELAXED_ORDERING flag, then base on
the result if we get a return that indicate that the relaxed ordering
is not supported we should update our device to disable relaxed ordering
in configuration space. If the device above us doesn't exist or isn't
the PCIe device, we shouldn't do anything and skip updating relaxed ordering
because we are probably running in a guest.
Signed-off-by: Ding Tianhong <redacted>
---
drivers/pci/pci.c | 29 +++++++++++++++++++++++++++++
drivers/pci/probe.c | 43 +++++++++++++++++++++++++++++++++++++++++++
include/linux/pci.h | 2 ++
3 files changed, 74 insertions(+)
@@ -4878,6 +4878,35 @@ int pcie_set_mps(struct pci_dev *dev, int mps)EXPORT_SYMBOL(pcie_set_mps);/**+*pcie_clear_relaxed_ordering-clearPCIExpressrelexedorderingbit+*@dev:PCIdevicetoquery+*+*Ifpossibleclearrelaxedordering+*/+intpcie_clear_relaxed_ordering(structpci_dev*dev)+{+returnpcie_capability_clear_word(dev,PCI_EXP_DEVCTL,+PCI_EXP_DEVCTL_RELAX_EN);+}+EXPORT_SYMBOL(pcie_clear_relaxed_ordering);++/**+*pcie_get_relaxed_ordering-checkPCIExpressrelexedorderingbit+*@dev:PCIdevicetoquery+*+*Returnstrueifrelaxedorderingisbeenset+*/+intpcie_get_relaxed_ordering(structpci_dev*dev)+{+u16v;++pcie_capability_read_word(dev,PCI_EXP_DEVCTL,&v);++return(v&PCI_EXP_DEVCTL_RELAX_EN)>>4;+}+EXPORT_SYMBOL(pcie_get_relaxed_ordering);++/***pcie_get_minimum_link-determineminimumlinksettingsofaPCIdevice*@dev:PCIdevicetoquery*@speed:storageforminimumspeed
@@ -1701,6 +1701,48 @@ static void pci_configure_extended_tags(struct pci_dev *dev)PCI_EXP_DEVCTL_EXT_TAG);}+/**+*pci_dev_disable_relaxed_ordering-checkifthePCIdevice+*shoulddisabletherelaxedorderingattribute.+*@dev:PCIdevice+*+*ReturntrueifanyofthePCIdevicesaboveusdonotsupport+*relaxedordering.+*/+staticintpci_dev_disable_relaxed_ordering(structpci_dev*dev)+{+intro_disabled=0;++while(dev){+if(dev->dev_flags&PCI_DEV_FLAGS_NO_RELAXED_ORDERING){+ro_disabled=1;+break;+}+dev=dev->bus->self;+}++returnro_disabled;+}++staticvoidpci_configure_relaxed_ordering(structpci_dev*dev)+{+structpci_dev*bridge=pci_upstream_bridge(dev);+intorigin_ero;++if(!pci_is_pcie(dev)||!bridge||!pci_is_pcie(bridge))+return;++origin_ero=pcie_get_relaxed_ordering(dev);+/* If the releaxed ordering enable bit is not set, do nothing. */+if(!origin_ero)+return;++if(pci_dev_disable_relaxed_ordering(dev)){+pcie_clear_relaxed_ordering(dev);+dev_info(&dev->dev,"Disable Relaxed Ordering\n");+}+}+staticvoidpci_configure_device(structpci_dev*dev){structhotplug_paramshpp;
From: Casey Leedom <redacted>
The new flag PCI_DEV_FLAGS_NO_RELAXED_ORDERING indicates that the Relaxed
Ordering Attribute should not be used on Transaction Layer Packets destined
for the PCIe End Node so flagged. Initially flagged this way are Intel
E5-26xx Root Complex Ports which suffer from a Flow Control Credit
Performance Problem and AMD A1100 ARM ("SEATTLE") Root Complex Ports which
don't obey PCIe 3.0 ordering rules which can lead to Data Corruption.
Signed-off-by: Casey Leedom <redacted>
Signed-off-by: Ding Tianhong <redacted>
---
drivers/pci/quirks.c | 38 ++++++++++++++++++++++++++++++++++++++
include/linux/pci.h | 2 ++
2 files changed, 40 insertions(+)
@@ -183,6 +183,8 @@ enum pci_dev_flags {PCI_DEV_FLAGS_BRIDGE_XLATE_ROOT=(__forcepci_dev_flags_t)(1<<9),/* Do not use FLR even if device advertises PCI_AF_CAP */PCI_DEV_FLAGS_NO_FLR_RESET=(__forcepci_dev_flags_t)(1<<10),+/* Don't use Relaxed Ordering for TLPs directed@this device */+PCI_DEV_FLAGS_NO_RELAXED_ORDERING=(__forcepci_dev_flags_t)(1<<11),};enumpci_irq_reroute_variant{
@@ -4628,6 +4628,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)#ifdef CONFIG_PCI_IOVu32v,port_vec;#endif+structpci_dev*root;printk_once(KERN_INFO"%s - version %s\n",DRV_DESC,DRV_VERSION);
@@ -4726,6 +4727,22 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)adapter->msg_enable=DFLT_MSG_ENABLE;memset(adapter->chan_map,0xff,sizeof(adapter->chan_map));+/* If possible, we use PCIe Relaxed Ordering Attribute to deliver+*IngressPacketDatatoFreeListBuffersinordertoallowfor+*chipsetperformanceoptimizationsbetweentheRootComplexand+*MemoryControllers.(MessagestotheassociatedIngressQueue+*notifyingnewPacketPlacementintheFreeListsBufferswillbe+*sendwithouttheRelaxedOrderingAttributethusguaranteingthat+*allprecedingPCIeTransactionLayerPacketswillbeprocessed+*first.)ButsomeRootComplexeshavevariousissueswithUpstream+*TransactionLayerPacketswiththeRelaxedOrderingAttributeset.+*SowecheckourRootComplextoseeifit'sflagedwithadvice+*againstusingRelaxedOrdering.+*/+root=pci_find_pcie_root_port(adapter->pdev);+if(pcie_get_relaxed_ordering(root))+adapter->flags|=ROOT_NO_RELAXED_ORDERING;+spin_lock_init(&adapter->stats_lock);spin_lock_init(&adapter->tid_release_lock);spin_lock_init(&adapter->win0_lock);
@@ -2571,6 +2571,7 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,structfw_iq_cmdc;structsge*s=&adap->sge;structport_info*pi=netdev_priv(dev);+intrelaxed=!(adap->flags&ROOT_NO_RELAXED_ORDERING);/* Size needs to be multiple of 16, including status entry. */iq->size=roundup(iq->size,16);
From: John Garry <hidden> Date: 2017-06-07 17:56:50
On 07/06/2017 10:16, Ding Tianhong wrote:
Hi Ding,
A few general style comments:
The PCIe Device Control Register use the bit 4 to indicate that
whether the device is permitted to enable relaxed ordering or not.
But relaxed ordering is not safe for some platform which could only
use strong write ordering, so devices are allowed (but not required)
to enable relaxed ordering bit by default.
If a PCIe device didn't enable the relaxed ordering attribute default,
we should not do anything in the PCIe configuration, otherwise we
should check if any of the devices above us do not support relaxed
ordering by the PCI_DEV_FLAGS_NO_RELAXED_ORDERING flag, then base on
the result if we get a return that indicate that the relaxed ordering
is not supported we should update our device to disable relaxed ordering
in configuration space. If the device above us doesn't exist or isn't
the PCIe device, we shouldn't do anything and skip updating relaxed ordering
because we are probably running in a guest.
@@ -4878,6 +4878,35 @@ int pcie_set_mps(struct pci_dev *dev, int mps)EXPORT_SYMBOL(pcie_set_mps);/**+*pcie_clear_relaxed_ordering-clearPCIExpressrelexedorderingbit+*@dev:PCIdevicetoquery+*+*Ifpossibleclearrelaxedordering+*/+intpcie_clear_relaxed_ordering(structpci_dev*dev)+{+returnpcie_capability_clear_word(dev,PCI_EXP_DEVCTL,+PCI_EXP_DEVCTL_RELAX_EN);+}+EXPORT_SYMBOL(pcie_clear_relaxed_ordering);++/**+*pcie_get_relaxed_ordering-checkPCIExpressrelexedorderingbit
s/relexed/relaxed/
Check what on relaxed ordering bit?
And the function name is inconsistent with this discription.
+ * @dev: PCI device to query
+ *
+ * Returns true if relaxed ordering is been set
If you want to return true/false, then use !!, below in the function
quoted hunk
+ */
+int pcie_get_relaxed_ordering(struct pci_dev *dev)
+{
+ u16 v;
+
+ pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &v);
+
+ return (v & PCI_EXP_DEVCTL_RELAX_EN) >> 4;
+}
+EXPORT_SYMBOL(pcie_get_relaxed_ordering);
+
+/**
* pcie_get_minimum_link - determine minimum link settings of a PCI device
* @dev: PCI device to query
* @speed: storage for minimum speed
I think that we need a more accurate description. I know some people
think a function which just "checks" is vague.
+ * @dev: PCI device
+ *
+ * Return true if any of the PCI devices above us do not support
+ * relaxed ordering.
+ */
+static int pci_dev_disable_relaxed_ordering(struct pci_dev *dev)
The function name implies an action - disabling - but this function does
nothing except return a value
+{
+ int ro_disabled = 0;
+
+ while(dev) {
Did you run checkpatch?
+ if (dev->dev_flags & PCI_DEV_FLAGS_NO_RELAXED_ORDERING) {
+ ro_disabled = 1;
just return true, and return false at the bottom, so you can do away
with ro_disabled (which is not a bool)
From: Alexander Duyck <hidden> Date: 2017-06-07 23:24:46
On Wed, Jun 7, 2017 at 2:16 AM, Ding Tianhong [off-list ref] wrote:
From: Casey Leedom <redacted>
cxgb4 Ethernet driver now queries Root Complex Port to determine if it can
send TLPs to it with the Relaxed Ordering Attribute set.
Signed-off-by: Casey Leedom <redacted>
Signed-off-by: Ding Tianhong <redacted>
So I am pretty sure this patch doesn't work with patch 2. We need to
update it so that it doesn't check the root complex but instead checks
itself to see if it is allowed to use relaxed ordering.
What we need here is the ability to detect if relaxed ordering is
disabled, and if so take the steps needed to enable peer to peer
relaxed ordering without enabling relaxed ordering to the root
complex. Do I have that right Casey?
@@ -4628,6 +4628,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)#ifdef CONFIG_PCI_IOVu32v,port_vec;#endif+structpci_dev*root;printk_once(KERN_INFO"%s - version %s\n",DRV_DESC,DRV_VERSION);
@@ -4726,6 +4727,22 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)adapter->msg_enable=DFLT_MSG_ENABLE;memset(adapter->chan_map,0xff,sizeof(adapter->chan_map));+/* If possible, we use PCIe Relaxed Ordering Attribute to deliver+*IngressPacketDatatoFreeListBuffersinordertoallowfor+*chipsetperformanceoptimizationsbetweentheRootComplexand+*MemoryControllers.(MessagestotheassociatedIngressQueue+*notifyingnewPacketPlacementintheFreeListsBufferswillbe+*sendwithouttheRelaxedOrderingAttributethusguaranteingthat+*allprecedingPCIeTransactionLayerPacketswillbeprocessed+*first.)ButsomeRootComplexeshavevariousissueswithUpstream+*TransactionLayerPacketswiththeRelaxedOrderingAttributeset.+*SowecheckourRootComplextoseeifit'sflagedwithadvice+*againstusingRelaxedOrdering.+*/+root=pci_find_pcie_root_port(adapter->pdev);+if(pcie_get_relaxed_ordering(root))+adapter->flags|=ROOT_NO_RELAXED_ORDERING;+spin_lock_init(&adapter->stats_lock);spin_lock_init(&adapter->tid_release_lock);spin_lock_init(&adapter->win0_lock);
@@ -2571,6 +2571,7 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,structfw_iq_cmdc;structsge*s=&adap->sge;structport_info*pi=netdev_priv(dev);+intrelaxed=!(adap->flags&ROOT_NO_RELAXED_ORDERING);/* Size needs to be multiple of 16, including status entry. */iq->size=roundup(iq->size,16);
Hi John:
Thanks for the reviewing, I will fix it in next version.
Ding
On 2017/6/8 1:55, John Garry wrote:
On 07/06/2017 10:16, Ding Tianhong wrote:
Hi Ding,
A few general style comments:
quoted
The PCIe Device Control Register use the bit 4 to indicate that
whether the device is permitted to enable relaxed ordering or not.
But relaxed ordering is not safe for some platform which could only
use strong write ordering, so devices are allowed (but not required)
to enable relaxed ordering bit by default.
If a PCIe device didn't enable the relaxed ordering attribute default,
we should not do anything in the PCIe configuration, otherwise we
should check if any of the devices above us do not support relaxed
ordering by the PCI_DEV_FLAGS_NO_RELAXED_ORDERING flag, then base on
the result if we get a return that indicate that the relaxed ordering
is not supported we should update our device to disable relaxed ordering
in configuration space. If the device above us doesn't exist or isn't
the PCIe device, we shouldn't do anything and skip updating relaxed ordering
because we are probably running in a guest.
@@ -4878,6 +4878,35 @@ int pcie_set_mps(struct pci_dev *dev, int mps)EXPORT_SYMBOL(pcie_set_mps);/**+*pcie_clear_relaxed_ordering-clearPCIExpressrelexedorderingbit+*@dev:PCIdevicetoquery+*+*Ifpossibleclearrelaxedordering+*/+intpcie_clear_relaxed_ordering(structpci_dev*dev)+{+returnpcie_capability_clear_word(dev,PCI_EXP_DEVCTL,+PCI_EXP_DEVCTL_RELAX_EN);+}+EXPORT_SYMBOL(pcie_clear_relaxed_ordering);++/**+*pcie_get_relaxed_ordering-checkPCIExpressrelexedorderingbit
s/relexed/relaxed/
Check what on relaxed ordering bit?
And the function name is inconsistent with this discription.
quoted
+ * @dev: PCI device to query
+ *
+ * Returns true if relaxed ordering is been set
If you want to return true/false, then use !!, below in the function
quoted
+ */
+int pcie_get_relaxed_ordering(struct pci_dev *dev)
+{
+ u16 v;
+
+ pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &v);
+
+ return (v & PCI_EXP_DEVCTL_RELAX_EN) >> 4;
+}
+EXPORT_SYMBOL(pcie_get_relaxed_ordering);
+
+/**
* pcie_get_minimum_link - determine minimum link settings of a PCI device
* @dev: PCI device to query
* @speed: storage for minimum speed
I think that we need a more accurate description. I know some people think a function which just "checks" is vague.
quoted
+ * @dev: PCI device
+ *
+ * Return true if any of the PCI devices above us do not support
+ * relaxed ordering.
+ */
+static int pci_dev_disable_relaxed_ordering(struct pci_dev *dev)
The function name implies an action - disabling - but this function does nothing except return a value
quoted
+{
+ int ro_disabled = 0;
+
+ while(dev) {
Did you run checkpatch?
quoted
+ if (dev->dev_flags & PCI_DEV_FLAGS_NO_RELAXED_ORDERING) {
+ ro_disabled = 1;
just return true, and return false at the bottom, so you can do away with ro_disabled (which is not a bool)
On Wed, Jun 7, 2017 at 2:16 AM, Ding Tianhong [off-list ref] wrote:
quoted
From: Casey Leedom <redacted>
cxgb4 Ethernet driver now queries Root Complex Port to determine if it can
send TLPs to it with the Relaxed Ordering Attribute set.
Signed-off-by: Casey Leedom <redacted>
Signed-off-by: Ding Tianhong <redacted>
So I am pretty sure this patch doesn't work with patch 2. We need to
update it so that it doesn't check the root complex but instead checks
itself to see if it is allowed to use relaxed ordering.
Right, we should check the End Point PCIe device configuration space, not RC.
What we need here is the ability to detect if relaxed ordering is
disabled, and if so take the steps needed to enable peer to peer
relaxed ordering without enabling relaxed ordering to the root
complex. Do I have that right Casey?
I am not very clear to this driver about how to enable peer to peer
relaxed ordering without enabling relaxed ordering to the RC, need
some help from Casey, so I will still focus on this patch and only
fix the peer to RC relaxed ordering problem, I hope Casey could send
another patch to fix it later.
Thanks
Ding
@@ -4628,6 +4628,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)#ifdef CONFIG_PCI_IOVu32v,port_vec;#endif+structpci_dev*root;printk_once(KERN_INFO"%s - version %s\n",DRV_DESC,DRV_VERSION);
@@ -4726,6 +4727,22 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)adapter->msg_enable=DFLT_MSG_ENABLE;memset(adapter->chan_map,0xff,sizeof(adapter->chan_map));+/* If possible, we use PCIe Relaxed Ordering Attribute to deliver+*IngressPacketDatatoFreeListBuffersinordertoallowfor+*chipsetperformanceoptimizationsbetweentheRootComplexand+*MemoryControllers.(MessagestotheassociatedIngressQueue+*notifyingnewPacketPlacementintheFreeListsBufferswillbe+*sendwithouttheRelaxedOrderingAttributethusguaranteingthat+*allprecedingPCIeTransactionLayerPacketswillbeprocessed+*first.)ButsomeRootComplexeshavevariousissueswithUpstream+*TransactionLayerPacketswiththeRelaxedOrderingAttributeset.+*SowecheckourRootComplextoseeifit'sflagedwithadvice+*againstusingRelaxedOrdering.+*/+root=pci_find_pcie_root_port(adapter->pdev);+if(pcie_get_relaxed_ordering(root))+adapter->flags|=ROOT_NO_RELAXED_ORDERING;+spin_lock_init(&adapter->stats_lock);spin_lock_init(&adapter->tid_release_lock);spin_lock_init(&adapter->win0_lock);
@@ -2571,6 +2571,7 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,structfw_iq_cmdc;structsge*s=&adap->sge;structport_info*pi=netdev_priv(dev);+intrelaxed=!(adap->flags&ROOT_NO_RELAXED_ORDERING);/* Size needs to be multiple of 16, including status entry. */iq->size=roundup(iq->size,16);