linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/14]  PCI/P2PDMA: Support transactions that hit the host bridge
@ 2019-07-30 16:35 Logan Gunthorpe
  2019-07-30 16:35 ` [PATCH v2 01/14] PCI/P2PDMA: Introduce private pagemap structure Logan Gunthorpe
                   ` (14 more replies)
  0 siblings, 15 replies; 26+ messages in thread
From: Logan Gunthorpe @ 2019-07-30 16:35 UTC (permalink / raw)
  To: linux-kernel, linux-pci, linux-nvme, linux-rdma
  Cc: Bjorn Helgaas, Christoph Hellwig, Christian Koenig,
	Jason Gunthorpe, Sagi Grimberg, Keith Busch, Jens Axboe,
	Dan Williams, Eric Pilmore, Stephen Bates, Logan Gunthorpe

Here's v2 of the patchset. It doesn't sound like there's anything
terribly controversial here so this version is mostly just some
cleanup changes for clarity.

Changes in v2:
 * Rebase on v5.3-rc2 (No changes)
 * Re-introduce the private pagemap structure and move the p2p-specific
   elements out of the commond dev_pagemap (per Christoph)
 * Use flags instead of bool in the whitelist (per Jason)
 * Only store the mapping type in the xarray (instead of the distance
   with flags) such that a function can return the mapping method
   with a switch statement to decide how to map. (per Christoph)
 * Drop find_parent_pci_dev() on the fast path and rely on the fact
   that the struct device passed to the mapping functions *must* be
   a PCI device and convert it directly. (per suggestions from
   Christoph and Jason)
 * Collected Christian's Reviewed-by's

--

As discussed on the list previously, in order to fully support the
whitelist Christian added with the IOMMU, we must ensure that we
map any buffer going through the IOMMU with an aprropriate dma_map
call. This patchset accomplishes this by cleaning up the output of
upstream_bridge_distance() to better indicate the mapping requirements,
caching these requirements in an xarray, then looking them up at map
time and applying the appropriate mapping method.

After this patchset, it's possible to use the NVMe-of P2P support to
transfer between devices without a switch on the whitelisted root
complexes. A couple Intel device I have tested this on have also
been added to the white list.

Most of the changes are contained within the p2pdma.c, but there are
a few minor touches to other subsystems, mostly to add support
to call an unmap function.

The final patch in this series demonstrates a possible
pci_p2pdma_map_resource() function that I expect Christian will need
but does not have any users at this time so I don't intend for it to be
considered for merging.

This patchset is based on 5.3-rc2 and a git branch is available here:

https://github.com/sbates130272/linux-p2pmem/ p2pdma_rc_map_v2

--

Logan Gunthorpe (14):
  PCI/P2PDMA: Introduce private pagemap structure
  PCI/P2PDMA: Add the provider's pci_dev to the pci_p2pdma_pagemap
    struct
  PCI/P2PDMA: Add constants for not-supported result
    upstream_bridge_distance()
  PCI/P2PDMA: Factor out __upstream_bridge_distance()
  PCI/P2PDMA: Apply host bridge white list for ACS
  PCI/P2PDMA: Factor out host_bridge_whitelist()
  PCI/P2PDMA: Add whitelist support for Intel Host Bridges
  PCI/P2PDMA: Add attrs argument to pci_p2pdma_map_sg()
  PCI/P2PDMA: Introduce pci_p2pdma_unmap_sg()
  PCI/P2PDMA: Factor out __pci_p2pdma_map_sg()
  PCI/P2PDMA: Store mapping method in an xarray
  PCI/P2PDMA: dma_map P2PDMA map requests that traverse the host bridge
  PCI/P2PDMA: No longer require no-mmu for host bridge whitelist
  PCI/P2PDMA: Update documentation for pci_p2pdma_distance_many()

 drivers/infiniband/core/rw.c |   6 +-
 drivers/nvme/host/pci.c      |  10 +-
 drivers/pci/p2pdma.c         | 361 +++++++++++++++++++++++++----------
 include/linux/memremap.h     |   1 -
 include/linux/pci-p2pdma.h   |  28 ++-
 5 files changed, 296 insertions(+), 110 deletions(-)

--
2.20.1

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 01/14] PCI/P2PDMA: Introduce private pagemap structure
  2019-07-30 16:35 [PATCH v2 00/14] PCI/P2PDMA: Support transactions that hit the host bridge Logan Gunthorpe
@ 2019-07-30 16:35 ` Logan Gunthorpe
  2019-07-30 16:35 ` [PATCH v2 02/14] PCI/P2PDMA: Add the provider's pci_dev to the pci_p2pdma_pagemap struct Logan Gunthorpe
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Logan Gunthorpe @ 2019-07-30 16:35 UTC (permalink / raw)
  To: linux-kernel, linux-pci, linux-nvme, linux-rdma
  Cc: Bjorn Helgaas, Christoph Hellwig, Christian Koenig,
	Jason Gunthorpe, Sagi Grimberg, Keith Busch, Jens Axboe,
	Dan Williams, Eric Pilmore, Stephen Bates, Logan Gunthorpe

Move the PCI bus offset from the generic dev_pagemap structure to a
specific pci_p2pdma_pagemap structure.

This structure will grow in subsequent patches.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/pci/p2pdma.c     | 26 ++++++++++++++++++++------
 include/linux/memremap.h |  1 -
 2 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index 234476226529..03e9c887bdfb 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -25,6 +25,16 @@ struct pci_p2pdma {
 	bool p2pmem_published;
 };
 
