[PATCH 2/2] drm/i915: Fill stolen with garbage across hibernation for testing.

Chris Wilson chris at chris-wilson.co.uk
Wed Aug 29 16:13:36 UTC 2018


Under CI, we only use S4-devices for speed and reliability. However,
this does mean that we miss out on some of the more interesting
side-effects that come from letting the BIOS lose and capacitors
discharge. However, we can simulate a lot of that for ourselves, and one
issue we have found in the past is that the contents of the memory the
BIOS reserves for graphics (stolen memory) is lost. To simulate that we
need only to completely overwrite it with garbage. (The only trick
involved is that we must use indirect access via the GGTT.)

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Jakub Bartmiński <jakub.bartminski at intel.com>
Cc: Matthew Auld <matthew.william.auld at gmail.com>
Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h        |  1 +
 drivers/gpu/drm/i915/i915_gem.c        |  9 ++++++++
 drivers/gpu/drm/i915/i915_gem_stolen.c | 31 ++++++++++++++++++++++++++
 3 files changed, 41 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e5b9d3c77139..e45b9b1eea04 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3307,6 +3307,7 @@ int i915_gem_stolen_insert_node_in_range(struct drm_i915_private *dev_priv,
 void i915_gem_stolen_remove_node(struct drm_i915_private *dev_priv,
 				 struct drm_mm_node *node);
 int i915_gem_init_stolen(struct drm_i915_private *dev_priv);
+void i915_gem_stolen_lost(struct drm_i915_private *i915);
 void i915_gem_cleanup_stolen(struct drm_device *dev);
 struct drm_i915_gem_object *
 i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 0453eb42a1a3..f5f669890a51 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -5854,6 +5854,15 @@ int i915_gem_freeze_late(struct drm_i915_private *i915)
 	}
 	mutex_unlock(&i915->drm.struct_mutex);
 
+	/*
+	 * As a final sting in the tail, invalidate stolen. Under a real S4,
+	 * stolen is lost and needs to be refilled on resume. However, under
+	 * CI we merely do S4-device testing (as full S4 is too unreliable
+	 * for automated testing across a cluster), so to simulate the effect
+	 * of stolen being trashed across S4, we trash it ourselves.
+	 */
+	i915_gem_stolen_lost(i915);
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index 53440bf87650..6f723eb38782 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -26,8 +26,11 @@
  *
  */
 
+#include <linux/random.h>
+
 #include <drm/drmP.h>
 #include <drm/i915_drm.h>
+
 #include "i915_drv.h"
 
 /*
@@ -167,6 +170,34 @@ static int i915_adjust_stolen(struct drm_i915_private *dev_priv,
 	return 0;
 }
 
+void i915_gem_stolen_lost(struct drm_i915_private *i915)
+{
+	struct i915_ggtt *ggtt = &i915->ggtt;
+	const u64 slot = ggtt->error_capture.start;
+	const resource_size_t size = resource_size(&i915->dsm);
+	unsigned long page;
+	u32 prng = 0x12345678;
+
+	/* Under CI simulate stolen being taken over by the BIOS */
+	if (!IS_ENABLED(CONFIG_DRM_I915_DEBUG))
+		return;
+
+	for (page = 0; page < size; page += PAGE_SIZE) {
+		const dma_addr_t dma = i915->dsm.start + page;
+		u32 __iomem *s;
+		int x;
+
+		ggtt->vm.insert_page(&ggtt->vm, dma, slot, I915_CACHE_NONE, 0);
+
+		s = io_mapping_map_atomic_wc(&ggtt->iomap, slot);
+		for (x = 0; x < PAGE_SIZE/sizeof(u32); x++)
+			s[x] = prng = next_pseudo_random32(prng);
+		io_mapping_unmap_atomic(s);
+	}
+
+	ggtt->vm.clear_range(&ggtt->vm, slot, PAGE_SIZE);
+}
+
 void i915_gem_cleanup_stolen(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = to_i915(dev);
-- 
2.18.0



More information about the Intel-gfx-trybot mailing list