[PATCH] noatomic

Chris Wilson chris at chris-wilson.co.uk
Wed Jan 13 00:23:25 UTC 2021


---
 drivers/gpu/drm/i915/i915_gem_gtt.c |  1 +
 drivers/iommu/dma-iommu.c           | 16 ++++++++++++++--
 drivers/iommu/iommu-internal.h      | 14 ++++++++++++++
 drivers/iommu/iommu.c               |  9 +++++----
 include/linux/dma-mapping.h         |  2 ++
 5 files changed, 36 insertions(+), 6 deletions(-)
 create mode 100644 drivers/iommu/iommu-internal.h

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 3ee2f682eff6..b0d38a574ddc 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -33,6 +33,7 @@ int i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj,
 				     PCI_DMA_BIDIRECTIONAL,
 				     DMA_ATTR_SKIP_CPU_SYNC |
 				     DMA_ATTR_NO_KERNEL_MAPPING |
+				     DMA_ATTR_MAY_SLEEP |
 				     DMA_ATTR_NO_WARN))
 			return 0;
 
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 4078358ed66e..1a8576d5d530 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -26,6 +26,8 @@
 #include <linux/crash_dump.h>
 #include <linux/dma-direct.h>
 
+#include "iommu-internal.h"
+
 struct iommu_dma_msi_page {
 	struct list_head	list;
 	dma_addr_t		iova;
@@ -974,6 +976,7 @@ static int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg,
 	dma_addr_t iova;
 	size_t iova_len = 0;
 	unsigned long mask = dma_get_seg_boundary(dev);
+	gfp_t gfp;
 	int i;
 
 	if (unlikely(iommu_dma_deferred_attach(dev, domain)))
@@ -1025,15 +1028,24 @@ static int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg,
 	}
 
 	iova = iommu_dma_alloc_iova(domain, iova_len, dma_get_mask(dev), dev);
-	if (!iova)
+	if (!iova) {
+		pr_err("iommu_dma_alloc_iova failed\n");
 		goto out_restore_sg;
+	}
 
 	/*
 	 * We'll leave any physical concatenation to the IOMMU driver's
 	 * implementation - it knows better than we do.
 	 */
-	if (iommu_map_sg_atomic(domain, iova, sg, nents, prot) < iova_len)
+	gfp = GFP_ATOMIC;
+	if (attrs & DMA_ATTR_MAY_SLEEP)
+		gfp = GFP_KERNEL;
+	if (attrs & DMA_ATTR_NO_WARN)
+		gfp |= __GFP_NOWARN;
+	if (__iommu_map_sg(domain, iova, sg, nents, prot, gfp) < iova_len) {
+		pr_err("iommu_map_sg failed\n");
 		goto out_free_iova;
+	}
 
 	return __finalise_sg(dev, sg, nents, iova);
 
diff --git a/drivers/iommu/iommu-internal.h b/drivers/iommu/iommu-internal.h
new file mode 100644
index 000000000000..18e54ef42c03
--- /dev/null
+++ b/drivers/iommu/iommu-internal.h
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
+ * Author: Joerg Roedel <jroedel at suse.de>
+ */
+
+#ifndef __IOMMU_INTERNAL_H__
+#define __IOMMU_INTERNAL_H__
+
+size_t __iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
+		      struct scatterlist *sg, unsigned int nents, int prot,
+		      gfp_t gfp);
+
+#endif /* __IOMMU_INTERNAL_H__ */
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index ffeebda8d6de..0a7de4cda322 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -25,6 +25,8 @@
 #include <linux/module.h>
 #include <trace/events/iommu.h>
 
+#include "iommu-internal.h"
+
 static struct kset *iommu_group_kset;
 static DEFINE_IDA(iommu_group_ida);
 
@@ -2529,9 +2531,9 @@ size_t iommu_unmap_fast(struct iommu_domain *domain,
 }
 EXPORT_SYMBOL_GPL(iommu_unmap_fast);
 
-static size_t __iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
-			     struct scatterlist *sg, unsigned int nents, int prot,
-			     gfp_t gfp)
+size_t __iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
+		      struct scatterlist *sg, unsigned int nents, int prot,
+		      gfp_t gfp)
 {
 	size_t len = 0, mapped = 0;
 	phys_addr_t start;
@@ -2570,7 +2572,6 @@ static size_t __iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
 	iommu_unmap(domain, iova, mapped);
 
 	return 0;
-
 }
 
 size_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 2e49996a8f39..d887b720cceb 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -61,6 +61,8 @@
  */
 #define DMA_ATTR_PRIVILEGED		(1UL << 9)
 
+#define DMA_ATTR_MAY_SLEEP		(1UL << 10)
+
 /*
  * A dma_addr_t can hold any valid DMA or bus address for the platform.  It can
  * be given to a device to use as a DMA source or target.  It is specific to a
-- 
2.20.1



More information about the Intel-gfx-trybot mailing list