diff mbox series

[06/14] PCI/P2PDMA: Add whitelist support for Intel Host Bridges

Message ID 20190722230859.5436-7-logang@deltatee.com
State Superseded
Delegated to: Bjorn Helgaas
Headers show
Series PCI/P2PDMA: Support transactions that hit the host bridge | expand

Commit Message

Logan Gunthorpe July 22, 2019, 11:08 p.m. UTC
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 | 36 ++++++++++++++++++++++++++++++++----
 1 file changed, 32 insertions(+), 4 deletions(-)

Comments

Jason Gunthorpe July 25, 2019, 6:52 p.m. UTC | #1
On Mon, Jul 22, 2019 at 05:08:51PM -0600, Logan Gunthorpe wrote:
> 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 | 36 ++++++++++++++++++++++++++++++++----
>  1 file changed, 32 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
> index dfb802afc8ca..143e11d2a5c3 100644
> +++ b/drivers/pci/p2pdma.c
> @@ -250,9 +250,28 @@ 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;
> +	bool req_same_host_bridge;

This would be more readable in the initializer as a flags not a bool

Jason
Logan Gunthorpe July 25, 2019, 7:14 p.m. UTC | #2
On 2019-07-25 12:52 p.m., Jason Gunthorpe wrote:
> On Mon, Jul 22, 2019 at 05:08:51PM -0600, Logan Gunthorpe wrote:
>> 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 | 36 ++++++++++++++++++++++++++++++++----
>>  1 file changed, 32 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
>> index dfb802afc8ca..143e11d2a5c3 100644
>> +++ b/drivers/pci/p2pdma.c
>> @@ -250,9 +250,28 @@ 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;
>> +	bool req_same_host_bridge;
> 
> This would be more readable in the initializer as a flags not a bool

Ok, will change for v2.

Logan
diff mbox series

Patch

diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c
index dfb802afc8ca..143e11d2a5c3 100644
--- a/drivers/pci/p2pdma.c
+++ b/drivers/pci/p2pdma.c
@@ -250,9 +250,28 @@  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;
+	bool req_same_host_bridge;
+} pci_p2pdma_whitelist[] = {
+	/* AMD ZEN */
+	{PCI_VENDOR_ID_AMD,	0x1450,	false},
+
+	/* Intel Xeon E5/Core i7 */
+	{PCI_VENDOR_ID_INTEL,	0x3c00, true},
+	{PCI_VENDOR_ID_INTEL,	0x3c01, true},
+	/* Intel Xeon E7 v3/Xeon E5 v3/Core i7 */
+	{PCI_VENDOR_ID_INTEL,	0x2f00, true},
+	{PCI_VENDOR_ID_INTEL,	0x2f01, true},
+	{}
+};
+
+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)
@@ -262,9 +281,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->req_same_host_bridge && !same_host_bridge)
+			return false;
+
 		return true;
+	}
 
 	return false;
 }
@@ -281,7 +305,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;