Inter-revision diff: patch 6

Comparing v3 (message) to v11 (message)

--- v3
+++ v11
@@ -1,108 +1,96 @@
-PCIe spec 5.0r1.0 section 2.2.6.2 implementation note, In configurations
-where a Requester with 10-Bit Tag Requester capability needs to target
-multiple Completers, one needs to ensure that the Requester sends 10-Bit
-Tag Requests only to Completers that have 10-Bit Tag Completer capability.
-So we enable 10-Bit Tag Requester for root port only when the devices
-under the root port support 10-Bit Tag Completer.
+The P2PDMA mapping should fail if a device with 10-Bit Tag Requester
+interact with a device that does not support 10-Bit Tag Completer.
+
+Add a 10-Bit Tag check in the P2PDMA code to ensure that a device with
+10-Bit Tag Requester doesn't interact with a device that does not
+support 10-Bit Tag Completer. Before that happens, the kernel should
+emit a warning.
+
+"echo 0 > /sys/bus/pci/devices/.../tags" to disable 10-Bit Tag
+Requester for PF device.
+
+"echo 0 > /sys/bus/pci/devices/.../sriov_vf_tags_ctl" to disable
+10-Bit Tag Requester for VF device.
 
 Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
+Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
 ---
- drivers/pci/pcie/portdrv_pci.c | 75 ++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 75 insertions(+)
+ drivers/pci/p2pdma.c | 48 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 48 insertions(+)
 
-diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
-index c7ff1ee..baf413f 100644
---- a/drivers/pci/pcie/portdrv_pci.c
-+++ b/drivers/pci/pcie/portdrv_pci.c
-@@ -90,6 +90,78 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = {
- #define PCIE_PORTDRV_PM_OPS	NULL
- #endif /* !PM */
+diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
+index 50cdde3e9a8b..1565a31183af 100644
+--- a/drivers/pci/p2pdma.c
++++ b/drivers/pci/p2pdma.c
+@@ -19,6 +19,7 @@
+ #include <linux/random.h>
+ #include <linux/seq_buf.h>
+ #include <linux/xarray.h>
++#include "pci.h"
  
-+static int pci_10bit_tag_comp_support(struct pci_dev *dev, void *data)
+ enum pci_p2pdma_map_type {
+ 	PCI_P2PDMA_MAP_UNKNOWN = 0,
+@@ -410,6 +411,50 @@ static unsigned long map_types_idx(struct pci_dev *client)
+ 		(client->bus->number << 8) | client->devfn;
+ }
+ 
++static bool pci_10bit_tags_unsupported(struct pci_dev *a,
++				       struct pci_dev *b,
++				       bool verbose)
 +{
-+	u8 *support = data;
++	bool req;
++	bool comp;
++	u16 ctl;
++	const char *str = "tags";
 +
-+	if (*support == 0)
-+		return 0;
-+
-+	if (!pci_is_pcie(dev)) {
-+		*support = 0;
-+		return 0;
++	if (a->is_virtfn) {
++#ifdef CONFIG_PCI_IOV
++		req = !!(a->physfn->sriov->ctrl &
++			 PCI_SRIOV_CTRL_VF_10BIT_TAG_REQ_EN);
++#endif
++	} else {
++		pcie_capability_read_word(a, PCI_EXP_DEVCTL2, &ctl);
++		req = !!(ctl & PCI_EXP_DEVCTL2_10BIT_TAG_REQ_EN);
 +	}
 +
-+	/*
-+	 * PCIe spec 5.0r1.0 section 2.2.6.2 implementation note.
-+	 * For configurations where a Requester with 10-Bit Tag Requester
-+	 * capability targets Completers where some do and some do not have
-+	 * 10-Bit Tag Completer capability, how the Requester determines which
-+	 * NPRs include 10-Bit Tags is outside the scope of this specification.
-+	 * So we do not consider hotplug scenario.
-+	 */
-+	if (dev->is_hotplug_bridge) {
-+		*support = 0;
-+		return 0;
-+	}
++	comp = !!(b->devcap2 & PCI_EXP_DEVCAP2_10BIT_TAG_COMP);
 +
-+	if (!(dev->pcie_devcap2 & PCI_EXP_DEVCAP2_10BIT_TAG_COMP)) {
-+		*support = 0;
-+		return 0;
-+	}
++	/* 10-bit tags not enabled on requester */
++	if (!req)
++		return false;
 +
-+	return 0;
-+}
++	 /* Completer can handle anything */
++	if (comp)
++		return false;
 +
-+static void pci_configure_rp_10bit_tag(struct pci_dev *dev)
-+{
-+	u8 support = 1;
-+	struct pci_dev *pchild;
++	if (!verbose)
++		return true;
 +
-+	if (dev->subordinate == NULL)
-+		return;
++	pci_warn(a, "cannot be used for peer-to-peer DMA as 10-Bit Tag Requester enable is set for this device, but peer device (%s) does not support the 10-Bit Tag Completer\n",
++		 pci_name(b));
 +
-+	/* If no devices under the root port, no need to enable 10-Bit Tag. */
-+	pchild = list_first_entry_or_null(&dev->subordinate->devices,
-+					  struct pci_dev, bus_list);
-+	if (pchild == NULL)
-+		return;
++	if (a->is_virtfn)
++		str = "sriov_vf_tags_ctl";
 +
-+	pci_10bit_tag_comp_support(dev, &support);
-+	if (!support)
-+		return;
++	pci_warn(a, "to disable 10-Bit Tag Requester for this device, echo 0 > /sys/bus/pci/devices/%s/%s\n",
++		 pci_name(a), str);
 +
-+	/*
-+	 * PCIe spec 5.0r1.0 section 2.2.6.2 implementation note.
-+	 * In configurations where a Requester with 10-Bit Tag Requester
-+	 * capability needs to target multiple Completers, one needs to ensure
-+	 * that the Requester sends 10-Bit Tag Requests only to Completers
-+	 * that have 10-Bit Tag Completer capability. So we enable 10-Bit Tag
-+	 * Requester for root port only when the devices under the root port
-+	 * support 10-Bit Tag Completer.
-+	 */
-+	pci_walk_bus(dev->subordinate, pci_10bit_tag_comp_support, &support);
-+	if (!support)
-+		return;
-+
-+	if (!(dev->pcie_devcap2 & PCI_EXP_DEVCAP2_10BIT_TAG_REQ))
-+		return;
-+
-+	pci_dbg(dev, "enabling 10-Bit Tag Requester\n");
-+	pcie_capability_set_word(dev, PCI_EXP_DEVCTL2,
-+				 PCI_EXP_DEVCTL2_10BIT_TAG_REQ_EN);
++	return true;
 +}
 +
  /*
-  * pcie_portdrv_probe - Probe PCI-Express port devices
-  * @dev: PCI-Express port device being probed
-@@ -111,6 +183,9 @@ static int pcie_portdrv_probe(struct pci_dev *dev,
- 	     (type != PCI_EXP_TYPE_RC_EC)))
- 		return -ENODEV;
- 
-+	if (type == PCI_EXP_TYPE_ROOT_PORT)
-+		pci_configure_rp_10bit_tag(dev);
+  * Calculate the P2PDMA mapping type and distance between two PCI devices.
+  *
+@@ -532,6 +577,9 @@ calc_map_type_and_dist(struct pci_dev *provider, struct pci_dev *client,
+ 		map_type = PCI_P2PDMA_MAP_NOT_SUPPORTED;
+ 	}
+ done:
++	if (pci_10bit_tags_unsupported(client, provider, verbose))
++		map_type = PCI_P2PDMA_MAP_NOT_SUPPORTED;
 +
- 	if (type == PCI_EXP_TYPE_RC_EC)
- 		pcie_link_rcec(dev);
- 
+ 	rcu_read_lock();
+ 	p2pdma = rcu_dereference(provider->p2pdma);
+ 	if (p2pdma)
 -- 
-2.7.4
+2.22.0
 
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help