+struct pci_p2pdma_pagemap {
+	struct dev_pagemap pgmap;
+	u64 bus_offset;
+};
+
+static struct pci_p2pdma_pagemap *to_p2p_pgmap(struct dev_pagemap *pgmap)
+{
+	return container_of(pgmap, struct pci_p2pdma_pagemap, pgmap);
+}
+
 static ssize_t size_show(struct device *dev, struct device_attribute *attr,
 			 char *buf)
 {
@@ -135,6 +145,7 @@ static int pci_p2pdma_setup(struct pci_dev *pdev)
 int pci_p2pdma_add_resource(struct pci_dev *pdev, int bar, size_t size,
 			    u64 offset)
 {
+	struct pci_p2pdma_pagemap *p2p_pgmap;
 	struct dev_pagemap *pgmap;
 	void *addr;
 	int error;
@@ -157,14 +168,17 @@ int pci_p2pdma_add_resource(struct pci_dev *pdev, int bar, size_t size,
 			return error;
 	}
 
-	pgmap = devm_kzalloc(&pdev->dev, sizeof(*pgmap), GFP_KERNEL);
-	if (!pgmap)
+	p2p_pgmap = devm_kzalloc(&pdev->dev, sizeof(*p2p_pgmap), GFP_KERNEL);
+	if (!p2p_pgmap)
 		return -ENOMEM;
+
+	pgmap = &p2p_pgmap->pgmap;
 	pgmap->res.start = pci_resource_start(pdev, bar) + offset;
 	pgmap->res.end = pgmap->res.start + size - 1;
 	pgmap->res.flags = pci_resource_flags(pdev, bar);
 	pgmap->type = MEMORY_DEVICE_PCI_P2PDMA;
-	pgmap->pci_p2pdma_bus_offset = pci_bus_address(pdev, bar) -
+
+	p2p_pgmap->bus_offset = pci_bus_address(pdev, bar) -
 		pci_resource_start(pdev, bar);
 
 	addr = devm_memremap_pages(&pdev->dev, pgmap);
@@ -720,7 +734,7 @@ EXPORT_SYMBOL_GPL(pci_p2pmem_publish);
 int pci_p2pdma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 		      enum dma_data_direction dir)
 {
-	struct dev_pagemap *pgmap;
+	struct pci_p2pdma_pagemap *p2p_pgmap;
 	struct scatterlist *s;
 	phys_addr_t paddr;
 	int i;
@@ -736,10 +750,10 @@ int pci_p2pdma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 		return 0;
 
 	for_each_sg(sg, s, nents, i) {
-		pgmap = sg_page(s)->pgmap;
+		p2p_pgmap = to_p2p_pgmap(sg_page(s)->pgmap);
 		paddr = sg_phys(s);
 
-		s->dma_address = paddr - pgmap->pci_p2pdma_bus_offset;
+		s->dma_address = paddr - p2p_pgmap->bus_offset;
 		sg_dma_len(s) = s->length;
 	}
 
diff --git a/include/linux/memremap.h b/include/linux/memremap.h
index f8a5b2a19945..b459518ce475 100644
--- a/include/linux/memremap.h
+++ b/include/linux/memremap.h
@@ -112,7 +112,6 @@ struct dev_pagemap {
 	struct device *dev;
 	enum memory_type type;
 	unsigned int flags;
-	u64 pci_p2pdma_bus_offset;
 	const struct dev_pagemap_ops *ops;
 };
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 02/14] PCI/P2PDMA: Add the provider's pci_dev to the pci_p2pdma_pagemap struct
  2019-07-30 16:35 [PATCH v2 00/14] PCI/P2PDMA: Support transactions that hit the host bridge Logan Gunthorpe
  2019-07-30 16:35 ` [PATCH v2 01/14] PCI/P2PDMA: Introduce private pagemap structure Logan Gunthorpe
@ 2019-07-30 16:35 ` Logan Gunthorpe
  2019-07-30 16:35 ` [PATCH v2 03/14] PCI/P2PDMA: Add constants for not-supported result upstream_bridge_distance() Logan Gunthorpe
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Logan Gunthorpe @ 2019-07-30 16:35 UTC (permalink / raw)
  To: linux-kernel, linux-pci, linux-nvme, linux-rdma
  Cc: Bjorn Helgaas, Christoph Hellwig, Christian Koenig,
	Jason Gunthorpe, Sagi Grimberg, Keith Busch, Jens Axboe,
	Dan Williams, Eric Pilmore, Stephen Bates, Logan Gunthorpe

The provider will be needed to figure out how to properly map
a device.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/pci/p2pdma.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index 03e9c887bdfb..93fbda14f4a9 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -27,6 +27,7 @@ struct pci_p2pdma {
 
 struct pci_p2pdma_pagemap {
 	struct dev_pagemap pgmap;
+	struct pci_dev *provider;
 	u64 bus_offset;
 };
 
@@ -178,6 +179,7 @@ int pci_p2pdma_add_resource(struct pci_dev *pdev, int bar, size_t size,
 	pgmap->res.flags = pci_resource_flags(pdev, bar);
 	pgmap->type = MEMORY_DEVICE_PCI_P2PDMA;
 
+	p2p_pgmap->provider = pdev;
 	p2p_pgmap->bus_offset = pci_bus_address(pdev, bar) -
 		pci_resource_start(pdev, bar);
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 03/14] PCI/P2PDMA: Add constants for not-supported result upstream_bridge_distance()
  2019-07-30 16:35 [PATCH v2 00/14] PCI/P2PDMA: Support transactions that hit the host bridge Logan Gunthorpe
  2019-07-30 16:35 ` [PATCH v2 01/14] PCI/P2PDMA: Introduce private pagemap structure Logan Gunthorpe
  2019-07-30 16:35 ` [PATCH v2 02/14] PCI/P2PDMA: Add the provider's pci_dev to the pci_p2pdma_pagemap struct Logan Gunthorpe
@ 2019-07-30 16:35 ` Logan Gunthorpe
  2019-08-07  5:54   ` Christoph Hellwig
  2019-07-30 16:35 ` [PATCH v2 04/14] PCI/P2PDMA: Factor out __upstream_bridge_distance() Logan Gunthorpe
                   ` (11 subsequent siblings)
  14 siblings, 1 reply; 26+ messages in thread
From: Logan Gunthorpe @ 2019-07-30 16:35 UTC (permalink / raw)
  To: linux-kernel, linux-pci, linux-nvme, linux-rdma
  Cc: Bjorn Helgaas, Christoph Hellwig, Christian Koenig,
	Jason Gunthorpe, Sagi Grimberg, Keith Busch, Jens Axboe,
	Dan Williams, Eric Pilmore, Stephen Bates, Logan Gunthorpe,
	Christian König

Add constant flags to indicate two devices are not supported or whether
the data path goes through the host bridge instead of using the negative
values -1 and -2.

This helps annotate the code better, but the main reason is so we
can use the information to store the required mapping method in an
xarray.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
---
 drivers/pci/p2pdma.c | 52 ++++++++++++++++++++++++++------------------
 1 file changed, 31 insertions(+), 21 deletions(-)

diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index 93fbda14f4a9..64f5a0e30244 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -289,6 +289,20 @@ static bool root_complex_whitelist(struct pci_dev *dev)
 	return false;
 }
 
+enum {
+	/*
+	 * These arbitrary offset are or'd onto the upstream distance
+	 * calculation for the following conditions:
+	 */
+
+	/* The data path includes the host-bridge */
+	P2PDMA_THRU_HOST_BRIDGE		= 0x02000000,
+	/* The data path is forced through the host-bridge due to ACS */
+	P2PDMA_ACS_FORCES_UPSTREAM	= 0x04000000,
+	/* The data path is not supported by P2PDMA */
+	P2PDMA_NOT_SUPPORTED		= 0x08000000,
+};
+
 /*
  * Find the distance through the nearest common upstream bridge between
  * two PCI devices.
@@ -313,22 +327,17 @@ static bool root_complex_whitelist(struct pci_dev *dev)
  * port of the switch, to the common upstream port, back up to the second
  * downstream port and then to Device B.
  *
- * Any two devices that don't have a common upstream bridge will return -1.
- * In this way devices on separate PCIe root ports will be rejected, which
- * is what we want for peer-to-peer seeing each PCIe root port defines a
- * separate hierarchy domain and there's no way to determine whether the root
- * complex supports forwarding between them.
+ * Any two devices that cannot communicate using p2pdma will return the distance
+ * with the flag P2PDMA_NOT_SUPPORTED.
  *
- * In the case where two devices are connected to different PCIe switches,
- * this function will still return a positive distance as long as both
- * switches eventually have a common upstream bridge. Note this covers
- * the case of using multiple PCIe switches to achieve a desired level of
- * fan-out from a root port. The exact distance will be a function of the
- * number of switches between Device A and Device B.
+ * Any two devices that have a data path that goes through the host bridge
+ * will consult a whitelist. If the host bridges are on the whitelist,
+ * then the distance will be returned with the flag P2PDMA_THRU_HOST_BRIDGE set.
+ * If either bridge is not on the whitelist, the flag P2PDMA_NOT_SUPPORTED will
+ * be set.
  *
  * If a bridge which has any ACS redirection bits set is in the path
- * then this functions will return -2. This is so we reject any
- * cases where the TLPs are forwarded up into the root complex.
+ * then this functions will flag the result with P2PDMA_ACS_FORCES_UPSTREAM.
  * In this case, a list of all infringing bridge addresses will be
  * populated in acs_list (assuming it's non-null) for printk purposes.
  */
@@ -375,9 +384,9 @@ static int upstream_bridge_distance(struct pci_dev *provider,
 	 */
 	if (root_complex_whitelist(provider) &&
 	    root_complex_whitelist(client))
-		return 0x1000 + dist_a + dist_b;
+		return (dist_a + dist_b) | P2PDMA_THRU_HOST_BRIDGE;
 
-	return -1;
+	return (dist_a + dist_b) | P2PDMA_NOT_SUPPORTED;
 
 check_b_path_acs:
 	bb = b;
@@ -395,7 +404,7 @@ static int upstream_bridge_distance(struct pci_dev *provider,
 	}
 
 	if (acs_cnt)
-		return -2;
+		return P2PDMA_NOT_SUPPORTED | P2PDMA_ACS_FORCES_UPSTREAM;
 
 	return dist_a + dist_b;
 }
@@ -411,16 +420,17 @@ static int upstream_bridge_distance_warn(struct pci_dev *provider,
 		return -ENOMEM;
 
 	ret = upstream_bridge_distance(provider, client, &acs_list);
-	if (ret == -2) {
-		pci_warn(client, "cannot be used for peer-to-peer DMA as ACS redirect is set between the client and provider (%s)\n",
+	if (ret & P2PDMA_ACS_FORCES_UPSTREAM) {
+		pci_warn(client, "ACS redirect is set between the client and provider (%s)\n",
 			 pci_name(provider));
 		/* Drop final semicolon */
 		acs_list.buffer[acs_list.len-1] = 0;
 		pci_warn(client, "to disable ACS redirect for this path, add the kernel parameter: pci=disable_acs_redir=%s\n",
 			 acs_list.buffer);
+	}
 
-	} else if (ret < 0) {
-		pci_warn(client, "cannot be used for peer-to-peer DMA as the client and provider (%s) do not share an upstream bridge\n",
+	if (ret & P2PDMA_NOT_SUPPORTED) {
+		pci_warn(client, "cannot be used for peer-to-peer DMA as the client and provider (%s) do not share an upstream bridge or whitelisted host bridge\n",
 			 pci_name(provider));
 	}
 
@@ -484,7 +494,7 @@ int pci_p2pdma_distance_many(struct pci_dev *provider, struct device **clients,
 
 		pci_dev_put(pci_client);
 
-		if (ret < 0)
+		if (ret & P2PDMA_NOT_SUPPORTED)
 			not_supported = true;
 
 		if (not_supported && !verbose)
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 04/14] PCI/P2PDMA: Factor out __upstream_bridge_distance()
  2019-07-30 16:35 [PATCH v2 00/14] PCI/P2PDMA: Support transactions that hit the host bridge Logan Gunthorpe
                   ` (2 preceding siblings ...)
  2019-07-30 16:35 ` [PATCH v2 03/14] PCI/P2PDMA: Add constants for not-supported result upstream_bridge_distance() Logan Gunthorpe
@ 2019-07-30 16:35 ` Logan Gunthorpe
  2019-07-30 16:35 ` [PATCH v2 05/14] PCI/P2PDMA: Apply host bridge white list for ACS Logan Gunthorpe
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Logan Gunthorpe @ 2019-07-30 16:35 UTC (permalink / raw)
  To: linux-kernel, linux-pci, linux-nvme, linux-rdma
  Cc: Bjorn Helgaas, Christoph Hellwig, Christian Koenig,
	Jason Gunthorpe, Sagi Grimberg, Keith Busch, Jens Axboe,
	Dan Williams, Eric Pilmore, Stephen Bates, Logan Gunthorpe,
	Christian König

This is a prep patch to create a second level helper. There are no
functional changes.

The root complex whitelist code will be moved into this function in
a subsequent patch.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
---
 drivers/pci/p2pdma.c | 89 ++++++++++++++++++++++++--------------------
 1 file changed, 48 insertions(+), 41 deletions(-)

diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index 64f5a0e30244..b4ef6e8da784 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -303,47 +303,9 @@ enum {
 	P2PDMA_NOT_SUPPORTED		= 0x08000000,
 };
 
-/*
- * Find the distance through the nearest common upstream bridge between
- * two PCI devices.
- *
- * If the two devices are the same device then 0 will be returned.
- *
- * If there are two virtual functions of the same device behind the same
- * bridge port then 2 will be returned (one step down to the PCIe switch,
- * then one step back to the same device).
- *
- * In the case where two devices are connected to the same PCIe switch, the
- * value 4 will be returned. This corresponds to the following PCI tree:
- *
- *     -+  Root Port
- *      \+ Switch Upstream Port
- *       +-+ Switch Downstream Port
- *       + \- Device A
- *       \-+ Switch Downstream Port
- *         \- Device B
- *
- * The distance is 4 because we traverse from Device A through the downstream
- * port of the switch, to the common upstream port, back up to the second
- * downstream port and then to Device B.
- *
- * Any two devices that cannot communicate using p2pdma will return the distance
- * with the flag P2PDMA_NOT_SUPPORTED.
- *
- * Any two devices that have a data path that goes through the host bridge
- * will consult a whitelist. If the host bridges are on the whitelist,
- * then the distance will be returned with the flag P2PDMA_THRU_HOST_BRIDGE set.
- * If either bridge is not on the whitelist, the flag P2PDMA_NOT_SUPPORTED will
- * be set.
- *
- * If a bridge which has any ACS redirection bits set is in the path
- * then this functions will flag the result with P2PDMA_ACS_FORCES_UPSTREAM.
- * In this case, a list of all infringing bridge addresses will be
- * populated in acs_list (assuming it's non-null) for printk purposes.
- */
-static int upstream_bridge_distance(struct pci_dev *provider,
-				    struct pci_dev *client,
-				    struct seq_buf *acs_list)
+static int __upstream_bridge_distance(struct pci_dev *provider,
+				      struct pci_dev *client,
+				      struct seq_buf *acs_list)
 {
 	struct pci_dev *a = provider, *b = client, *bb;
 	int dist_a = 0;
@@ -409,6 +371,51 @@ static int upstream_bridge_distance(struct pci_dev *provider,
 	return dist_a + dist_b;
 }
 
+/*
+ * Find the distance through the nearest common upstream bridge between
+ * two PCI devices.
+ *
+ * If the two devices are the same device then 0 will be returned.
+ *
+ * If there are two virtual functions of the same device behind the same
+ * bridge port then 2 will be returned (one step down to the PCIe switch,
+ * then one step back to the same device).
+ *
+ * In the case where two devices are connected to the same PCIe switch, the
+ * value 4 will be returned. This corresponds to the following PCI tree:
+ *
+ *     -+  Root Port
+ *      \+ Switch Upstream Port
+ *       +-+ Switch Downstream Port
+ *       + \- Device A
+ *       \-+ Switch Downstream Port
+ *         \- Device B
+ *
+ * The distance is 4 because we traverse from Device A through the downstream
+ * port of the switch, to the common upstream port, back up to the second
+ * downstream port and then to Device B.
+ *
+ * Any two devices that cannot communicate using p2pdma will return the distance
+ * with the flag P2PDMA_NOT_SUPPORTED.
+ *
+ * Any two devices that have a data path that goes through the host bridge
+ * will consult a whitelist. If the host bridges are on the whitelist,
+ * then the distance will be returned with the flag P2PDMA_THRU_HOST_BRIDGE set.
+ * If either bridge is not on the whitelist, the flag P2PDMA_NOT_SUPPORTED will
+ * be set.
+ *
+ * If a bridge which has any ACS redirection bits set is in the path
+ * then this functions will flag the result with P2PDMA_ACS_FORCES_UPSTREAM.
+ * In this case, a list of all infringing bridge addresses will be
+ * populated in acs_list (assuming it's non-null) for printk purposes.
+ */
+static int upstream_bridge_distance(struct pci_dev *provider,
+				    struct pci_dev *client,
+				    struct seq_buf *acs_list)
+{
+	return __upstream_bridge_distance(provider, client, acs_list);
+}
+
 static int upstream_bridge_distance_warn(struct pci_dev *provider,
 					 struct pci_dev *client)
 {
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 05/14] PCI/P2PDMA: Apply host bridge white list for ACS
  2019-07-30 16:35 [PATCH v2 00/14] PCI/P2PDMA: Support transactions that hit the host bridge Logan Gunthorpe
                   ` (3 preceding siblings ...)
  2019-07-30 16:35 ` [PATCH v2 04/14] PCI/P2PDMA: Factor out __upstream_bridge_distance() Logan Gunthorpe
@ 2019-07-30 16:35 ` Logan Gunthorpe
  2019-07-30 16:35 ` [PATCH v2 06/14] PCI/P2PDMA: Factor out host_bridge_whitelist() Logan Gunthorpe
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Logan Gunthorpe @ 2019-07-30 16:35 UTC (permalink / raw)
  To: linux-kernel, linux-pci, linux-nvme, linux-rdma
  Cc: Bjorn Helgaas, Christoph Hellwig, Christian Koenig,
	Jason Gunthorpe, Sagi Grimberg, Keith Busch, Jens Axboe,
	Dan Williams, Eric Pilmore, Stephen Bates, Logan Gunthorpe,
	Christian König

When a P2PDMA transfer is rejected due to ACS being set, we
can also check the white list and allow the transactions.

Do this by pushing the whitelist check into the
upstream_bridge_distance() function.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
---
 drivers/pci/p2pdma.c | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index b4ef6e8da784..10765ab90e64 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -340,15 +340,7 @@ static int __upstream_bridge_distance(struct pci_dev *provider,
 		dist_a++;
 	}
 
-	/*
-	 * Allow the connection if both devices are on a whitelisted root
-	 * complex, but add an arbitrary large value to the distance.
-	 */
-	if (root_complex_whitelist(provider) &&
-	    root_complex_whitelist(client))
-		return (dist_a + dist_b) | P2PDMA_THRU_HOST_BRIDGE;
-
-	return (dist_a + dist_b) | P2PDMA_NOT_SUPPORTED;
+	return (dist_a + dist_b) | P2PDMA_THRU_HOST_BRIDGE;
 
 check_b_path_acs:
 	bb = b;
@@ -366,7 +358,8 @@ static int __upstream_bridge_distance(struct pci_dev *provider,
 	}
 
 	if (acs_cnt)
-		return P2PDMA_NOT_SUPPORTED | P2PDMA_ACS_FORCES_UPSTREAM;
+		return (dist_a + dist_b) | P2PDMA_ACS_FORCES_UPSTREAM |
+			P2PDMA_THRU_HOST_BRIDGE;
 
 	return dist_a + dist_b;
 }
@@ -413,7 +406,17 @@ static int upstream_bridge_distance(struct pci_dev *provider,
 				    struct pci_dev *client,
 				    struct seq_buf *acs_list)
 {
-	return __upstream_bridge_distance(provider, client, acs_list);
+	int dist;
+
+	dist = __upstream_bridge_distance(provider, client, acs_list);
+
+	if (!(dist & P2PDMA_THRU_HOST_BRIDGE))
+		return dist;
+
+	if (root_complex_whitelist(provider) && root_complex_whitelist(client))
+		return dist;
+
+	return dist | P2PDMA_NOT_SUPPORTED;
 }
 
 static int upstream_bridge_distance_warn(struct pci_dev *provider,
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 06/14] PCI/P2PDMA: Factor out host_bridge_whitelist()
  2019-07-30 16:35 [PATCH v2 00/14] PCI/P2PDMA: Support transactions that hit the host bridge Logan Gunthorpe
                   ` (4 preceding siblings ...)
  2019-07-30 16:35 ` [PATCH v2 05/14] PCI/P2PDMA: Apply host bridge white list for ACS Logan Gunthorpe
@ 2019-07-30 16:35 ` Logan Gunthorpe
  2019-07-30 16:35 ` [PATCH v2 07/14] PCI/P2PDMA: Add whitelist support for Intel Host Bridges Logan Gunthorpe
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Logan Gunthorpe @ 2019-07-30 16:35 UTC (permalink / raw)
  To: linux-kernel, linux-pci, linux-nvme, linux-rdma
  Cc: Bjorn Helgaas, Christoph Hellwig, Christian Koenig,
	Jason Gunthorpe, Sagi Grimberg, Keith Busch, Jens Axboe,
	Dan Williams, Eric Pilmore, Stephen Bates, Logan Gunthorpe

Push both PCI devices into the whitelist checking function seeing
some hardware will require us ensuring they are on the same host
bridge.

At the same time we rename root_complex_whitelist() to
host_bridge_whitelist() to match the terminology used in the code.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/pci/p2pdma.c | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index 10765ab90e64..ca36ea533ed7 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -262,19 +262,11 @@ static void seq_buf_print_bus_devfn(struct seq_buf *buf, struct pci_dev *pdev)
 	seq_buf_printf(buf, "%s;", pci_name(pdev));
 }
 
-/*
- * If we can't find a common upstream bridge take a look at the root
- * complex and compare it to a whitelist of known good hardware.
- */
-static bool root_complex_whitelist(struct pci_dev *dev)
+static bool __host_bridge_whitelist(struct pci_host_bridge *host)
 {
-	struct pci_host_bridge *host = pci_find_host_bridge(dev->bus);
 	struct pci_dev *root = pci_get_slot(host->bus, PCI_DEVFN(0, 0));
 	unsigned short vendor, device;
 
-	if (iommu_present(dev->dev.bus))
-		return false;
-
 	if (!root)
 		return false;
 
@@ -289,6 +281,24 @@ static bool root_complex_whitelist(struct pci_dev *dev)
 	return false;
 }
 
+/*
+ * If we can't find a common upstream bridge take a look at the root
+ * complex and compare it to a whitelist of known good hardware.
+ */
+static bool host_bridge_whitelist(struct pci_dev *a, struct pci_dev *b)
+{
+	struct pci_host_bridge *host_a = pci_find_host_bridge(a->bus);
+	struct pci_host_bridge *host_b = pci_find_host_bridge(b->bus);
+
+	if (iommu_present(a->dev.bus) || iommu_present(b->dev.bus))
+		return false;
+
+	if (__host_bridge_whitelist(host_a) && __host_bridge_whitelist(host_b))
+		return true;
+
+	return false;
+}
+
 enum {
 	/*
 	 * These arbitrary offset are or'd onto the upstream distance
@@ -413,7 +423,7 @@ static int upstream_bridge_distance(struct pci_dev *provider,
 	if (!(dist & P2PDMA_THRU_HOST_BRIDGE))
 		return dist;
 
-	if (root_complex_whitelist(provider) && root_complex_whitelist(client))
+	if (host_bridge_whitelist(provider, client))
 		return dist;
 
 	return dist | P2PDMA_NOT_SUPPORTED;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 07/14] PCI/P2PDMA: Add whitelist support for Intel Host Bridges
  2019-07-30 16:35 [PATCH v2 00/14] PCI/P2PDMA: Support transactions that hit the host bridge Logan Gunthorpe
                   ` (5 preceding siblings ...)
  2019-07-30 16:35 ` [PATCH v2 06/14] PCI/P2PDMA: Factor out host_bridge_whitelist() Logan Gunthorpe
@ 2019-07-30 16:35 ` Logan Gunthorpe
  2019-07-30 16:35 ` [PATCH v2 08/14] PCI/P2PDMA: Add attrs argument to pci_p2pdma_map_sg() Logan Gunthorpe
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Logan Gunthorpe @ 2019-07-30 16:35 UTC (permalink / raw)
  To: linux-kernel, linux-pci, linux-nvme, linux-rdma
  Cc: Bjorn Helgaas, Christoph Hellwig, Christian Koenig,
	Jason Gunthorpe, Sagi Grimberg, Keith Busch, Jens Axboe,
	Dan Williams, Eric Pilmore, Stephen Bates, Logan Gunthorpe

Intel devices do not have good support for P2P requests that span
different host bridges as the transactions will cross the QPI/UPI bus
and this does not perform well.

Therefore, enable support for these devices only if the host bridges
match.

Adds the Intel device's that have been tested to work. There are
likely many others out there that will need to be tested and added.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/pci/p2pdma.c | 38 ++++++++++++++++++++++++++++++++++----
 1 file changed, 34 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index ca36ea533ed7..1504f7ea006a 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -262,9 +262,30 @@ static void seq_buf_print_bus_devfn(struct seq_buf *buf, struct pci_dev *pdev)
 	seq_buf_printf(buf, "%s;", pci_name(pdev));
 }
 
-static bool __host_bridge_whitelist(struct pci_host_bridge *host)
+static const struct pci_p2pdma_whitelist_entry {
+	unsigned short vendor;
+	unsigned short device;
+	enum {
+		REQ_SAME_HOST_BRIDGE	= 1 << 0,
+	} flags;
+} pci_p2pdma_whitelist[] = {
+	/* AMD ZEN */
+	{PCI_VENDOR_ID_AMD,	0x1450,	0},
+
+	/* Intel Xeon E5/Core i7 */
+	{PCI_VENDOR_ID_INTEL,	0x3c00, REQ_SAME_HOST_BRIDGE},
+	{PCI_VENDOR_ID_INTEL,	0x3c01, REQ_SAME_HOST_BRIDGE},
+	/* Intel Xeon E7 v3/Xeon E5 v3/Core i7 */
+	{PCI_VENDOR_ID_INTEL,	0x2f00, REQ_SAME_HOST_BRIDGE},
+	{PCI_VENDOR_ID_INTEL,	0x2f01, REQ_SAME_HOST_BRIDGE},
+	{}
+};
+
+static bool __host_bridge_whitelist(struct pci_host_bridge *host,
+				    bool same_host_bridge)
 {
 	struct pci_dev *root = pci_get_slot(host->bus, PCI_DEVFN(0, 0));
+	const struct pci_p2pdma_whitelist_entry *entry;
 	unsigned short vendor, device;
 
 	if (!root)
@@ -274,9 +295,14 @@ static bool __host_bridge_whitelist(struct pci_host_bridge *host)
 	device = root->device;
 	pci_dev_put(root);
 
-	/* AMD ZEN host bridges can do peer to peer */
-	if (vendor == PCI_VENDOR_ID_AMD && device == 0x1450)
+	for (entry = pci_p2pdma_whitelist; entry->vendor; entry++) {
+		if (vendor != entry->vendor || device != entry->device)
+			continue;
+		if (entry->flags & REQ_SAME_HOST_BRIDGE && !same_host_bridge)
+			return false;
+
 		return true;
+	}
 
 	return false;
 }
@@ -293,7 +319,11 @@ static bool host_bridge_whitelist(struct pci_dev *a, struct pci_dev *b)
 	if (iommu_present(a->dev.bus) || iommu_present(b->dev.bus))
 		return false;
 
-	if (__host_bridge_whitelist(host_a) && __host_bridge_whitelist(host_b))
+	if (host_a == host_b)
+		return __host_bridge_whitelist(host_a, true);
+
+	if (__host_bridge_whitelist(host_a, false) &&
+	    __host_bridge_whitelist(host_b, false))
 		return true;
 
 	return false;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 08/14] PCI/P2PDMA: Add attrs argument to pci_p2pdma_map_sg()
  2019-07-30 16:35 [PATCH v2 00/14] PCI/P2PDMA: Support transactions that hit the host bridge Logan Gunthorpe
                   ` (6 preceding siblings ...)
  2019-07-30 16:35 ` [PATCH v2 07/14] PCI/P2PDMA: Add whitelist support for Intel Host Bridges Logan Gunthorpe
@ 2019-07-30 16:35 ` Logan Gunthorpe
  2019-07-30 16:35 ` [PATCH v2 09/14] PCI/P2PDMA: Introduce pci_p2pdma_unmap_sg() Logan Gunthorpe
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Logan Gunthorpe @ 2019-07-30 16:35 UTC (permalink / raw)
  To: linux-kernel, linux-pci, linux-nvme, linux-rdma
  Cc: Bjorn Helgaas, Christoph Hellwig, Christian Koenig,
	Jason Gunthorpe, Sagi Grimberg, Keith Busch, Jens Axboe,
	Dan Williams, Eric Pilmore, Stephen Bates, Logan Gunthorpe

This is to match the dma_map_sg() API which this function will have
to call in an future patch.

Adds a pci_p2pdma_map_sg_attrs() function and helper to call it with
no attributes just like the dma_map_sg() function.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/nvme/host/pci.c    |  4 ++--
 drivers/pci/p2pdma.c       |  7 ++++---
 include/linux/pci-p2pdma.h | 15 +++++++++++----
 3 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index db160cee42ad..f97bb031228a 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -832,8 +832,8 @@ static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req,
 		goto out;
 
 	if (is_pci_p2pdma_page(sg_page(iod->sg)))
-		nr_mapped = pci_p2pdma_map_sg(dev->dev, iod->sg, iod->nents,
-					      rq_dma_dir(req));
+		nr_mapped = pci_p2pdma_map_sg_attrs(dev->dev, iod->sg,
+				iod->nents, rq_dma_dir(req), DMA_ATTR_NO_WARN);
 	else
 		nr_mapped = dma_map_sg_attrs(dev->dev, iod->sg, iod->nents,
 					     rq_dma_dir(req), DMA_ATTR_NO_WARN);
diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index 1504f7ea006a..0d875abea8a1 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -788,13 +788,14 @@ EXPORT_SYMBOL_GPL(pci_p2pmem_publish);
  * @sg: scatter list to map
  * @nents: elements in the scatterlist
  * @dir: DMA direction
+ * @attrs: dma attributes passed to dma_map_sg() (if called)
  *
  * Scatterlists mapped with this function should not be unmapped in any way.
  *
  * Returns the number of SG entries mapped or 0 on error.
  */
-int pci_p2pdma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-		      enum dma_data_direction dir)
+int pci_p2pdma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
+		int nents, enum dma_data_direction dir, unsigned long attrs)
 {
 	struct pci_p2pdma_pagemap *p2p_pgmap;
 	struct scatterlist *s;
@@ -821,7 +822,7 @@ int pci_p2pdma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 
 	return nents;
 }
-EXPORT_SYMBOL_GPL(pci_p2pdma_map_sg);
+EXPORT_SYMBOL_GPL(pci_p2pdma_map_sg_attrs);
 
 /**
  * pci_p2pdma_enable_store - parse a configfs/sysfs attribute store
diff --git a/include/linux/pci-p2pdma.h b/include/linux/pci-p2pdma.h
index bca9bc3e5be7..7fd51954f93a 100644
--- a/include/linux/pci-p2pdma.h
+++ b/include/linux/pci-p2pdma.h
@@ -30,8 +30,8 @@ struct scatterlist *pci_p2pmem_alloc_sgl(struct pci_dev *pdev,
 					 unsigned int *nents, u32 length);
 void pci_p2pmem_free_sgl(struct pci_dev *pdev, struct scatterlist *sgl);
 void pci_p2pmem_publish(struct pci_dev *pdev, bool publish);
-int pci_p2pdma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-		      enum dma_data_direction dir);
+int pci_p2pdma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
+		int nents, enum dma_data_direction dir, unsigned long attrs);
 int pci_p2pdma_enable_store(const char *page, struct pci_dev **p2p_dev,
 			    bool *use_p2pdma);
 ssize_t pci_p2pdma_enable_show(char *page, struct pci_dev *p2p_dev,
@@ -81,8 +81,9 @@ static inline void pci_p2pmem_free_sgl(struct pci_dev *pdev,
 static inline void pci_p2pmem_publish(struct pci_dev *pdev, bool publish)
 {
 }
-static inline int pci_p2pdma_map_sg(struct device *dev,
-		struct scatterlist *sg, int nents, enum dma_data_direction dir)
+static inline int pci_p2pdma_map_sg_attrs(struct device *dev,
+		struct scatterlist *sg, int nents, enum dma_data_direction dir,
+		unsigned long attrs)
 {
 	return 0;
 }
@@ -111,4 +112,10 @@ static inline struct pci_dev *pci_p2pmem_find(struct device *client)
 	return pci_p2pmem_find_many(&client, 1);
 }
 
+static inline int pci_p2pdma_map_sg(struct device *dev, struct scatterlist *sg,
+				    int nents, enum dma_data_direction dir)
+{
+	return pci_p2pdma_map_sg_attrs(dev, sg, nents, dir, 0);
+}
+
 #endif /* _LINUX_PCI_P2P_H */
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 09/14] PCI/P2PDMA: Introduce pci_p2pdma_unmap_sg()
  2019-07-30 16:35 [PATCH v2 00/14] PCI/P2PDMA: Support transactions that hit the host bridge Logan Gunthorpe
                   ` (7 preceding siblings ...)
  2019-07-30 16:35 ` [PATCH v2 08/14] PCI/P2PDMA: Add attrs argument to pci_p2pdma_map_sg() Logan Gunthorpe
@ 2019-07-30 16:35 ` Logan Gunthorpe
  2019-07-30 16:35 ` [PATCH v2 10/14] PCI/P2PDMA: Factor out __pci_p2pdma_map_sg() Logan Gunthorpe
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Logan Gunthorpe @ 2019-07-30 16:35 UTC (permalink / raw)
  To: linux-kernel, linux-pci, linux-nvme, linux-rdma
  Cc: Bjorn Helgaas, Christoph Hellwig, Christian Koenig,
	Jason Gunthorpe, Sagi Grimberg, Keith Busch, Jens Axboe,
	Dan Williams, Eric Pilmore, Stephen Bates, Logan Gunthorpe

Add pci_p2pdma_unmap_sg() to the two places that call
pci_p2pdma_map_sg().

This is a prep patch to introduce correct mappings for p2pdma
transactions that go through the root complex.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/infiniband/core/rw.c |  6 ++++--
 drivers/nvme/host/pci.c      |  6 ++++--
 drivers/pci/p2pdma.c         | 18 +++++++++++++++++-
 include/linux/pci-p2pdma.h   | 13 +++++++++++++
 4 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/drivers/infiniband/core/rw.c b/drivers/infiniband/core/rw.c
index dce06108c8c3..5337393d4dfe 100644
--- a/drivers/infiniband/core/rw.c
+++ b/drivers/infiniband/core/rw.c
@@ -583,8 +583,10 @@ void rdma_rw_ctx_destroy(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u8 port_num,
 		break;
 	}
 
-	/* P2PDMA contexts do not need to be unmapped */
-	if (!is_pci_p2pdma_page(sg_page(sg)))
+	if (is_pci_p2pdma_page(sg_page(sg)))
+		pci_p2pdma_unmap_sg(qp->pd->device->dma_device, sg,
+				    sg_cnt, dir);
+	else
 		ib_dma_unmap_sg(qp->pd->device, sg, sg_cnt, dir);
 }
 EXPORT_SYMBOL(rdma_rw_ctx_destroy);
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index f97bb031228a..0f92cca7a860 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -547,8 +547,10 @@ static void nvme_unmap_data(struct nvme_dev *dev, struct request *req)
 
 	WARN_ON_ONCE(!iod->nents);
 
-	/* P2PDMA requests do not need to be unmapped */
-	if (!is_pci_p2pdma_page(sg_page(iod->sg)))
+	if (is_pci_p2pdma_page(sg_page(iod->sg)))
+		pci_p2pdma_unmap_sg(dev->dev, iod->sg, iod->nents,
+				    rq_dma_dir(req));
+	else
 		dma_unmap_sg(dev->dev, iod->sg, iod->nents, rq_dma_dir(req));
 
 
diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index 0d875abea8a1..392653fe0583 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -790,7 +790,8 @@ EXPORT_SYMBOL_GPL(pci_p2pmem_publish);
  * @dir: DMA direction
  * @attrs: dma attributes passed to dma_map_sg() (if called)
  *
- * Scatterlists mapped with this function should not be unmapped in any way.
+ * Scatterlists mapped with this function should be unmapped using
+ * pci_p2pdma_unmap_sg_attrs().
  *
  * Returns the number of SG entries mapped or 0 on error.
  */
@@ -824,6 +825,21 @@ int pci_p2pdma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
 }
 EXPORT_SYMBOL_GPL(pci_p2pdma_map_sg_attrs);
 
+/**
+ * pci_p2pdma_unmap_sg - unmap a PCI peer-to-peer scatterlist that was
+ *	mapped with pci_p2pdma_map_sg()
+ * @dev: device doing the DMA request
+ * @sg: scatter list to map
+ * @nents: number of elements returned by pci_p2pdma_map_sg()
+ * @dir: DMA direction
+ * @attrs: dma attributes passed to dma_unmap_sg() (if called)
+ */
+void pci_p2pdma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg,
+		int nents, enum dma_data_direction dir, unsigned long attrs)
+{
+}
+EXPORT_SYMBOL_GPL(pci_p2pdma_unmap_sg_attrs);
+
 /**
  * pci_p2pdma_enable_store - parse a configfs/sysfs attribute store
  *		to enable p2pdma
diff --git a/include/linux/pci-p2pdma.h b/include/linux/pci-p2pdma.h
index 7fd51954f93a..8318a97c9c61 100644
--- a/include/linux/pci-p2pdma.h
+++ b/include/linux/pci-p2pdma.h
@@ -32,6 +32,8 @@ void pci_p2pmem_free_sgl(struct pci_dev *pdev, struct scatterlist *sgl);
 void pci_p2pmem_publish(struct pci_dev *pdev, bool publish);
 int pci_p2pdma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
 		int nents, enum dma_data_direction dir, unsigned long attrs);
+void pci_p2pdma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg,
+		int nents, enum dma_data_direction dir, unsigned long attrs);
 int pci_p2pdma_enable_store(const char *page, struct pci_dev **p2p_dev,
 			    bool *use_p2pdma);
 ssize_t pci_p2pdma_enable_show(char *page, struct pci_dev *p2p_dev,
@@ -87,6 +89,11 @@ static inline int pci_p2pdma_map_sg_attrs(struct device *dev,
 {
 	return 0;
 }
+static inline void pci_p2pdma_unmap_sg_attrs(struct device *dev,
+		struct scatterlist *sg, int nents, enum dma_data_direction dir,
+		unsigned long attrs)
+{
+}
 static inline int pci_p2pdma_enable_store(const char *page,
 		struct pci_dev **p2p_dev, bool *use_p2pdma)
 {
@@ -118,4 +125,10 @@ static inline int pci_p2pdma_map_sg(struct device *dev, struct scatterlist *sg,
 	return pci_p2pdma_map_sg_attrs(dev, sg, nents, dir, 0);
 }
 
+static inline void pci_p2pdma_unmap_sg(struct device *dev,
+		struct scatterlist *sg, int nents, enum dma_data_direction dir)
+{
+	pci_p2pdma_unmap_sg_attrs(dev, sg, nents, dir, 0);
+}
+
 #endif /* _LINUX_PCI_P2P_H */
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 10/14] PCI/P2PDMA: Factor out __pci_p2pdma_map_sg()
  2019-07-30 16:35 [PATCH v2 00/14] PCI/P2PDMA: Support transactions that hit the host bridge Logan Gunthorpe
                   ` (8 preceding siblings ...)
  2019-07-30 16:35 ` [PATCH v2 09/14] PCI/P2PDMA: Introduce pci_p2pdma_unmap_sg() Logan Gunthorpe
@ 2019-07-30 16:35 ` Logan Gunthorpe
  2019-07-30 16:35 ` [PATCH v2 11/14] PCI/P2PDMA: Store mapping method in an xarray Logan Gunthorpe
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Logan Gunthorpe @ 2019-07-30 16:35 UTC (permalink / raw)
  To: linux-kernel, linux-pci, linux-nvme, linux-rdma
  Cc: Bjorn Helgaas, Christoph Hellwig, Christian Koenig,
	Jason Gunthorpe, Sagi Grimberg, Keith Busch, Jens Axboe,
	Dan Williams, Eric Pilmore, Stephen Bates, Logan Gunthorpe

Factor out the bus only mapping into it's own static function.
No functional changes. The original pci_p2pdma_map_sg_attrs() will
be used to decide whether this is an appropriate way to map.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/pci/p2pdma.c | 41 ++++++++++++++++++++++++-----------------
 1 file changed, 24 insertions(+), 17 deletions(-)

diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index 392653fe0583..fe647bd8f947 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -782,23 +782,9 @@ void pci_p2pmem_publish(struct pci_dev *pdev, bool publish)
 }
 EXPORT_SYMBOL_GPL(pci_p2pmem_publish);
 
-/**
- * pci_p2pdma_map_sg - map a PCI peer-to-peer scatterlist for DMA
- * @dev: device doing the DMA request
- * @sg: scatter list to map
- * @nents: elements in the scatterlist
- * @dir: DMA direction
- * @attrs: dma attributes passed to dma_map_sg() (if called)
- *
- * Scatterlists mapped with this function should be unmapped using
- * pci_p2pdma_unmap_sg_attrs().
- *
- * Returns the number of SG entries mapped or 0 on error.
- */
-int pci_p2pdma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
-		int nents, enum dma_data_direction dir, unsigned long attrs)
+static int __pci_p2pdma_map_sg(struct pci_p2pdma_pagemap *p2p_pgmap,
+		struct device *dev, struct scatterlist *sg, int nents)
 {
-	struct pci_p2pdma_pagemap *p2p_pgmap;
 	struct scatterlist *s;
 	phys_addr_t paddr;
 	int i;
@@ -814,7 +800,6 @@ int pci_p2pdma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
 		return 0;
 
 	for_each_sg(sg, s, nents, i) {
-		p2p_pgmap = to_p2p_pgmap(sg_page(s)->pgmap);
 		paddr = sg_phys(s);
 
 		s->dma_address = paddr - p2p_pgmap->bus_offset;
@@ -823,6 +808,28 @@ int pci_p2pdma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
 
 	return nents;
 }
+
+/**
+ * pci_p2pdma_map_sg - map a PCI peer-to-peer scatterlist for DMA
+ * @dev: device doing the DMA request
+ * @sg: scatter list to map
+ * @nents: elements in the scatterlist
+ * @dir: DMA direction
+ * @attrs: dma attributes passed to dma_map_sg() (if called)
+ *
+ * Scatterlists mapped with this function should be unmapped using
+ * pci_p2pdma_unmap_sg_attrs().
+ *
+ * Returns the number of SG entries mapped or 0 on error.
+ */
+int pci_p2pdma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
+		int nents, enum dma_data_direction dir, unsigned long attrs)
+{
+	struct pci_p2pdma_pagemap *p2p_pgmap =
+		to_p2p_pgmap(sg_page(sg)->pgmap);
+
+	return __pci_p2pdma_map_sg(p2p_pgmap, dev, sg, nents);
+}
 EXPORT_SYMBOL_GPL(pci_p2pdma_map_sg_attrs);
 
 /**
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 11/14] PCI/P2PDMA: Store mapping method in an xarray
  2019-07-30 16:35 [PATCH v2 00/14] PCI/P2PDMA: Support transactions that hit the host bridge Logan Gunthorpe
                   ` (9 preceding siblings ...)
  2019-07-30 16:35 ` [PATCH v2 10/14] PCI/P2PDMA: Factor out __pci_p2pdma_map_sg() Logan Gunthorpe
@ 2019-07-30 16:35 ` Logan Gunthorpe
  2019-08-07  5:59   ` Christoph Hellwig
  2019-07-30 16:35 ` [PATCH v2 12/14] PCI/P2PDMA: dma_map P2PDMA map requests that traverse the host bridge Logan Gunthorpe
                   ` (3 subsequent siblings)
  14 siblings, 1 reply; 26+ messages in thread
From: Logan Gunthorpe @ 2019-07-30 16:35 UTC (permalink / raw)
  To: linux-kernel, linux-pci, linux-nvme, linux-rdma
  Cc: Bjorn Helgaas, Christoph Hellwig, Christian Koenig,
	Jason Gunthorpe, Sagi Grimberg, Keith Busch, Jens Axboe,
	Dan Williams, Eric Pilmore, Stephen Bates, Logan Gunthorpe

When upstream_bridge_distance() is called store the method required
to map the DMA transfers in an xarray so that it can be looked up
efficiently on the hot path in pci_p2pdma_map_sg().

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/pci/p2pdma.c | 40 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 35 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index fe647bd8f947..010aa8742bec 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -19,10 +19,19 @@
 #include <linux/random.h>
 #include <linux/seq_buf.h>
 #include <linux/iommu.h>
+#include <linux/xarray.h>
+
+enum pci_p2pdma_map_type {
+	PCI_P2PDMA_MAP_UNKNOWN = 0,
+	PCI_P2PDMA_MAP_NOT_SUPPORTED,
+	PCI_P2PDMA_MAP_BUS_ADDR,
+	PCI_P2PDMA_MAP_THRU_IOMMU,
+};
 
 struct pci_p2pdma {
 	struct gen_pool *pool;
 	bool p2pmem_published;
+	struct xarray map_types;
 };
 
 struct pci_p2pdma_pagemap {
@@ -98,6 +107,7 @@ static void pci_p2pdma_release(void *data)
 
 	gen_pool_destroy(p2pdma->pool);
 	sysfs_remove_group(&pdev->dev.kobj, &p2pmem_group);
+	xa_destroy(&p2pdma->map_types);
 }
 
 static int pci_p2pdma_setup(struct pci_dev *pdev)
@@ -109,6 +119,8 @@ static int pci_p2pdma_setup(struct pci_dev *pdev)
 	if (!p2p)
 		return -ENOMEM;
 
+	xa_init(&p2p->map_types);
+
 	p2p->pool = gen_pool_create(PAGE_SHIFT, dev_to_node(&pdev->dev));
 	if (!p2p->pool)
 		goto out;
@@ -404,6 +416,12 @@ static int __upstream_bridge_distance(struct pci_dev *provider,
 	return dist_a + dist_b;
 }
 
+static int map_types_idx(struct pci_dev *client)
+{
+	return (pci_domain_nr(client->bus) << 16) |
+		(client->bus->number << 8) | client->devfn;
+}
+
 /*
  * Find the distance through the nearest common upstream bridge between
  * two PCI devices.
@@ -446,17 +464,29 @@ static int upstream_bridge_distance(struct pci_dev *provider,
 				    struct pci_dev *client,
 				    struct seq_buf *acs_list)
 {
+	enum pci_p2pdma_map_type map_type;
 	int dist;
 
 	dist = __upstream_bridge_distance(provider, client, acs_list);
 
-	if (!(dist & P2PDMA_THRU_HOST_BRIDGE))
-		return dist;
+	if (!(dist & P2PDMA_THRU_HOST_BRIDGE)) {
+		map_type = PCI_P2PDMA_MAP_BUS_ADDR;
+		goto store_map_type_and_return;
+	}
+
+	if (host_bridge_whitelist(provider, client)) {
+		map_type = PCI_P2PDMA_MAP_THRU_IOMMU;
+	} else {
+		dist |= P2PDMA_NOT_SUPPORTED;
+		map_type = PCI_P2PDMA_MAP_NOT_SUPPORTED;
+	}
 
-	if (host_bridge_whitelist(provider, client))
-		return dist;
+store_map_type_and_return:
+	if (provider->p2pdma)
+		xa_store(&provider->p2pdma->map_types, map_types_idx(client),
+			 xa_mk_value(map_type), GFP_KERNEL);
 
-	return dist | P2PDMA_NOT_SUPPORTED;
+	return dist;
 }
 
 static int upstream_bridge_distance_warn(struct pci_dev *provider,
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 12/14] PCI/P2PDMA: dma_map P2PDMA map requests that traverse the host bridge
  2019-07-30 16:35 [PATCH v2 00/14] PCI/P2PDMA: Support transactions that hit the host bridge Logan Gunthorpe
                   ` (10 preceding siblings ...)
  2019-07-30 16:35 ` [PATCH v2 11/14] PCI/P2PDMA: Store mapping method in an xarray Logan Gunthorpe
@ 2019-07-30 16:35 ` Logan Gunthorpe
  2019-07-30 16:35 ` [PATCH v2 13/14] PCI/P2PDMA: No longer require no-mmu for host bridge whitelist Logan Gunthorpe
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Logan Gunthorpe @ 2019-07-30 16:35 UTC (permalink / raw)
  To: linux-kernel, linux-pci, linux-nvme, linux-rdma
  Cc: Bjorn Helgaas, Christoph Hellwig, Christian Koenig,
	Jason Gunthorpe, Sagi Grimberg, Keith Busch, Jens Axboe,
	Dan Williams, Eric Pilmore, Stephen Bates, Logan Gunthorpe

Any requests that traverse the host bridge will need to be mapped into
the IOMMU, so call dma_map_sg() inside pci_p2pdma_map_sg() when
appropriate.

Similarly, call dma_unmap_sg() inside pci_p2pdma_unmap_sg().

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/pci/p2pdma.c | 40 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index 010aa8742bec..b86a1c0c11a0 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -812,6 +812,16 @@ void pci_p2pmem_publish(struct pci_dev *pdev, bool publish)
 }
 EXPORT_SYMBOL_GPL(pci_p2pmem_publish);
 
+static enum pci_p2pdma_map_type pci_p2pdma_map_type(struct pci_dev *provider,
+						    struct pci_dev *client)
+{
+	if (!provider->p2pdma)
+		return PCI_P2PDMA_MAP_NOT_SUPPORTED;
+
+	return xa_to_value(xa_load(&provider->p2pdma->map_types,
+				   map_types_idx(client)));
+}
+
 static int __pci_p2pdma_map_sg(struct pci_p2pdma_pagemap *p2p_pgmap,
 		struct device *dev, struct scatterlist *sg, int nents)
 {
@@ -857,8 +867,22 @@ int pci_p2pdma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
 {
 	struct pci_p2pdma_pagemap *p2p_pgmap =
 		to_p2p_pgmap(sg_page(sg)->pgmap);
+	struct pci_dev *client;
 
-	return __pci_p2pdma_map_sg(p2p_pgmap, dev, sg, nents);
+	if (WARN_ON_ONCE(!dev_is_pci(dev)))
+		return 0;
+
+	client = to_pci_dev(dev);
+
+	switch (pci_p2pdma_map_type(p2p_pgmap->provider, client)) {
+	case PCI_P2PDMA_MAP_THRU_IOMMU:
+		return dma_map_sg_attrs(dev, sg, nents, dir, attrs);
+	case PCI_P2PDMA_MAP_BUS_ADDR:
+		return __pci_p2pdma_map_sg(p2p_pgmap, dev, sg, nents);
+	default:
+		WARN_ON_ONCE(1);
+		return 0;
+	}
 }
 EXPORT_SYMBOL_GPL(pci_p2pdma_map_sg_attrs);
 
@@ -874,6 +898,20 @@ EXPORT_SYMBOL_GPL(pci_p2pdma_map_sg_attrs);
 void pci_p2pdma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg,
 		int nents, enum dma_data_direction dir, unsigned long attrs)
 {
+	struct pci_p2pdma_pagemap *p2p_pgmap =
+		to_p2p_pgmap(sg_page(sg)->pgmap);
+	enum pci_p2pdma_map_type map_type;
+	struct pci_dev *client;
+
+	if (WARN_ON_ONCE(!dev_is_pci(dev)))
+		return;
+
+	client = to_pci_dev(dev);
+
+	map_type = pci_p2pdma_map_type(p2p_pgmap->provider, client);
+
+	if (map_type == PCI_P2PDMA_MAP_THRU_IOMMU)
+		dma_unmap_sg_attrs(dev, sg, nents, dir, attrs);
 }
 EXPORT_SYMBOL_GPL(pci_p2pdma_unmap_sg_attrs);
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 13/14] PCI/P2PDMA: No longer require no-mmu for host bridge whitelist
  2019-07-30 16:35 [PATCH v2 00/14] PCI/P2PDMA: Support transactions that hit the host bridge Logan Gunthorpe
                   ` (11 preceding siblings ...)
  2019-07-30 16:35 ` [PATCH v2 12/14] PCI/P2PDMA: dma_map P2PDMA map requests that traverse the host bridge Logan Gunthorpe
@ 2019-07-30 16:35 ` Logan Gunthorpe
  2019-08-07  5:59   ` Christoph Hellwig
  2019-07-30 16:35 ` [PATCH v2 14/14] PCI/P2PDMA: Update documentation for pci_p2pdma_distance_many() Logan Gunthorpe
  2019-08-06 23:44 ` [PATCH v2 00/14] PCI/P2PDMA: Support transactions that hit the host bridge Bjorn Helgaas
  14 siblings, 1 reply; 26+ messages in thread
From: Logan Gunthorpe @ 2019-07-30 16:35 UTC (permalink / raw)
  To: linux-kernel, linux-pci, linux-nvme, linux-rdma
  Cc: Bjorn Helgaas, Christoph Hellwig, Christian Koenig,
	Jason Gunthorpe, Sagi Grimberg, Keith Busch, Jens Axboe,
	Dan Williams, Eric Pilmore, Stephen Bates, Logan Gunthorpe

Now that we map the requests correctly we can remove the iommu_present()
restriction.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/pci/p2pdma.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index b86a1c0c11a0..2d643b26d080 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -18,7 +18,6 @@
 #include <linux/percpu-refcount.h>
 #include <linux/random.h>
 #include <linux/seq_buf.h>
-#include <linux/iommu.h>
 #include <linux/xarray.h>
 
 enum pci_p2pdma_map_type {
@@ -328,9 +327,6 @@ static bool host_bridge_whitelist(struct pci_dev *a, struct pci_dev *b)
 	struct pci_host_bridge *host_a = pci_find_host_bridge(a->bus);
 	struct pci_host_bridge *host_b = pci_find_host_bridge(b->bus);
 
-	if (iommu_present(a->dev.bus) || iommu_present(b->dev.bus))
-		return false;
-
 	if (host_a == host_b)
 		return __host_bridge_whitelist(host_a, true);
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 14/14] PCI/P2PDMA: Update documentation for pci_p2pdma_distance_many()
  2019-07-30 16:35 [PATCH v2 00/14] PCI/P2PDMA: Support transactions that hit the host bridge Logan Gunthorpe
                   ` (12 preceding siblings ...)
  2019-07-30 16:35 ` [PATCH v2 13/14] PCI/P2PDMA: No longer require no-mmu for host bridge whitelist Logan Gunthorpe
@ 2019-07-30 16:35 ` Logan Gunthorpe
  2019-08-06 23:44 ` [PATCH v2 00/14] PCI/P2PDMA: Support transactions that hit the host bridge Bjorn Helgaas
  14 siblings, 0 replies; 26+ messages in thread
From: Logan Gunthorpe @ 2019-07-30 16:35 UTC (permalink / raw)
  To: linux-kernel, linux-pci, linux-nvme, linux-rdma
  Cc: Bjorn Helgaas, Christoph Hellwig, Christian Koenig,
	Jason Gunthorpe, Sagi Grimberg, Keith Busch, Jens Axboe,
	Dan Williams, Eric Pilmore, Stephen Bates, Logan Gunthorpe

The comment describing pci_p2pdma_distance_many() still referred to
the devices being behind the same root port. This no longer applies
so reword the documentation.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/pci/p2pdma.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index 2d643b26d080..ac6b599a10ef 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -523,15 +523,14 @@ static int upstream_bridge_distance_warn(struct pci_dev *provider,
  * @num_clients: number of clients in the array
  * @verbose: if true, print warnings for devices when we return -1
  *
- * Returns -1 if any of the clients are not compatible (behind the same
- * root port as the provider), otherwise returns a positive number where
- * a lower number is the preferable choice. (If there's one client
- * that's the same as the provider it will return 0, which is best choice).
+ * Returns -1 if any of the clients are not compatible, otherwise returns a
+ * positive number where a lower number is the preferable choice. (If there's
+ * one client that's the same as the provider it will return 0, which is best
+ * choice).
  *
- * For now, "compatible" means the provider and the clients are all behind
- * the same PCI root port. This cuts out cases that may work but is safest
- * for the user. Future work can expand this to white-list root complexes that
- * can safely forward between each ports.
+ * "compatible" means the provider and the clients are either all behind
+ * the same PCI root port or the host bridge connected to each of the devices
+ * are is listed in the 'pci_p2pdma_whitelist'.
  */
 int pci_p2pdma_distance_many(struct pci_dev *provider, struct device **clients,
 			     int num_clients, bool verbose)
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 00/14] PCI/P2PDMA: Support transactions that hit the host bridge
  2019-07-30 16:35 [PATCH v2 00/14] PCI/P2PDMA: Support transactions that hit the host bridge Logan Gunthorpe
                   ` (13 preceding siblings ...)
  2019-07-30 16:35 ` [PATCH v2 14/14] PCI/P2PDMA: Update documentation for pci_p2pdma_distance_many() Logan Gunthorpe
@ 2019-08-06 23:44 ` Bjorn Helgaas
  2019-08-07  0:31   ` Logan Gunthorpe
  14 siblings, 1 reply; 26+ messages in thread
From: Bjorn Helgaas @ 2019-08-06 23:44 UTC (permalink / raw)
  To: Logan Gunthorpe
  Cc: linux-kernel, linux-pci, linux-nvme, linux-rdma, Sagi Grimberg,
	Christian Koenig, Jens Axboe, Keith Busch, Jason Gunthorpe,
	Stephen Bates, Dan Williams, Eric Pilmore, Christoph Hellwig

On Tue, Jul 30, 2019 at 10:35:31AM -0600, Logan Gunthorpe wrote:
> Here's v2 of the patchset. It doesn't sound like there's anything
> terribly controversial here so this version is mostly just some
> cleanup changes for clarity.
> 
> Changes in v2:
>  * Rebase on v5.3-rc2 (No changes)
>  * Re-introduce the private pagemap structure and move the p2p-specific
>    elements out of the commond dev_pagemap (per Christoph)
>  * Use flags instead of bool in the whitelist (per Jason)
>  * Only store the mapping type in the xarray (instead of the distance
>    with flags) such that a function can return the mapping method
>    with a switch statement to decide how to map. (per Christoph)
>  * Drop find_parent_pci_dev() on the fast path and rely on the fact
>    that the struct device passed to the mapping functions *must* be
>    a PCI device and convert it directly. (per suggestions from
>    Christoph and Jason)
>  * Collected Christian's Reviewed-by's
> --
> 
> As discussed on the list previously, in order to fully support the
> whitelist Christian added with the IOMMU, we must ensure that we
> map any buffer going through the IOMMU with an aprropriate dma_map
> call. This patchset accomplishes this by cleaning up the output of
> upstream_bridge_distance() to better indicate the mapping requirements,
> caching these requirements in an xarray, then looking them up at map
> time and applying the appropriate mapping method.
> 
> After this patchset, it's possible to use the NVMe-of P2P support to
> transfer between devices without a switch on the whitelisted root
> complexes. A couple Intel device I have tested this on have also
> been added to the white list.
> 
> Most of the changes are contained within the p2pdma.c, but there are
> a few minor touches to other subsystems, mostly to add support
> to call an unmap function.
> 
> The final patch in this series demonstrates a possible
> pci_p2pdma_map_resource() function that I expect Christian will need
> but does not have any users at this time so I don't intend for it to be
> considered for merging.

I don't see pci_p2pdma_map_resource() in any of these patches.

I tentatively applied these to pci/p2pdma with minor typographical
updates (below), but I'll update the branch if necessary.

> This patchset is based on 5.3-rc2 and a git branch is available here:
> 
> https://github.com/sbates130272/linux-p2pmem/ p2pdma_rc_map_v2
> 
> --
> 
> Logan Gunthorpe (14):
>   PCI/P2PDMA: Introduce private pagemap structure
>   PCI/P2PDMA: Add the provider's pci_dev to the pci_p2pdma_pagemap
>     struct
>   PCI/P2PDMA: Add constants for not-supported result
>     upstream_bridge_distance()
>   PCI/P2PDMA: Factor out __upstream_bridge_distance()
>   PCI/P2PDMA: Apply host bridge white list for ACS
>   PCI/P2PDMA: Factor out host_bridge_whitelist()
>   PCI/P2PDMA: Add whitelist support for Intel Host Bridges
>   PCI/P2PDMA: Add attrs argument to pci_p2pdma_map_sg()
>   PCI/P2PDMA: Introduce pci_p2pdma_unmap_sg()
>   PCI/P2PDMA: Factor out __pci_p2pdma_map_sg()
>   PCI/P2PDMA: Store mapping method in an xarray
>   PCI/P2PDMA: dma_map P2PDMA map requests that traverse the host bridge
>   PCI/P2PDMA: No longer require no-mmu for host bridge whitelist
>   PCI/P2PDMA: Update documentation for pci_p2pdma_distance_many()
> 
>  drivers/infiniband/core/rw.c |   6 +-
>  drivers/nvme/host/pci.c      |  10 +-
>  drivers/pci/p2pdma.c         | 361 +++++++++++++++++++++++++----------
>  include/linux/memremap.h     |   1 -
>  include/linux/pci-p2pdma.h   |  28 ++-
>  5 files changed, 296 insertions(+), 110 deletions(-)

diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index ac6b599a10ef..afa42512e604 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -442,17 +442,17 @@ static int map_types_idx(struct pci_dev *client)
  * port of the switch, to the common upstream port, back up to the second
  * downstream port and then to Device B.
  *
- * Any two devices that cannot communicate using p2pdma will return the distance
- * with the flag P2PDMA_NOT_SUPPORTED.
+ * Any two devices that cannot communicate using p2pdma will return the
+ * distance with the flag P2PDMA_NOT_SUPPORTED.
  *
  * Any two devices that have a data path that goes through the host bridge
  * will consult a whitelist. If the host bridges are on the whitelist,
- * then the distance will be returned with the flag P2PDMA_THRU_HOST_BRIDGE set.
+ * the distance will be returned with the flag P2PDMA_THRU_HOST_BRIDGE set.
  * If either bridge is not on the whitelist, the flag P2PDMA_NOT_SUPPORTED will
  * be set.
  *
  * If a bridge which has any ACS redirection bits set is in the path
- * then this functions will flag the result with P2PDMA_ACS_FORCES_UPSTREAM.
+ * this function will flag the result with P2PDMA_ACS_FORCES_UPSTREAM.
  * In this case, a list of all infringing bridge addresses will be
  * populated in acs_list (assuming it's non-null) for printk purposes.
  */
@@ -529,8 +529,8 @@ static int upstream_bridge_distance_warn(struct pci_dev *provider,
  * choice).
  *
  * "compatible" means the provider and the clients are either all behind
- * the same PCI root port or the host bridge connected to each of the devices
- * are is listed in the 'pci_p2pdma_whitelist'.
+ * the same PCI root port or the host bridges connected to each of the devices
+ * are listed in the 'pci_p2pdma_whitelist'.
  */
 int pci_p2pdma_distance_many(struct pci_dev *provider, struct device **clients,
 			     int num_clients, bool verbose)
@@ -850,7 +850,7 @@ static int __pci_p2pdma_map_sg(struct pci_p2pdma_pagemap *p2p_pgmap,
  * @sg: scatter list to map
  * @nents: elements in the scatterlist
  * @dir: DMA direction
- * @attrs: dma attributes passed to dma_map_sg() (if called)
+ * @attrs: DMA attributes passed to dma_map_sg() (if called)
  *
  * Scatterlists mapped with this function should be unmapped using
  * pci_p2pdma_unmap_sg_attrs().
@@ -888,7 +888,7 @@ EXPORT_SYMBOL_GPL(pci_p2pdma_map_sg_attrs);
  * @sg: scatter list to map
  * @nents: number of elements returned by pci_p2pdma_map_sg()
  * @dir: DMA direction
- * @attrs: dma attributes passed to dma_unmap_sg() (if called)
+ * @attrs: DMA attributes passed to dma_unmap_sg() (if called)
  */
 void pci_p2pdma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg,
 		int nents, enum dma_data_direction dir, unsigned long attrs)

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 00/14] PCI/P2PDMA: Support transactions that hit the host bridge
  2019-08-06 23:44 ` [PATCH v2 00/14] PCI/P2PDMA: Support transactions that hit the host bridge Bjorn Helgaas
@ 2019-08-07  0:31   ` Logan Gunthorpe
  2019-08-07 19:29     ` Bjorn Helgaas
  0 siblings, 1 reply; 26+ messages in thread
From: Logan Gunthorpe @ 2019-08-07  0:31 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: linux-kernel, linux-pci, linux-nvme, linux-rdma, Sagi Grimberg,
	Christian Koenig, Jens Axboe, Keith Busch, Jason Gunthorpe,
	Stephen Bates, Dan Williams, Eric Pilmore, Christoph Hellwig



On 2019-08-06 5:44 p.m., Bjorn Helgaas wrote:
> On Tue, Jul 30, 2019 at 10:35:31AM -0600, Logan Gunthorpe wrote:
>> Here's v2 of the patchset. It doesn't sound like there's anything
>> terribly controversial here so this version is mostly just some
>> cleanup changes for clarity.
>>
>> Changes in v2:
>>  * Rebase on v5.3-rc2 (No changes)
>>  * Re-introduce the private pagemap structure and move the p2p-specific
>>    elements out of the commond dev_pagemap (per Christoph)
>>  * Use flags instead of bool in the whitelist (per Jason)
>>  * Only store the mapping type in the xarray (instead of the distance
>>    with flags) such that a function can return the mapping method
>>    with a switch statement to decide how to map. (per Christoph)
>>  * Drop find_parent_pci_dev() on the fast path and rely on the fact
>>    that the struct device passed to the mapping functions *must* be
>>    a PCI device and convert it directly. (per suggestions from
>>    Christoph and Jason)
>>  * Collected Christian's Reviewed-by's
>> --
>>
>> As discussed on the list previously, in order to fully support the
>> whitelist Christian added with the IOMMU, we must ensure that we
>> map any buffer going through the IOMMU with an aprropriate dma_map
>> call. This patchset accomplishes this by cleaning up the output of
>> upstream_bridge_distance() to better indicate the mapping requirements,
>> caching these requirements in an xarray, then looking them up at map
>> time and applying the appropriate mapping method.
>>
>> After this patchset, it's possible to use the NVMe-of P2P support to
>> transfer between devices without a switch on the whitelisted root
>> complexes. A couple Intel device I have tested this on have also
>> been added to the white list.
>>
>> Most of the changes are contained within the p2pdma.c, but there are
>> a few minor touches to other subsystems, mostly to add support
>> to call an unmap function.
>>
>> The final patch in this series demonstrates a possible
>> pci_p2pdma_map_resource() function that I expect Christian will need
>> but does not have any users at this time so I don't intend for it to be
>> considered for merging.
> 
> I don't see pci_p2pdma_map_resource() in any of these patches.

Oh, sorry, I removed that in v2 seeing there was some confusion over it.
I guess I forgot to remove the reference in the cover letter.

> I tentatively applied these to pci/p2pdma with minor typographical
> updates (below), but I'll update the branch if necessary.

Great, thanks! The typographical changes look good.

I already have one very minor change queued up for these. Should I just
send you a small patch against your branch for you to squash?

Logan


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 03/14] PCI/P2PDMA: Add constants for not-supported result upstream_bridge_distance()
  2019-07-30 16:35 ` [PATCH v2 03/14] PCI/P2PDMA: Add constants for not-supported result upstream_bridge_distance() Logan Gunthorpe
@ 2019-08-07  5:54   ` Christoph Hellwig
  2019-08-07 15:58     ` Logan Gunthorpe
  0 siblings, 1 reply; 26+ messages in thread
From: Christoph Hellwig @ 2019-08-07  5:54 UTC (permalink / raw)
  To: Logan Gunthorpe
  Cc: linux-kernel, linux-pci, linux-nvme, linux-rdma, Bjorn Helgaas,
	Christoph Hellwig, Christian Koenig, Jason Gunthorpe,
	Sagi Grimberg, Keith Busch, Jens Axboe, Dan Williams,
	Eric Pilmore, Stephen Bates

On Tue, Jul 30, 2019 at 10:35:34AM -0600, Logan Gunthorpe wrote:
> Add constant flags to indicate two devices are not supported or whether
> the data path goes through the host bridge instead of using the negative
> values -1 and -2.
> 
> This helps annotate the code better, but the main reason is so we
> can use the information to store the required mapping method in an
> xarray.
> 
> Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
> Reviewed-by: Christian König <christian.koenig@amd.com>

Is there really no way to keep the distance separate from the type of
the connection as I requested?  I think that would avoid a lot of
confusion down the road.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 11/14] PCI/P2PDMA: Store mapping method in an xarray
  2019-07-30 16:35 ` [PATCH v2 11/14] PCI/P2PDMA: Store mapping method in an xarray Logan Gunthorpe
