[PATCH 031/131] drm/i915: Shrink pages around failure to dma map

Chris Wilson chris at chris-wilson.co.uk
Sat Aug 6 07:35:58 UTC 2016


Similar to how we handle resource allocation failure of both physical
memory and GGTT mmap space, if we fail to allocate our DMAR remapping,
shrink some of our other objects and try again.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 35 ++++++++++++++++++++++++++++++-----
 1 file changed, 30 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 0e0ff9fdceda..021ba203a992 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2299,12 +2299,37 @@ void i915_gem_suspend_gtt_mappings(struct drm_device *dev)
 
 int i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj)
 {
-	if (!dma_map_sg(&obj->base.dev->pdev->dev,
-			obj->pages->sgl, obj->pages->nents,
-			PCI_DMA_BIDIRECTIONAL))
-		return -ENOSPC;
+	struct drm_i915_private *i915 = to_i915(obj->base.dev);
+	struct device *dma_device = &obj->base.dev->pdev->dev;
 
-	return 0;
+	if (dma_map_sg(dma_device,
+		       obj->pages->sgl, obj->pages->nents,
+		       PCI_DMA_BIDIRECTIONAL))
+		return 0;
+
+	/* If we fail here, it is likely we couldn't allocate the map, or
+	 * we have exhausted the available DMAR space. First throw out
+	 * objects to make enough rooom for the mapping and try again,
+	 * though this doesn't take fragmentation into account. So if we
+	 * still fail, throw out everything we can and start afresh.
+	 */
+	i915_gem_shrink(i915,
+			obj->base.size >> PAGE_SHIFT,
+			I915_SHRINK_BOUND |
+			I915_SHRINK_UNBOUND |
+			I915_SHRINK_PURGEABLE);
+	if (dma_map_sg(dma_device,
+		       obj->pages->sgl, obj->pages->nents,
+		       PCI_DMA_BIDIRECTIONAL))
+		return 0;
+
+	i915_gem_shrink_all(i915);
+	if (dma_map_sg(dma_device,
+		       obj->pages->sgl, obj->pages->nents,
+		       PCI_DMA_BIDIRECTIONAL))
+		return 0;
+
+	return -ENOSPC;
 }
 
 static void gen8_set_pte(void __iomem *addr, gen8_pte_t pte)
-- 
2.8.1



More information about the Intel-gfx-trybot mailing list