[PATCH 56/64] drm/i915/gem: Reduce some locked waits

Chris Wilson chris at chris-wilson.co.uk
Tue Jun 23 16:11:38 UTC 2020


In the future, we will completely erradicate the locked waits on
dma_resv, but first there are a few low hanging fruits which we can
switch immediately to unlocked waits. In the process, we introduce an
i915_gem_object_invalidate_map() as a complement to the internal
i915_gem_object_flush_map(). One advantage to using explicit waits is
that we can impose a timeout for our selftests, helping us to detect
unexpected hangs much quicker.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/gem/i915_gem_object.h    |  9 +++++++
 drivers/gpu/drm/i915/gem/i915_gem_pages.c     | 25 +++++++++++++++++++
 .../i915/gem/selftests/i915_gem_client_blt.c  |  7 +++---
 .../i915/gem/selftests/i915_gem_coherency.c   | 24 +++++-------------
 .../drm/i915/gem/selftests/i915_gem_context.c |  8 +++---
 .../gpu/drm/i915/gt/selftest_workarounds.c    | 17 ++++++-------
 drivers/gpu/drm/i915/gvt/cmd_parser.c         |  8 ------
 .../drm/i915/selftests/intel_memory_region.c  |  7 +++---
 8 files changed, 61 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index 7bcd2661de4c..977e34c93b0a 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -372,6 +372,15 @@ enum i915_map_type {
 void *__must_check i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
 					   enum i915_map_type type);
 
+void __i915_gem_object_invalidate_map(struct drm_i915_gem_object *obj,
+				      unsigned long offset,
+				      unsigned long size);
+static inline void
+i915_gem_object_invalidate_map(struct drm_i915_gem_object *obj)
+{
+	__i915_gem_object_invalidate_map(obj, 0, obj->base.size);
+}
+
 void __i915_gem_object_flush_map(struct drm_i915_gem_object *obj,
 				 unsigned long offset,
 				 unsigned long size);
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
index af9e48ee4a33..539ef181a8c1 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
@@ -380,6 +380,31 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
 	goto out_unlock;
 }
 
+void __i915_gem_object_invalidate_map(struct drm_i915_gem_object *obj,
+				      unsigned long offset,
+				      unsigned long size)
+{
+	enum i915_map_type has_type;
+	void *ptr;
+
+	GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
+	GEM_BUG_ON(range_overflows_t(typeof(obj->base.size),
+				     offset, size, obj->base.size));
+
+	if (obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ)
+		return;
+
+	ptr = page_unpack_bits(obj->mm.mapping, &has_type);
+	if (has_type == I915_MAP_WC)
+		return;
+
+	drm_clflush_virt_range(ptr + offset, size);
+	if (size == obj->base.size) {
+		obj->write_domain &= ~I915_GEM_DOMAIN_CPU;
+		obj->cache_dirty = false;
+	}
+}
+
 void __i915_gem_object_flush_map(struct drm_i915_gem_object *obj,
 				 unsigned long offset,
 				 unsigned long size)
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c
index 299c29e9ad86..38e77c2c896f 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c
@@ -75,12 +75,13 @@ static int __igt_client_fill(struct intel_engine_cs *engine)
 		if (err)
 			goto err_unpin;
 
-		i915_gem_object_lock(obj);
-		err = i915_gem_object_set_to_cpu_domain(obj, false);
-		i915_gem_object_unlock(obj);
+		err = i915_gem_object_wait(obj,
+					   I915_WAIT_INTERRUPTIBLE,
+					   HZ / 2);
 		if (err)
 			goto err_unpin;
 