@ 2019-08-07  5:59   ` Christoph Hellwig
  0 siblings, 0 replies; 26+ messages in thread
From: Christoph Hellwig @ 2019-08-07  5:59 UTC (permalink / raw)
  To: Logan Gunthorpe
  Cc: linux-kernel, linux-pci, linux-nvme, linux-rdma, Bjorn Helgaas,
	Christoph Hellwig, Christian Koenig, Jason Gunthorpe,
	Sagi Grimberg, Keith Busch, Jens Axboe, Dan Williams,
	Eric Pilmore, Stephen Bates

On Tue, Jul 30, 2019 at 10:35:42AM -0600, Logan Gunthorpe wrote:
> When upstream_bridge_distance() is called store the method required
> to map the DMA transfers in an xarray so that it can be looked up
> efficiently on the hot path in pci_p2pdma_map_sg().
> 
> Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
> ---
>  drivers/pci/p2pdma.c | 40 +++++++++++++++++++++++++++++++++++-----
>  1 file changed, 35 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
> index fe647bd8f947..010aa8742bec 100644
> --- a/drivers/pci/p2pdma.c
> +++ b/drivers/pci/p2pdma.c
> @@ -19,10 +19,19 @@
>  #include <linux/random.h>
>  #include <linux/seq_buf.h>
>  #include <linux/iommu.h>
> +#include <linux/xarray.h>
> +
> +enum pci_p2pdma_map_type {
> +	PCI_P2PDMA_MAP_UNKNOWN = 0,
> +	PCI_P2PDMA_MAP_NOT_SUPPORTED,
> +	PCI_P2PDMA_MAP_BUS_ADDR,
> +	PCI_P2PDMA_MAP_THRU_IOMMU,
> +};

So here we add a new enum for the map type, but for the internal code
the previousloading of the distance is kept, which seems a little
strange.

> +	if (!(dist & P2PDMA_THRU_HOST_BRIDGE)) {
> +		map_type = PCI_P2PDMA_MAP_BUS_ADDR;
> +		goto store_map_type_and_return;
> +	}
> +
> +	if (host_bridge_whitelist(provider, client)) {
> +		map_type = PCI_P2PDMA_MAP_THRU_IOMMU;
> +	} else {
> +		dist |= P2PDMA_NOT_SUPPORTED;
> +		map_type = PCI_P2PDMA_MAP_NOT_SUPPORTED;
> +	}
>  
> +store_map_type_and_return:

Why not:

	if (dist & P2PDMA_THRU_HOST_BRIDGE) {
		if (host_bridge_whitelist(provider, client)) {
			map_type = PCI_P2PDMA_MAP_THRU_IOMMU;
		} else {
			dist |= P2PDMA_NOT_SUPPORTED;
			map_type = PCI_P2PDMA_MAP_NOT_SUPPORTED;
		}
	}

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 13/14] PCI/P2PDMA: No longer require no-mmu for host bridge whitelist
  2019-07-30 16:35 ` [PATCH v2 13/14] PCI/P2PDMA: No longer require no-mmu for host bridge whitelist Logan Gunthorpe
