Inter-revision diff: patch 2

Comparing v3 (message) to v6 (message)

--- v3
+++ v6
@@ -1,33 +1,40 @@
-Some NVIDIA GPU/NIC devices, although don't implement the CXL config space,
-they have many CXL-like properties. Call this kind "pre-CXL".
+Some NVIDIA GPU/NIC devices, though they don't implement CXL config space,
+have many CXL-like properties. Call this kind "pre-CXL".
 
-Similar to CXL.cache capaiblity, these pre-CXL devices also require the ATS
+Similar to CXL.cache capability, these pre-CXL devices also require the ATS
 function even when their RIDs are IOMMU bypassed, i.e. keep ATS "always on"
 v.s. "on demand" when a non-zero PASID line gets enabled in SVA use cases.
 
-Introduce pci_dev_specific_ats_always_on() quirk function to scan a list of
-IDs for these device. Then, include it pci_ats_always_on().
+Introduce pci_dev_specific_ats_required() quirk function to scan a list of
+IDs for these devices. Then, include it in pci_ats_required().
 
 Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
+Reviewed-by: Nirmoy Das <nirmoyd@nvidia.com>
+Tested-by: Nirmoy Das <nirmoyd@nvidia.com>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Acked-by: Bjorn Helgaas <bhelgaas@google.com>
 Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
 ---
  drivers/pci/pci.h    |  9 +++++++++
  drivers/pci/ats.c    |  3 ++-
- drivers/pci/quirks.c | 26 ++++++++++++++++++++++++++
- 3 files changed, 37 insertions(+), 1 deletion(-)
+ drivers/pci/quirks.c | 42 ++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 53 insertions(+), 1 deletion(-)
 
 diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
-index 13d998fbacce6..13fa71f965900 100644
+index 4a14f88e543a2..e8ad27abb1cfe 100644
 --- a/drivers/pci/pci.h
 +++ b/drivers/pci/pci.h
-@@ -1150,6 +1150,15 @@ static inline int pci_dev_specific_reset(struct pci_dev *dev, bool probe)
+@@ -1155,6 +1155,15 @@ static inline int pci_dev_specific_reset(struct pci_dev *dev, bool probe)
  }
  #endif
  
 +#if defined(CONFIG_PCI_QUIRKS) && defined(CONFIG_PCI_ATS)
-+bool pci_dev_specific_ats_always_on(struct pci_dev *dev);
++bool pci_dev_specific_ats_required(struct pci_dev *dev);
 +#else
-+static inline bool pci_dev_specific_ats_always_on(struct pci_dev *dev)
++static inline bool pci_dev_specific_ats_required(struct pci_dev *dev)
 +{
 +	return false;
 +}
@@ -37,48 +44,64 @@
  int acpi_get_rc_resources(struct device *dev, const char *hid, u16 segment,
  			  struct resource *res);
 diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c
-index cf262eb6e6890..e6995b536ad4c 100644
+index 84cd06d74fc9c..96efa00d97433 100644
 --- a/drivers/pci/ats.c
 +++ b/drivers/pci/ats.c
-@@ -243,7 +243,8 @@ bool pci_ats_always_on(struct pci_dev *pdev)
+@@ -247,7 +247,8 @@ bool pci_ats_required(struct pci_dev *pdev)
  	if (pdev->is_virtfn)
  		pdev = pci_physfn(pdev);
  
--	return pci_cxl_ats_always_on(pdev);
-+	return pci_cxl_ats_always_on(pdev) ||
-+	       pci_dev_specific_ats_always_on(pdev);
+-	return pci_cxl_ats_required(pdev);
++	return pci_cxl_ats_required(pdev) ||
++	       pci_dev_specific_ats_required(pdev);
  }
- EXPORT_SYMBOL_GPL(pci_ats_always_on);
+ EXPORT_SYMBOL_GPL(pci_ats_required);
  
 diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
-index 48946cca4be72..21451e62f284e 100644
+index caaed1a01dc02..c0242f3e9f063 100644
 --- a/drivers/pci/quirks.c
 +++ b/drivers/pci/quirks.c
-@@ -5714,6 +5714,32 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1457, quirk_intel_e2000_no_ats);
+@@ -5715,6 +5715,48 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1457, quirk_intel_e2000_no_ats);
  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1459, quirk_intel_e2000_no_ats);
  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x145a, quirk_intel_e2000_no_ats);
  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x145c, quirk_intel_e2000_no_ats);
 +
-+static const struct pci_dev_ats_always_on {
++static bool quirk_nvidia_gpu_ats_required(struct pci_dev *pdev)
++{
++	switch (pdev->device) {
++	case 0x2e00 ... 0x2e3f: /* GB20B */
++		return true;
++	}
++	return false;
++}
++
++static const struct pci_dev_ats_required {
 +	u16 vendor;
 +	u16 device;
-+} pci_dev_ats_always_on[] = {
++	bool (*ats_required)(struct pci_dev *dev);
++} pci_dev_ats_required[] = {
 +	/* NVIDIA GPUs */
-+	{ PCI_VENDOR_ID_NVIDIA, 0x2e12, },
-+	{ PCI_VENDOR_ID_NVIDIA, 0x2e2a, },
-+	{ PCI_VENDOR_ID_NVIDIA, 0x2e2b, },
++	{ PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, quirk_nvidia_gpu_ats_required },
 +	/* NVIDIA CX10 Family NVlink-C2C */
-+	{ PCI_VENDOR_ID_MELLANOX, 0x2101, },
++	{ PCI_VENDOR_ID_MELLANOX, 0x2101, NULL },
 +	{ 0 }
 +};
 +
-+/* Some pre-CXL devices require ATS on the RID when it is IOMMU-bypassed */
-+bool pci_dev_specific_ats_always_on(struct pci_dev *pdev)
++/*
++ * Some NVIDIA devices do not implement CXL config space, but present as PCIe
++ * devices that can issue CXL-like cache operations like CXL.cache. Thus, they
++ * require ATS to obtain host physical addresses, like pci_cxl_ats_required().
++ */
++bool pci_dev_specific_ats_required(struct pci_dev *pdev)
 +{
-+	const struct pci_dev_ats_always_on *i;
++	const struct pci_dev_ats_required *i;
 +
-+	for (i = pci_dev_ats_always_on; i->vendor; i++) {
-+		if (i->vendor == pdev->vendor && i->device == pdev->device)
++	for (i = pci_dev_ats_required; i->vendor; i++) {
++		if (i->vendor != pdev->vendor)
++			continue;
++		if (i->ats_required && i->ats_required(pdev))
++			return true;
++		if (!i->ats_required && i->device == pdev->device)
 +			return true;
 +	}
 +
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help