+		__i915_gem_object_invalidate_map(obj, 0, huge_gem_object_phys_size(obj));
 		for (i = 0; i < huge_gem_object_phys_size(obj) / sizeof(u32); ++i) {
 			if (vaddr[i] != val) {
 				pr_err("vaddr[%u]=%x, expected=%x\n", i,
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c
index 87d7d8aa080f..5b3a9839de9b 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c
@@ -142,45 +142,33 @@ static int gtt_get(struct context *ctx, unsigned long offset, u32 *v)
 	return err;
 }
 
-static int wc_set(struct context *ctx, unsigned long offset, u32 v)
+static int map_set(struct context *ctx, unsigned long offset, u32 v)
 {
 	u32 *map;
-	int err;
-
-	i915_gem_object_lock(ctx->obj);
-	err = i915_gem_object_set_to_wc_domain(ctx->obj, true);
-	i915_gem_object_unlock(ctx->obj);
-	if (err)
-		return err;
 
 	map = i915_gem_object_pin_map(ctx->obj, I915_MAP_WC);
 	if (IS_ERR(map))
 		return PTR_ERR(map);
 
 	map[offset / sizeof(*map)] = v;
-
 	__i915_gem_object_flush_map(ctx->obj, offset, sizeof(*map));
+
 	i915_gem_object_unpin_map(ctx->obj);
 
 	return 0;
 }
 
-static int wc_get(struct context *ctx, unsigned long offset, u32 *v)
+static int map_get(struct context *ctx, unsigned long offset, u32 *v)
 {
 	u32 *map;
-	int err;
-
-	i915_gem_object_lock(ctx->obj);
-	err = i915_gem_object_set_to_wc_domain(ctx->obj, false);
-	i915_gem_object_unlock(ctx->obj);
-	if (err)
-		return err;
 
 	map = i915_gem_object_pin_map(ctx->obj, I915_MAP_WC);
 	if (IS_ERR(map))
 		return PTR_ERR(map);
 
+	__i915_gem_object_invalidate_map(ctx->obj, offset, sizeof(*map));
 	*v = map[offset / sizeof(*map)];
+
 	i915_gem_object_unpin_map(ctx->obj);
 
 	return 0;
@@ -277,7 +265,7 @@ static const struct igt_coherency_mode {
 } igt_coherency_mode[] = {
 	{ "cpu", cpu_set, cpu_get, always_valid },
 	{ "gtt", gtt_set, gtt_get, needs_fence_registers },
-	{ "wc", wc_set, wc_get, always_valid },
+	{ "map", map_set, map_get, always_valid },
 	{ "gpu", gpu_set, NULL, needs_mi_store_dword },
 	{ },
 };
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
index bb57687aea99..c2f8a6b3b018 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
@@ -1704,11 +1704,12 @@ static int read_from_scratch(struct i915_gem_context *ctx,
 
 	i915_vma_unpin(vma);
 
+	i915_request_get(rq);
 	i915_request_add(rq);
 
-	i915_gem_object_lock(obj);
-	err = i915_gem_object_set_to_cpu_domain(obj, false);
-	i915_gem_object_unlock(obj);
+	if (i915_request_wait(rq, I915_WAIT_INTERRUPTIBLE, HZ / 5) < 0)
+		err = -ETIME;
+	i915_request_put(rq);
 	if (err)
 		goto out_vm;
 
@@ -1718,6 +1719,7 @@ static int read_from_scratch(struct i915_gem_context *ctx,
 		goto out_vm;
 	}
 
+	drm_clflush_virt_range(&cmd[result / sizeof(*cmd)], sizeof(*cmd));
 	*value = cmd[result / sizeof(*cmd)];
 	i915_gem_object_unpin_map(obj);
 
diff --git a/drivers/gpu/drm/i915/gt/selftest_workarounds.c b/drivers/gpu/drm/i915/gt/selftest_workarounds.c
index febc9e6692ba..39ddf3bdc36e 100644
--- a/drivers/gpu/drm/i915/gt/selftest_workarounds.c
+++ b/drivers/gpu/drm/i915/gt/selftest_workarounds.c
@@ -204,7 +204,6 @@ static int check_whitelist(struct i915_gem_context *ctx,
 			   struct intel_engine_cs *engine)
 {
 	struct drm_i915_gem_object *results;
-	struct intel_wedge_me wedge;
 	u32 *vaddr;
 	int err;
 	int i;
@@ -213,15 +212,14 @@ static int check_whitelist(struct i915_gem_context *ctx,
 	if (IS_ERR(results))
 		return PTR_ERR(results);
 
-	err = 0;
-	i915_gem_object_lock(results);
-	intel_wedge_on_timeout(&wedge, engine->gt, HZ / 5) /* safety net! */
-		err = i915_gem_object_set_to_cpu_domain(results, false);
-	i915_gem_object_unlock(results);
-	if (intel_gt_is_wedged(engine->gt))
-		err = -EIO;
-	if (err)
+	err = i915_gem_object_wait(results,
+				   I915_WAIT_ALL |
+				   I915_WAIT_INTERRUPTIBLE,
+				   HZ / 5);
+	if (err) {
+		intel_gt_set_wedged(engine->gt);
 		goto out_put;
+	}
 
 	vaddr = i915_gem_object_pin_map(results, I915_MAP_WB);
 	if (IS_ERR(vaddr)) {
@@ -229,6 +227,7 @@ static int check_whitelist(struct i915_gem_context *ctx,
 		goto out_put;
 	}
 
+	i915_gem_object_invalidate_map(results);
 	for (i = 0; i < RING_MAX_NONPRIV_SLOTS; i++) {
 		u32 expected = get_whitelist_reg(engine, i);
 		u32 actual = vaddr[i];
diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c
index f1940939260a..c4ac37dc7c81 100644
--- a/drivers/gpu/drm/i915/gvt/cmd_parser.c
+++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c
@@ -2982,14 +2982,6 @@ static int shadow_indirect_ctx(struct intel_shadow_wa_ctx *wa_ctx)
 		goto put_obj;
 	}
 
-	i915_gem_object_lock(obj);
-	ret = i915_gem_object_set_to_cpu_domain(obj, false);
-	i915_gem_object_unlock(obj);
-	if (ret) {
-		gvt_vgpu_err("failed to set shadow indirect ctx to CPU\n");
-		goto unmap_src;
-	}
-
 	ret = copy_gma_to_hva(workload->vgpu,
 				workload->vgpu->gtt.ggtt_mm,
 				guest_gma, guest_gma + ctx_size,
diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
index 6e80d99048e4..8017b06c7717 100644
--- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c
@@ -509,9 +509,10 @@ static int igt_lmem_write_cpu(void *arg)
 	if (err)
 		goto out_unpin;
 
-	i915_gem_object_lock(obj);
-	err = i915_gem_object_set_to_wc_domain(obj, true);
-	i915_gem_object_unlock(obj);
+	err = i915_gem_object_wait(obj,
+				   I915_WAIT_ALL |
+				   I915_WAIT_INTERRUPTIBLE,
+				   HZ / 2);
 	if (err)
 		goto out_unpin;
 
-- 
2.20.1



More information about the Intel-gfx-trybot mailing list