@ 2019-08-07  5:59   ` Christoph Hellwig
  2019-08-07 12:43     ` Bjorn Helgaas
  0 siblings, 1 reply; 26+ messages in thread
From: Christoph Hellwig @ 2019-08-07  5:59 UTC (permalink / raw)
  To: Logan Gunthorpe
  Cc: linux-kernel, linux-pci, linux-nvme, linux-rdma, Bjorn Helgaas,
	Christoph Hellwig, Christian Koenig, Jason Gunthorpe,
	Sagi Grimberg, Keith Busch, Jens Axboe, Dan Williams,
	Eric Pilmore, Stephen Bates

no-mmu sounds stange, as we use that for linux ports without paging
hardware.  I think an "io" got lost somewhere..

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 13/14] PCI/P2PDMA: No longer require no-mmu for host bridge whitelist
  2019-08-07  5:59   ` Christoph Hellwig
@ 2019-08-07 12:43     ` Bjorn Helgaas
  2019-08-08  7:29       ` Christoph Hellwig
  0 siblings, 1 reply; 26+ messages in thread
From: Bjorn Helgaas @ 2019-08-07 12:43 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Logan Gunthorpe, Sagi Grimberg, linux-rdma, linux-pci,
	linux-kernel, linux-nvme, Christian Koenig, Jens Axboe,
	Keith Busch, Jason Gunthorpe, Stephen Bates, Dan Williams,
	Eric Pilmore

On Wed, Aug 07, 2019 at 07:59:58AM +0200, Christoph Hellwig wrote:
> no-mmu sounds stange, as we use that for linux ports without paging
> hardware.  I think an "io" got lost somewhere..

I had already changed the subject to

  PCI/P2PDMA: Allow IOMMU for host bridge whitelist

but certainly open to better suggestions.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 03/14] PCI/P2PDMA: Add constants for not-supported result upstream_bridge_distance()
  2019-08-07  5:54   ` Christoph Hellwig
@ 2019-08-07 15:58     ` Logan Gunthorpe
  2019-08-08  7:31       ` Christoph Hellwig
  0 siblings, 1 reply; 26+ messages in thread
From: Logan Gunthorpe @ 2019-08-07 15:58 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-kernel, linux-pci, linux-nvme, linux-rdma, Bjorn Helgaas,
	Christian Koenig, Jason Gunthorpe, Sagi Grimberg, Keith Busch,
	Jens Axboe, Dan Williams, Eric Pilmore, Stephen Bates



On 2019-08-06 11:54 p.m., Christoph Hellwig wrote:
> On Tue, Jul 30, 2019 at 10:35:34AM -0600, Logan Gunthorpe wrote:
>> Add constant flags to indicate two devices are not supported or whether
>> the data path goes through the host bridge instead of using the negative
>> values -1 and -2.
>>
>> This helps annotate the code better, but the main reason is so we
>> can use the information to store the required mapping method in an
>> xarray.
>>
>> Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
>> Reviewed-by: Christian König <christian.koenig@amd.com>
> 
> Is there really no way to keep the distance separate from the type of
> the connection as I requested?  I think that would avoid a lot of
> confusion down the road.

Well I separated it in the xarray and the interface. It only stores the
type of mapping, not the distance and uses pci_p2pdma_map_type() to
retrieve it.

We only calculate it at the same time as we calculate the distance. This
is necessary because, to calculate the type, we have to walk the tree
and check the ACS bits. If we separated it, we'd have to walk the tree
twice in a very similar way just to determine both the distance and the
mapping type.

I'll apply your other feedback to a v3 next week.

Logan

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 00/14] PCI/P2PDMA: Support transactions that hit the host bridge
  2019-08-07  0:31   ` Logan Gunthorpe
@ 2019-08-07 19:29     ` Bjorn Helgaas
  0 siblings, 0 replies; 26+ messages in thread
From: Bjorn Helgaas @ 2019-08-07 19:29 UTC (permalink / raw)
  To: Logan Gunthorpe
  Cc: linux-kernel, linux-pci, linux-nvme, linux-rdma, Sagi Grimberg,
	Christian Koenig, Jens Axboe, Keith Busch, Jason Gunthorpe,
	Stephen Bates, Dan Williams, Eric Pilmore, Christoph Hellwig

On Tue, Aug 06, 2019 at 06:31:07PM -0600, Logan Gunthorpe wrote:
> On 2019-08-06 5:44 p.m., Bjorn Helgaas wrote:

> > I tentatively applied these to pci/p2pdma with minor typographical
> > updates (below), but I'll update the branch if necessary.
> 
> Great, thanks! The typographical changes look good.
> 
> I already have one very minor change queued up for these. Should I just
> send you a small patch against your branch for you to squash?

Yes, an incremental patch against my branch would be nice.

Bjorn

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 13/14] PCI/P2PDMA: No longer require no-mmu for host bridge whitelist
  2019-08-07 12:43     ` Bjorn Helgaas
@ 2019-08-08  7:29       ` Christoph Hellwig
  0 siblings, 0 replies; 26+ messages in thread
From: Christoph Hellwig @ 2019-08-08  7:29 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Christoph Hellwig, Logan Gunthorpe, Sagi Grimberg, linux-rdma,
	linux-pci, linux-kernel, linux-nvme, Christian Koenig,
	Jens Axboe, Keith Busch, Jason Gunthorpe, Stephen Bates,
	Dan Williams, Eric Pilmore

On Wed, Aug 07, 2019 at 07:43:01AM -0500, Bjorn Helgaas wrote:
> On Wed, Aug 07, 2019 at 07:59:58AM +0200, Christoph Hellwig wrote:
> > no-mmu sounds stange, as we use that for linux ports without paging
> > hardware.  I think an "io" got lost somewhere..
> 
> I had already changed the subject to
> 
>   PCI/P2PDMA: Allow IOMMU for host bridge whitelist
> 
> but certainly open to better suggestions.

Maybe:

PCI/P2PDMA: Allow P2P transfers behind IOMMUs

?

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 03/14] PCI/P2PDMA: Add constants for not-supported result upstream_bridge_distance()
  2019-08-07 15:58     ` Logan Gunthorpe
@ 2019-08-08  7:31       ` Christoph Hellwig
  2019-08-08 15:58         ` Logan Gunthorpe
  0 siblings, 1 reply; 26+ messages in thread
From: Christoph Hellwig @ 2019-08-08  7:31 UTC (permalink / raw)
  To: Logan Gunthorpe
  Cc: Christoph Hellwig, linux-kernel, linux-pci, linux-nvme,
	linux-rdma, Bjorn Helgaas, Christian Koenig, Jason Gunthorpe,
	Sagi Grimberg, Keith Busch, Jens Axboe, Dan Williams,
	Eric Pilmore, Stephen Bates

On Wed, Aug 07, 2019 at 09:58:06AM -0600, Logan Gunthorpe wrote:
> We only calculate it at the same time as we calculate the distance. This
> is necessary because, to calculate the type, we have to walk the tree
> and check the ACS bits. If we separated it, we'd have to walk the tree
> twice in a very similar way just to determine both the distance and the
> mapping type.

Calculating it together makes perfect sense.  What I find odd is the
overloading of a single return value.  Why not return the map type as
the return value, and the distance as a by reference argument to keep
them properly separated?

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 03/14] PCI/P2PDMA: Add constants for not-supported result upstream_bridge_distance()
  2019-08-08  7:31       ` Christoph Hellwig
@ 2019-08-08 15:58         ` Logan Gunthorpe
  0 siblings, 0 replies; 26+ messages in thread
From: Logan Gunthorpe @ 2019-08-08 15:58 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-kernel, linux-pci, linux-nvme, linux-rdma, Bjorn Helgaas,
	Christian Koenig, Jason Gunthorpe, Sagi Grimberg, Keith Busch,
	Jens Axboe, Dan Williams, Eric Pilmore, Stephen Bates



On 2019-08-08 1:31 a.m., Christoph Hellwig wrote:
> On Wed, Aug 07, 2019 at 09:58:06AM -0600, Logan Gunthorpe wrote:
>> We only calculate it at the same time as we calculate the distance. This
>> is necessary because, to calculate the type, we have to walk the tree
>> and check the ACS bits. If we separated it, we'd have to walk the tree
>> twice in a very similar way just to determine both the distance and the
>> mapping type.
> 
> Calculating it together makes perfect sense.  What I find odd is the
> overloading of a single return value.  Why not return the map type as
> the return value, and the distance as a by reference argument to keep
> them properly separated?

Ok, understood. I'll make that change and send some incremental patches
to Bjorn tomorrow.

Logan

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2019-08-08 15:59 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-30 16:35 [PATCH v2 00/14] PCI/P2PDMA: Support transactions that hit the host bridge Logan Gunthorpe
2019-07-30 16:35 ` [PATCH v2 01/14] PCI/P2PDMA: Introduce private pagemap structure Logan Gunthorpe
2019-07-30 16:35 ` [PATCH v2 02/14] PCI/P2PDMA: Add the provider's pci_dev to the pci_p2pdma_pagemap struct Logan Gunthorpe
2019-07-30 16:35 ` [PATCH v2 03/14] PCI/P2PDMA: Add constants for not-supported result upstream_bridge_distance() Logan Gunthorpe
2019-08-07  5:54   ` Christoph Hellwig
2019-08-07 15:58     ` Logan Gunthorpe
2019-08-08  7:31       ` Christoph Hellwig
2019-08-08 15:58         ` Logan Gunthorpe
2019-07-30 16:35 ` [PATCH v2 04/14] PCI/P2PDMA: Factor out __upstream_bridge_distance() Logan Gunthorpe
2019-07-30 16:35 ` [PATCH v2 05/14] PCI/P2PDMA: Apply host bridge white list for ACS Logan Gunthorpe
2019-07-30 16:35 ` [PATCH v2 06/14] PCI/P2PDMA: Factor out host_bridge_whitelist() Logan Gunthorpe
2019-07-30 16:35 ` [PATCH v2 07/14] PCI/P2PDMA: Add whitelist support for Intel Host Bridges Logan Gunthorpe
2019-07-30 16:35 ` [PATCH v2 08/14] PCI/P2PDMA: Add attrs argument to pci_p2pdma_map_sg() Logan Gunthorpe
2019-07-30 16:35 ` [PATCH v2 09/14] PCI/P2PDMA: Introduce pci_p2pdma_unmap_sg() Logan Gunthorpe
2019-07-30 16:35 ` [PATCH v2 10/14] PCI/P2PDMA: Factor out __pci_p2pdma_map_sg() Logan Gunthorpe
2019-07-30 16:35 ` [PATCH v2 11/14] PCI/P2PDMA: Store mapping method in an xarray Logan Gunthorpe
2019-08-07  5:59   ` Christoph Hellwig
2019-07-30 16:35 ` [PATCH v2 12/14] PCI/P2PDMA: dma_map P2PDMA map requests that traverse the host bridge Logan Gunthorpe
2019-07-30 16:35 ` [PATCH v2 13/14] PCI/P2PDMA: No longer require no-mmu for host bridge whitelist Logan Gunthorpe
2019-08-07  5:59   ` Christoph Hellwig
2019-08-07 12:43     ` Bjorn Helgaas
2019-08-08  7:29       ` Christoph Hellwig
2019-07-30 16:35 ` [PATCH v2 14/14] PCI/P2PDMA: Update documentation for pci_p2pdma_distance_many() Logan Gunthorpe
2019-08-06 23:44 ` [PATCH v2 00/14] PCI/P2PDMA: Support transactions that hit the host bridge Bjorn Helgaas
2019-08-07  0:31   ` Logan Gunthorpe
2019-08-07 19:29     ` Bjorn Helgaas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).