All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 01/28] drm/i915: Fix i915_request fence wait semantics
@ 2021-10-21 10:35 ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

The i915_request fence wait behaves differently for timeout = 0
compared to expected dma-fence behavior.

i915 behavior:
- Unsignaled: -ETIME
- Signaled: 0 (= timeout)

Expected:
- Unsignaled: 0
- Signaled: 1

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_request.c | 57 ++++++++++++++++++++++++-----
 drivers/gpu/drm/i915/i915_request.h |  5 +++
 2 files changed, 52 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index 820a1f38b271..42cd17357771 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -96,9 +96,9 @@ static signed long i915_fence_wait(struct dma_fence *fence,
 				   bool interruptible,
 				   signed long timeout)
 {
-	return i915_request_wait(to_request(fence),
-				 interruptible | I915_WAIT_PRIORITY,
-				 timeout);
+	return i915_request_wait_timeout(to_request(fence),
+					 interruptible | I915_WAIT_PRIORITY,
+					 timeout);
 }
 
 struct kmem_cache *i915_request_slab_cache(void)
@@ -1857,23 +1857,27 @@ static void request_wait_wake(struct dma_fence *fence, struct dma_fence_cb *cb)
 }
 
 /**
- * i915_request_wait - wait until execution of request has finished
+ * i915_request_wait_timeout - wait until execution of request has finished
  * @rq: the request to wait upon
  * @flags: how to wait
  * @timeout: how long to wait in jiffies
  *
- * i915_request_wait() waits for the request to be completed, for a
+ * i915_request_wait_timeout() waits for the request to be completed, for a
  * maximum of @timeout jiffies (with MAX_SCHEDULE_TIMEOUT implying an
  * unbounded wait).
  *
  * Returns the remaining time (in jiffies) if the request completed, which may
- * be zero or -ETIME if the request is unfinished after the timeout expires.
+ * be zero if the request is unfinished after the timeout expires.
+ * If the timeout is 0, it will return 1 if the fence is signaled.
+ *
  * May return -EINTR is called with I915_WAIT_INTERRUPTIBLE and a signal is
  * pending before the request completes.
+ *
+ * NOTE: This function has the same wait semantics as dma-fence.
  */
-long i915_request_wait(struct i915_request *rq,
-		       unsigned int flags,
-		       long timeout)
+long i915_request_wait_timeout(struct i915_request *rq,
+			       unsigned int flags,
+			       long timeout)
 {
 	const int state = flags & I915_WAIT_INTERRUPTIBLE ?
 		TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE;
@@ -1883,7 +1887,7 @@ long i915_request_wait(struct i915_request *rq,
 	GEM_BUG_ON(timeout < 0);
 
 	if (dma_fence_is_signaled(&rq->fence))
-		return timeout;
+		return timeout ?: 1;
 
 	if (!timeout)
 		return -ETIME;
@@ -1992,6 +1996,39 @@ long i915_request_wait(struct i915_request *rq,
 	return timeout;
 }
 
+/**
+ * i915_request_wait - wait until execution of request has finished
+ * @rq: the request to wait upon
+ * @flags: how to wait
+ * @timeout: how long to wait in jiffies
+ *
+ * i915_request_wait() waits for the request to be completed, for a
+ * maximum of @timeout jiffies (with MAX_SCHEDULE_TIMEOUT implying an
+ * unbounded wait).
+ *
+ * Returns the remaining time (in jiffies) if the request completed, which may
+ * be zero or -ETIME if the request is unfinished after the timeout expires.
+ * May return -EINTR is called with I915_WAIT_INTERRUPTIBLE and a signal is
+ * pending before the request completes.
+ *
+ * NOTE: This function behaves differently from dma-fence wait semantics for
+ * timeout = 0. It returns 0 on success, and -ETIME if not signaled.
+ */
+long i915_request_wait(struct i915_request *rq,
+		       unsigned int flags,
+		       long timeout)
+{
+	long ret = i915_request_wait_timeout(rq, flags, timeout);
+
+	if (!ret)
+		return -ETIME;
+
+	if (ret > 0 && !timeout)
+		return 0;
+
+	return ret;
+}
+
 static int print_sched_attr(const struct i915_sched_attr *attr,
 			    char *buf, int x, int len)
 {
diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h
index dc359242d1ae..3c6e8acd1457 100644
--- a/drivers/gpu/drm/i915/i915_request.h
+++ b/drivers/gpu/drm/i915/i915_request.h
@@ -414,6 +414,11 @@ void i915_request_unsubmit(struct i915_request *request);
 
 void i915_request_cancel(struct i915_request *rq, int error);
 
+long i915_request_wait_timeout(struct i915_request *rq,
+			       unsigned int flags,
+			       long timeout)
+	__attribute__((nonnull(1)));
+
 long i915_request_wait(struct i915_request *rq,
 		       unsigned int flags,
 		       long timeout)
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 01/28] drm/i915: Fix i915_request fence wait semantics
@ 2021-10-21 10:35 ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

The i915_request fence wait behaves differently for timeout = 0
compared to expected dma-fence behavior.

i915 behavior:
- Unsignaled: -ETIME
- Signaled: 0 (= timeout)

Expected:
- Unsignaled: 0
- Signaled: 1

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_request.c | 57 ++++++++++++++++++++++++-----
 drivers/gpu/drm/i915/i915_request.h |  5 +++
 2 files changed, 52 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index 820a1f38b271..42cd17357771 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -96,9 +96,9 @@ static signed long i915_fence_wait(struct dma_fence *fence,
 				   bool interruptible,
 				   signed long timeout)
 {
-	return i915_request_wait(to_request(fence),
-				 interruptible | I915_WAIT_PRIORITY,
-				 timeout);
+	return i915_request_wait_timeout(to_request(fence),
+					 interruptible | I915_WAIT_PRIORITY,
+					 timeout);
 }
 
 struct kmem_cache *i915_request_slab_cache(void)
@@ -1857,23 +1857,27 @@ static void request_wait_wake(struct dma_fence *fence, struct dma_fence_cb *cb)
 }
 
 /**
- * i915_request_wait - wait until execution of request has finished
+ * i915_request_wait_timeout - wait until execution of request has finished
  * @rq: the request to wait upon
  * @flags: how to wait
  * @timeout: how long to wait in jiffies
  *
- * i915_request_wait() waits for the request to be completed, for a
+ * i915_request_wait_timeout() waits for the request to be completed, for a
  * maximum of @timeout jiffies (with MAX_SCHEDULE_TIMEOUT implying an
  * unbounded wait).
  *
  * Returns the remaining time (in jiffies) if the request completed, which may
- * be zero or -ETIME if the request is unfinished after the timeout expires.
+ * be zero if the request is unfinished after the timeout expires.
+ * If the timeout is 0, it will return 1 if the fence is signaled.
+ *
  * May return -EINTR is called with I915_WAIT_INTERRUPTIBLE and a signal is
  * pending before the request completes.
+ *
+ * NOTE: This function has the same wait semantics as dma-fence.
  */
-long i915_request_wait(struct i915_request *rq,
-		       unsigned int flags,
-		       long timeout)
+long i915_request_wait_timeout(struct i915_request *rq,
+			       unsigned int flags,
+			       long timeout)
 {
 	const int state = flags & I915_WAIT_INTERRUPTIBLE ?
 		TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE;
@@ -1883,7 +1887,7 @@ long i915_request_wait(struct i915_request *rq,
 	GEM_BUG_ON(timeout < 0);
 
 	if (dma_fence_is_signaled(&rq->fence))
-		return timeout;
+		return timeout ?: 1;
 
 	if (!timeout)
 		return -ETIME;
@@ -1992,6 +1996,39 @@ long i915_request_wait(struct i915_request *rq,
 	return timeout;
 }
 
+/**
+ * i915_request_wait - wait until execution of request has finished
+ * @rq: the request to wait upon
+ * @flags: how to wait
+ * @timeout: how long to wait in jiffies
+ *
+ * i915_request_wait() waits for the request to be completed, for a
+ * maximum of @timeout jiffies (with MAX_SCHEDULE_TIMEOUT implying an
+ * unbounded wait).
+ *
+ * Returns the remaining time (in jiffies) if the request completed, which may
+ * be zero or -ETIME if the request is unfinished after the timeout expires.
+ * May return -EINTR is called with I915_WAIT_INTERRUPTIBLE and a signal is
+ * pending before the request completes.
+ *
+ * NOTE: This function behaves differently from dma-fence wait semantics for
+ * timeout = 0. It returns 0 on success, and -ETIME if not signaled.
+ */
+long i915_request_wait(struct i915_request *rq,
+		       unsigned int flags,
+		       long timeout)
+{
+	long ret = i915_request_wait_timeout(rq, flags, timeout);
+
+	if (!ret)
+		return -ETIME;
+
+	if (ret > 0 && !timeout)
+		return 0;
+
+	return ret;
+}
+
 static int print_sched_attr(const struct i915_sched_attr *attr,
 			    char *buf, int x, int len)
 {
diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h
index dc359242d1ae..3c6e8acd1457 100644
--- a/drivers/gpu/drm/i915/i915_request.h
+++ b/drivers/gpu/drm/i915/i915_request.h
@@ -414,6 +414,11 @@ void i915_request_unsubmit(struct i915_request *request);
 
 void i915_request_cancel(struct i915_request *rq, int error);
 
+long i915_request_wait_timeout(struct i915_request *rq,
+			       unsigned int flags,
+			       long timeout)
+	__attribute__((nonnull(1)));
+
 long i915_request_wait(struct i915_request *rq,
 		       unsigned int flags,
 		       long timeout)
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 02/28] drm/i915: use new iterator in i915_gem_object_wait_reservation
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:35   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Christian König, Maarten Lankhorst

From: Christian König <christian.koenig@amd.com>

Simplifying the code a bit.

Signed-off-by: Christian König <christian.koenig@amd.com>
[mlankhorst: Handle timeout = 0 correctly, use new i915_request_wait_timeout.]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_wait.c | 65 ++++++++----------------
 1 file changed, 20 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_wait.c b/drivers/gpu/drm/i915/gem/i915_gem_wait.c
index f909aaa09d9c..840c13706999 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_wait.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_wait.c
@@ -25,7 +25,7 @@ i915_gem_object_wait_fence(struct dma_fence *fence,
 		return timeout;
 
 	if (dma_fence_is_i915(fence))
-		return i915_request_wait(to_request(fence), flags, timeout);
+		return i915_request_wait_timeout(to_request(fence), flags, timeout);
 
 	return dma_fence_wait_timeout(fence,
 				      flags & I915_WAIT_INTERRUPTIBLE,
@@ -37,58 +37,29 @@ i915_gem_object_wait_reservation(struct dma_resv *resv,
 				 unsigned int flags,
 				 long timeout)
 {
-	struct dma_fence *excl;
-	bool prune_fences = false;
-
-	if (flags & I915_WAIT_ALL) {
-		struct dma_fence **shared;
-		unsigned int count, i;
-		int ret;
-
-		ret = dma_resv_get_fences(resv, &excl, &count, &shared);
-		if (ret)
-			return ret;
-
-		for (i = 0; i < count; i++) {
-			timeout = i915_gem_object_wait_fence(shared[i],
-							     flags, timeout);
-			if (timeout < 0)
-				break;
-
-			dma_fence_put(shared[i]);
-		}
-
-		for (; i < count; i++)
-			dma_fence_put(shared[i]);
-		kfree(shared);
+	struct dma_resv_iter cursor;
+	struct dma_fence *fence;
+	long ret = timeout ?: 1;
+
+	dma_resv_iter_begin(&cursor, resv, flags & I915_WAIT_ALL);
+	dma_resv_for_each_fence_unlocked(&cursor, fence) {
+		ret = i915_gem_object_wait_fence(fence, flags, timeout);
+		if (ret <= 0)
+			break;
 
-		/*
-		 * If both shared fences and an exclusive fence exist,
-		 * then by construction the shared fences must be later
-		 * than the exclusive fence. If we successfully wait for
-		 * all the shared fences, we know that the exclusive fence
-		 * must all be signaled. If all the shared fences are
-		 * signaled, we can prune the array and recover the
-		 * floating references on the fences/requests.
-		 */
-		prune_fences = count && timeout >= 0;
-	} else {
-		excl = dma_resv_get_excl_unlocked(resv);
+		if (timeout)
+			timeout = ret;
 	}
-
-	if (excl && timeout >= 0)
-		timeout = i915_gem_object_wait_fence(excl, flags, timeout);
-
-	dma_fence_put(excl);
+	dma_resv_iter_end(&cursor);
 
 	/*
 	 * Opportunistically prune the fences iff we know they have *all* been
 	 * signaled.
 	 */
-	if (prune_fences)
+	if (timeout > 0)
 		dma_resv_prune(resv);
 
-	return timeout;
+	return ret;
 }
 
 static void fence_set_priority(struct dma_fence *fence,
@@ -196,7 +167,11 @@ i915_gem_object_wait(struct drm_i915_gem_object *obj,
 
 	timeout = i915_gem_object_wait_reservation(obj->base.resv,
 						   flags, timeout);
-	return timeout < 0 ? timeout : 0;
+
+	if (timeout < 0)
+		return timeout;
+
+	return !timeout ? -ETIME : 0;
 }
 
 static inline unsigned long nsecs_to_jiffies_timeout(const u64 n)
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 02/28] drm/i915: use new iterator in i915_gem_object_wait_reservation
@ 2021-10-21 10:35   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Christian König, Maarten Lankhorst

From: Christian König <christian.koenig@amd.com>

Simplifying the code a bit.

Signed-off-by: Christian König <christian.koenig@amd.com>
[mlankhorst: Handle timeout = 0 correctly, use new i915_request_wait_timeout.]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_wait.c | 65 ++++++++----------------
 1 file changed, 20 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_wait.c b/drivers/gpu/drm/i915/gem/i915_gem_wait.c
index f909aaa09d9c..840c13706999 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_wait.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_wait.c
@@ -25,7 +25,7 @@ i915_gem_object_wait_fence(struct dma_fence *fence,
 		return timeout;
 
 	if (dma_fence_is_i915(fence))
-		return i915_request_wait(to_request(fence), flags, timeout);
+		return i915_request_wait_timeout(to_request(fence), flags, timeout);
 
 	return dma_fence_wait_timeout(fence,
 				      flags & I915_WAIT_INTERRUPTIBLE,
@@ -37,58 +37,29 @@ i915_gem_object_wait_reservation(struct dma_resv *resv,
 				 unsigned int flags,
 				 long timeout)
 {
-	struct dma_fence *excl;
-	bool prune_fences = false;
-
-	if (flags & I915_WAIT_ALL) {
-		struct dma_fence **shared;
-		unsigned int count, i;
-		int ret;
-
-		ret = dma_resv_get_fences(resv, &excl, &count, &shared);
-		if (ret)
-			return ret;
-
-		for (i = 0; i < count; i++) {
-			timeout = i915_gem_object_wait_fence(shared[i],
-							     flags, timeout);
-			if (timeout < 0)
-				break;
-
-			dma_fence_put(shared[i]);
-		}
-
-		for (; i < count; i++)
-			dma_fence_put(shared[i]);
-		kfree(shared);
+	struct dma_resv_iter cursor;
+	struct dma_fence *fence;
+	long ret = timeout ?: 1;
+
+	dma_resv_iter_begin(&cursor, resv, flags & I915_WAIT_ALL);
+	dma_resv_for_each_fence_unlocked(&cursor, fence) {
+		ret = i915_gem_object_wait_fence(fence, flags, timeout);
+		if (ret <= 0)
+			break;
 
-		/*
-		 * If both shared fences and an exclusive fence exist,
-		 * then by construction the shared fences must be later
-		 * than the exclusive fence. If we successfully wait for
-		 * all the shared fences, we know that the exclusive fence
-		 * must all be signaled. If all the shared fences are
-		 * signaled, we can prune the array and recover the
-		 * floating references on the fences/requests.
-		 */
-		prune_fences = count && timeout >= 0;
-	} else {
-		excl = dma_resv_get_excl_unlocked(resv);
+		if (timeout)
+			timeout = ret;
 	}
-
-	if (excl && timeout >= 0)
-		timeout = i915_gem_object_wait_fence(excl, flags, timeout);
-
-	dma_fence_put(excl);
+	dma_resv_iter_end(&cursor);
 
 	/*
 	 * Opportunistically prune the fences iff we know they have *all* been
 	 * signaled.
 	 */
-	if (prune_fences)
+	if (timeout > 0)
 		dma_resv_prune(resv);
 
-	return timeout;
+	return ret;
 }
 
 static void fence_set_priority(struct dma_fence *fence,
@@ -196,7 +167,11 @@ i915_gem_object_wait(struct drm_i915_gem_object *obj,
 
 	timeout = i915_gem_object_wait_reservation(obj->base.resv,
 						   flags, timeout);
-	return timeout < 0 ? timeout : 0;
+
+	if (timeout < 0)
+		return timeout;
+
+	return !timeout ? -ETIME : 0;
 }
 
 static inline unsigned long nsecs_to_jiffies_timeout(const u64 n)
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 03/28] drm/i915: Remove dma_resv_prune
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:35   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

The signaled bit is already used for quick testing if a fence is signaled.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/Makefile                |  1 -
 drivers/gpu/drm/i915/dma_resv_utils.c        | 17 -----------------
 drivers/gpu/drm/i915/dma_resv_utils.h        | 13 -------------
 drivers/gpu/drm/i915/gem/i915_gem_shrinker.c |  3 ---
 drivers/gpu/drm/i915/gem/i915_gem_wait.c     |  8 --------
 5 files changed, 42 deletions(-)
 delete mode 100644 drivers/gpu/drm/i915/dma_resv_utils.c
 delete mode 100644 drivers/gpu/drm/i915/dma_resv_utils.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 467872cca027..b87e3ed10d86 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -60,7 +60,6 @@ i915-y += i915_drv.o \
 
 # core library code
 i915-y += \
-	dma_resv_utils.o \
 	i915_memcpy.o \
 	i915_mm.o \
 	i915_sw_fence.o \
diff --git a/drivers/gpu/drm/i915/dma_resv_utils.c b/drivers/gpu/drm/i915/dma_resv_utils.c
deleted file mode 100644
index 7df91b7e4ca8..000000000000
--- a/drivers/gpu/drm/i915/dma_resv_utils.c
+++ /dev/null
@@ -1,17 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright © 2020 Intel Corporation
- */
-
-#include <linux/dma-resv.h>
-
-#include "dma_resv_utils.h"
-
-void dma_resv_prune(struct dma_resv *resv)
-{
-	if (dma_resv_trylock(resv)) {
-		if (dma_resv_test_signaled(resv, true))
-			dma_resv_add_excl_fence(resv, NULL);
-		dma_resv_unlock(resv);
-	}
-}
diff --git a/drivers/gpu/drm/i915/dma_resv_utils.h b/drivers/gpu/drm/i915/dma_resv_utils.h
deleted file mode 100644
index b9d8fb5f8367..000000000000
--- a/drivers/gpu/drm/i915/dma_resv_utils.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2020 Intel Corporation
- */
-
-#ifndef DMA_RESV_UTILS_H
-#define DMA_RESV_UTILS_H
-
-struct dma_resv;
-
-void dma_resv_prune(struct dma_resv *resv);
-
-#endif /* DMA_RESV_UTILS_H */
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
index 5ab136ffdeb2..af3eb7fd951d 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
@@ -15,7 +15,6 @@
 
 #include "gt/intel_gt_requests.h"
 
-#include "dma_resv_utils.h"
 #include "i915_trace.h"
 
 static bool swap_available(void)
@@ -229,8 +228,6 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww,
 					i915_gem_object_unlock(obj);
 			}
 
-			dma_resv_prune(obj->base.resv);
-
 			scanned += obj->base.size >> PAGE_SHIFT;
 skip:
 			i915_gem_object_put(obj);
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_wait.c b/drivers/gpu/drm/i915/gem/i915_gem_wait.c
index 840c13706999..1592d95c3ead 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_wait.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_wait.c
@@ -10,7 +10,6 @@
 
 #include "gt/intel_engine.h"
 
-#include "dma_resv_utils.h"
 #include "i915_gem_ioctls.h"
 #include "i915_gem_object.h"
 
@@ -52,13 +51,6 @@ i915_gem_object_wait_reservation(struct dma_resv *resv,
 	}
 	dma_resv_iter_end(&cursor);
 
-	/*
-	 * Opportunistically prune the fences iff we know they have *all* been
-	 * signaled.
-	 */
-	if (timeout > 0)
-		dma_resv_prune(resv);
-
 	return ret;
 }
 
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 03/28] drm/i915: Remove dma_resv_prune
@ 2021-10-21 10:35   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

The signaled bit is already used for quick testing if a fence is signaled.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/Makefile                |  1 -
 drivers/gpu/drm/i915/dma_resv_utils.c        | 17 -----------------
 drivers/gpu/drm/i915/dma_resv_utils.h        | 13 -------------
 drivers/gpu/drm/i915/gem/i915_gem_shrinker.c |  3 ---
 drivers/gpu/drm/i915/gem/i915_gem_wait.c     |  8 --------
 5 files changed, 42 deletions(-)
 delete mode 100644 drivers/gpu/drm/i915/dma_resv_utils.c
 delete mode 100644 drivers/gpu/drm/i915/dma_resv_utils.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 467872cca027..b87e3ed10d86 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -60,7 +60,6 @@ i915-y += i915_drv.o \
 
 # core library code
 i915-y += \
-	dma_resv_utils.o \
 	i915_memcpy.o \
 	i915_mm.o \
 	i915_sw_fence.o \
diff --git a/drivers/gpu/drm/i915/dma_resv_utils.c b/drivers/gpu/drm/i915/dma_resv_utils.c
deleted file mode 100644
index 7df91b7e4ca8..000000000000
--- a/drivers/gpu/drm/i915/dma_resv_utils.c
+++ /dev/null
@@ -1,17 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * Copyright © 2020 Intel Corporation
- */
-
-#include <linux/dma-resv.h>
-
-#include "dma_resv_utils.h"
-
-void dma_resv_prune(struct dma_resv *resv)
-{
-	if (dma_resv_trylock(resv)) {
-		if (dma_resv_test_signaled(resv, true))
-			dma_resv_add_excl_fence(resv, NULL);
-		dma_resv_unlock(resv);
-	}
-}
diff --git a/drivers/gpu/drm/i915/dma_resv_utils.h b/drivers/gpu/drm/i915/dma_resv_utils.h
deleted file mode 100644
index b9d8fb5f8367..000000000000
--- a/drivers/gpu/drm/i915/dma_resv_utils.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2020 Intel Corporation
- */
-
-#ifndef DMA_RESV_UTILS_H
-#define DMA_RESV_UTILS_H
-
-struct dma_resv;
-
-void dma_resv_prune(struct dma_resv *resv);
-
-#endif /* DMA_RESV_UTILS_H */
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
index 5ab136ffdeb2..af3eb7fd951d 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
@@ -15,7 +15,6 @@
 
 #include "gt/intel_gt_requests.h"
 
-#include "dma_resv_utils.h"
 #include "i915_trace.h"
 
 static bool swap_available(void)
@@ -229,8 +228,6 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww,
 					i915_gem_object_unlock(obj);
 			}
 
-			dma_resv_prune(obj->base.resv);
-
 			scanned += obj->base.size >> PAGE_SHIFT;
 skip:
 			i915_gem_object_put(obj);
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_wait.c b/drivers/gpu/drm/i915/gem/i915_gem_wait.c
index 840c13706999..1592d95c3ead 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_wait.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_wait.c
@@ -10,7 +10,6 @@
 
 #include "gt/intel_engine.h"
 
-#include "dma_resv_utils.h"
 #include "i915_gem_ioctls.h"
 #include "i915_gem_object.h"
 
@@ -52,13 +51,6 @@ i915_gem_object_wait_reservation(struct dma_resv *resv,
 	}
 	dma_resv_iter_end(&cursor);
 
-	/*
-	 * Opportunistically prune the fences iff we know they have *all* been
-	 * signaled.
-	 */
-	if (timeout > 0)
-		dma_resv_prune(resv);
-
 	return ret;
 }
 
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 04/28] drm/i915: Remove unused bits of i915_vma/active api
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:35   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst, Niranjana Vishwanathapura

When reworking the code to move the eviction fence to the object,
the best code is removed code.

Remove some functions that are unused, and change the function definition
if it's only used in 1 place.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 drivers/gpu/drm/i915/i915_active.c | 28 +++-------------------------
 drivers/gpu/drm/i915/i915_active.h | 17 +----------------
 drivers/gpu/drm/i915/i915_vma.c    |  2 +-
 drivers/gpu/drm/i915/i915_vma.h    |  2 --
 4 files changed, 5 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c
index 3103c1e1fd14..ee2b3a375362 100644
--- a/drivers/gpu/drm/i915/i915_active.c
+++ b/drivers/gpu/drm/i915/i915_active.c
@@ -426,8 +426,9 @@ replace_barrier(struct i915_active *ref, struct i915_active_fence *active)
 	return true;
 }
 
-int i915_active_ref(struct i915_active *ref, u64 idx, struct dma_fence *fence)
+int i915_active_add_request(struct i915_active *ref, struct i915_request *rq)
 {
+	struct dma_fence *fence = &rq->fence;
 	struct i915_active_fence *active;
 	int err;
 
@@ -436,7 +437,7 @@ int i915_active_ref(struct i915_active *ref, u64 idx, struct dma_fence *fence)
 	if (err)
 		return err;
 
-	active = active_instance(ref, idx);
+	active = active_instance(ref, i915_request_timeline(rq)->fence_context);
 	if (!active) {
 		err = -ENOMEM;
 		goto out;
@@ -477,29 +478,6 @@ __i915_active_set_fence(struct i915_active *ref,
 	return prev;
 }
 
-static struct i915_active_fence *
-__active_fence(struct i915_active *ref, u64 idx)
-{
-	struct active_node *it;
-
-	it = __active_lookup(ref, idx);
-	if (unlikely(!it)) { /* Contention with parallel tree builders! */
-		spin_lock_irq(&ref->tree_lock);
-		it = __active_lookup(ref, idx);
-		spin_unlock_irq(&ref->tree_lock);
-	}
-	GEM_BUG_ON(!it); /* slot must be preallocated */
-
-	return &it->base;
-}
-
-struct dma_fence *
-__i915_active_ref(struct i915_active *ref, u64 idx, struct dma_fence *fence)
-{
-	/* Only valid while active, see i915_active_acquire_for_context() */
-	return __i915_active_set_fence(ref, __active_fence(ref, idx), fence);
-}
-
 struct dma_fence *
 i915_active_set_exclusive(struct i915_active *ref, struct dma_fence *f)
 {
diff --git a/drivers/gpu/drm/i915/i915_active.h b/drivers/gpu/drm/i915/i915_active.h
index 5fcdb0e2bc9e..7eb44132183a 100644
--- a/drivers/gpu/drm/i915/i915_active.h
+++ b/drivers/gpu/drm/i915/i915_active.h
@@ -164,26 +164,11 @@ void __i915_active_init(struct i915_active *ref,
 	__i915_active_init(ref, active, retire, flags, &__mkey, &__wkey);	\
 } while (0)
 
-struct dma_fence *
-__i915_active_ref(struct i915_active *ref, u64 idx, struct dma_fence *fence);
-int i915_active_ref(struct i915_active *ref, u64 idx, struct dma_fence *fence);
-
-static inline int
-i915_active_add_request(struct i915_active *ref, struct i915_request *rq)
-{
-	return i915_active_ref(ref,
-			       i915_request_timeline(rq)->fence_context,
-			       &rq->fence);
-}
+int i915_active_add_request(struct i915_active *ref, struct i915_request *rq);
 
 struct dma_fence *
 i915_active_set_exclusive(struct i915_active *ref, struct dma_fence *f);
 
-static inline bool i915_active_has_exclusive(struct i915_active *ref)
-{
-	return rcu_access_pointer(ref->excl.fence);
-}
-
 int __i915_active_wait(struct i915_active *ref, int state);
 static inline int i915_active_wait(struct i915_active *ref)
 {
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 90546fa58fc1..1187f1956c20 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -1220,7 +1220,7 @@ __i915_request_await_bind(struct i915_request *rq, struct i915_vma *vma)
 	return __i915_request_await_exclusive(rq, &vma->active);
 }
 
-int __i915_vma_move_to_active(struct i915_vma *vma, struct i915_request *rq)
+static int __i915_vma_move_to_active(struct i915_vma *vma, struct i915_request *rq)
 {
 	int err;
 
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 648dbe744c96..b882fd7b5f99 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -55,8 +55,6 @@ static inline bool i915_vma_is_active(const struct i915_vma *vma)
 /* do not reserve memory to prevent deadlocks */
 #define __EXEC_OBJECT_NO_RESERVE BIT(31)
 
-int __must_check __i915_vma_move_to_active(struct i915_vma *vma,
-					   struct i915_request *rq);
 int __must_check _i915_vma_move_to_active(struct i915_vma *vma,
 					  struct i915_request *rq,
 					  struct dma_fence *fence,
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 04/28] drm/i915: Remove unused bits of i915_vma/active api
@ 2021-10-21 10:35   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst, Niranjana Vishwanathapura

When reworking the code to move the eviction fence to the object,
the best code is removed code.

Remove some functions that are unused, and change the function definition
if it's only used in 1 place.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 drivers/gpu/drm/i915/i915_active.c | 28 +++-------------------------
 drivers/gpu/drm/i915/i915_active.h | 17 +----------------
 drivers/gpu/drm/i915/i915_vma.c    |  2 +-
 drivers/gpu/drm/i915/i915_vma.h    |  2 --
 4 files changed, 5 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c
index 3103c1e1fd14..ee2b3a375362 100644
--- a/drivers/gpu/drm/i915/i915_active.c
+++ b/drivers/gpu/drm/i915/i915_active.c
@@ -426,8 +426,9 @@ replace_barrier(struct i915_active *ref, struct i915_active_fence *active)
 	return true;
 }
 
-int i915_active_ref(struct i915_active *ref, u64 idx, struct dma_fence *fence)
+int i915_active_add_request(struct i915_active *ref, struct i915_request *rq)
 {
+	struct dma_fence *fence = &rq->fence;
 	struct i915_active_fence *active;
 	int err;
 
@@ -436,7 +437,7 @@ int i915_active_ref(struct i915_active *ref, u64 idx, struct dma_fence *fence)
 	if (err)
 		return err;
 
-	active = active_instance(ref, idx);
+	active = active_instance(ref, i915_request_timeline(rq)->fence_context);
 	if (!active) {
 		err = -ENOMEM;
 		goto out;
@@ -477,29 +478,6 @@ __i915_active_set_fence(struct i915_active *ref,
 	return prev;
 }
 
-static struct i915_active_fence *
-__active_fence(struct i915_active *ref, u64 idx)
-{
-	struct active_node *it;
-
-	it = __active_lookup(ref, idx);
-	if (unlikely(!it)) { /* Contention with parallel tree builders! */
-		spin_lock_irq(&ref->tree_lock);
-		it = __active_lookup(ref, idx);
-		spin_unlock_irq(&ref->tree_lock);
-	}
-	GEM_BUG_ON(!it); /* slot must be preallocated */
-
-	return &it->base;
-}
-
-struct dma_fence *
-__i915_active_ref(struct i915_active *ref, u64 idx, struct dma_fence *fence)
-{
-	/* Only valid while active, see i915_active_acquire_for_context() */
-	return __i915_active_set_fence(ref, __active_fence(ref, idx), fence);
-}
-
 struct dma_fence *
 i915_active_set_exclusive(struct i915_active *ref, struct dma_fence *f)
 {
diff --git a/drivers/gpu/drm/i915/i915_active.h b/drivers/gpu/drm/i915/i915_active.h
index 5fcdb0e2bc9e..7eb44132183a 100644
--- a/drivers/gpu/drm/i915/i915_active.h
+++ b/drivers/gpu/drm/i915/i915_active.h
@@ -164,26 +164,11 @@ void __i915_active_init(struct i915_active *ref,
 	__i915_active_init(ref, active, retire, flags, &__mkey, &__wkey);	\
 } while (0)
 
-struct dma_fence *
-__i915_active_ref(struct i915_active *ref, u64 idx, struct dma_fence *fence);
-int i915_active_ref(struct i915_active *ref, u64 idx, struct dma_fence *fence);
-
-static inline int
-i915_active_add_request(struct i915_active *ref, struct i915_request *rq)
-{
-	return i915_active_ref(ref,
-			       i915_request_timeline(rq)->fence_context,
-			       &rq->fence);
-}
+int i915_active_add_request(struct i915_active *ref, struct i915_request *rq);
 
 struct dma_fence *
 i915_active_set_exclusive(struct i915_active *ref, struct dma_fence *f);
 
-static inline bool i915_active_has_exclusive(struct i915_active *ref)
-{
-	return rcu_access_pointer(ref->excl.fence);
-}
-
 int __i915_active_wait(struct i915_active *ref, int state);
 static inline int i915_active_wait(struct i915_active *ref)
 {
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 90546fa58fc1..1187f1956c20 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -1220,7 +1220,7 @@ __i915_request_await_bind(struct i915_request *rq, struct i915_vma *vma)
 	return __i915_request_await_exclusive(rq, &vma->active);
 }
 
-int __i915_vma_move_to_active(struct i915_vma *vma, struct i915_request *rq)
+static int __i915_vma_move_to_active(struct i915_vma *vma, struct i915_request *rq)
 {
 	int err;
 
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 648dbe744c96..b882fd7b5f99 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -55,8 +55,6 @@ static inline bool i915_vma_is_active(const struct i915_vma *vma)
 /* do not reserve memory to prevent deadlocks */
 #define __EXEC_OBJECT_NO_RESERVE BIT(31)
 
-int __must_check __i915_vma_move_to_active(struct i915_vma *vma,
-					   struct i915_request *rq);
 int __must_check _i915_vma_move_to_active(struct i915_vma *vma,
 					  struct i915_request *rq,
 					  struct dma_fence *fence,
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 05/28] drm/i915: Slightly rework EXEC_OBJECT_CAPTURE handling, v2.
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:35   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst, Niranjana Vishwanathapura

Use a single null-terminated array for simplicity instead of a linked
list. This might slightly speed up execbuf when many vma's may be marked
as capture, but definitely removes an allocation from a signaling path.

We are not allowed to allocate memory in eb_move_to_gpu, but we can't
enforce it yet through annotations.

Changes since v1:
- Rebase on top of multi-batchbuffer changes.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> #v1
---
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 29 ++++++++++++-------
 drivers/gpu/drm/i915/i915_gpu_error.c         |  9 +++---
 drivers/gpu/drm/i915/i915_request.c           |  9 ++----
 drivers/gpu/drm/i915/i915_request.h           |  7 +----
 4 files changed, 26 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index 9c323666bd7c..eaacadd2d2e5 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -265,6 +265,9 @@ struct i915_execbuffer {
 	/* number of batches in execbuf IOCTL */
 	unsigned int num_batches;
 
+	/* Number of objects with EXEC_OBJECT_CAPTURE set */
+	unsigned int capture_count;
+
 	/** list of vma not yet bound during reservation phase */
 	struct list_head unbound;
 
@@ -909,6 +912,9 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb)
 			goto err;
 		}
 
+		if (eb->exec[i].flags & EXEC_OBJECT_CAPTURE)
+			eb->capture_count++;
+
 		err = eb_validate_vma(eb, &eb->exec[i], vma);
 		if (unlikely(err)) {
 			i915_vma_put(vma);
@@ -1906,19 +1912,11 @@ static int eb_move_to_gpu(struct i915_execbuffer *eb)
 		assert_vma_held(vma);
 
 		if (flags & EXEC_OBJECT_CAPTURE) {
-			struct i915_capture_list *capture;
+			eb->capture_count--;
 
 			for_each_batch_create_order(eb, j) {
-				if (!eb->requests[j])
-					break;
-
-				capture = kmalloc(sizeof(*capture), GFP_KERNEL);
-				if (capture) {
-					capture->next =
-						eb->requests[j]->capture_list;
-					capture->vma = vma;
-					eb->requests[j]->capture_list = capture;
-				}
+				if (eb->requests[j]->capture_list)
+					eb->requests[j]->capture_list[eb->capture_count] = vma;
 			}
 		}
 
@@ -3130,6 +3128,14 @@ eb_requests_create(struct i915_execbuffer *eb, struct dma_fence *in_fence,
 			return out_fence;
 		}
 
+		if (eb->capture_count) {
+			eb->requests[i]->capture_list =
+				kvcalloc(eb->capture_count + 1,
+					sizeof(*eb->requests[i]->capture_list),
+					GFP_KERNEL | __GFP_NOWARN);
+		}
+
+
 		/*
 		 * Only the first request added (committed to backend) has to
 		 * take the in fences into account as all subsequent requests
@@ -3197,6 +3203,7 @@ i915_gem_do_execbuffer(struct drm_device *dev,
 
 	eb.fences = NULL;
 	eb.num_fences = 0;
+	eb.capture_count = 0;
 
 	memset(eb.requests, 0, sizeof(struct i915_request *) *
 	       ARRAY_SIZE(eb.requests));
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 2a2d7643b551..45104bb12a98 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -1356,10 +1356,10 @@ capture_user(struct intel_engine_capture_vma *capture,
 	     const struct i915_request *rq,
 	     gfp_t gfp)
 {
-	struct i915_capture_list *c;
+	int i;
 
-	for (c = rq->capture_list; c; c = c->next)
-		capture = capture_vma(capture, c->vma, "user", gfp);
+	for (i = 0; rq->capture_list[i]; i++)
+		capture = capture_vma(capture, rq->capture_list[i], "user", gfp);
 
 	return capture;
 }
@@ -1407,7 +1407,8 @@ intel_engine_coredump_add_request(struct intel_engine_coredump *ee,
 	 * by userspace.
 	 */
 	vma = capture_vma(vma, rq->batch, "batch", gfp);
-	vma = capture_user(vma, rq, gfp);
+	if (rq->capture_list)
+		vma = capture_user(vma, rq, gfp);
 	vma = capture_vma(vma, rq->ring->vma, "ring", gfp);
 	vma = capture_vma(vma, rq->context->state, "HW context", gfp);
 
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index 42cd17357771..9b28e6f97c4b 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -188,15 +188,10 @@ void i915_request_notify_execute_cb_imm(struct i915_request *rq)
 
 static void free_capture_list(struct i915_request *request)
 {
-	struct i915_capture_list *capture;
+	struct i915_vma **capture;
 
 	capture = fetch_and_zero(&request->capture_list);
-	while (capture) {
-		struct i915_capture_list *next = capture->next;
-
-		kfree(capture);
-		capture = next;
-	}
+	kvfree(capture);
 }
 
 static void __i915_request_fill(struct i915_request *rq, u8 val)
diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h
index 3c6e8acd1457..2d04b25dca36 100644
--- a/drivers/gpu/drm/i915/i915_request.h
+++ b/drivers/gpu/drm/i915/i915_request.h
@@ -48,11 +48,6 @@ struct drm_i915_gem_object;
 struct drm_printer;
 struct i915_request;
 
-struct i915_capture_list {
-	struct i915_capture_list *next;
-	struct i915_vma *vma;
-};
-
 #define RQ_TRACE(rq, fmt, ...) do {					\
 	const struct i915_request *rq__ = (rq);				\
 	ENGINE_TRACE(rq__->engine, "fence %llx:%lld, current %d " fmt,	\
@@ -299,7 +294,7 @@ struct i915_request {
 	 * active reference - all objects on this list must also be
 	 * on the active_list (of their final request).
 	 */
-	struct i915_capture_list *capture_list;
+	struct i915_vma **capture_list;
 
 	/** Time at which this request was emitted, in jiffies. */
 	unsigned long emitted_jiffies;
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 05/28] drm/i915: Slightly rework EXEC_OBJECT_CAPTURE handling, v2.
@ 2021-10-21 10:35   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst, Niranjana Vishwanathapura

Use a single null-terminated array for simplicity instead of a linked
list. This might slightly speed up execbuf when many vma's may be marked
as capture, but definitely removes an allocation from a signaling path.

We are not allowed to allocate memory in eb_move_to_gpu, but we can't
enforce it yet through annotations.

Changes since v1:
- Rebase on top of multi-batchbuffer changes.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> #v1
---
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 29 ++++++++++++-------
 drivers/gpu/drm/i915/i915_gpu_error.c         |  9 +++---
 drivers/gpu/drm/i915/i915_request.c           |  9 ++----
 drivers/gpu/drm/i915/i915_request.h           |  7 +----
 4 files changed, 26 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index 9c323666bd7c..eaacadd2d2e5 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -265,6 +265,9 @@ struct i915_execbuffer {
 	/* number of batches in execbuf IOCTL */
 	unsigned int num_batches;
 
+	/* Number of objects with EXEC_OBJECT_CAPTURE set */
+	unsigned int capture_count;
+
 	/** list of vma not yet bound during reservation phase */
 	struct list_head unbound;
 
@@ -909,6 +912,9 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb)
 			goto err;
 		}
 
+		if (eb->exec[i].flags & EXEC_OBJECT_CAPTURE)
+			eb->capture_count++;
+
 		err = eb_validate_vma(eb, &eb->exec[i], vma);
 		if (unlikely(err)) {
 			i915_vma_put(vma);
@@ -1906,19 +1912,11 @@ static int eb_move_to_gpu(struct i915_execbuffer *eb)
 		assert_vma_held(vma);
 
 		if (flags & EXEC_OBJECT_CAPTURE) {
-			struct i915_capture_list *capture;
+			eb->capture_count--;
 
 			for_each_batch_create_order(eb, j) {
-				if (!eb->requests[j])
-					break;
-
-				capture = kmalloc(sizeof(*capture), GFP_KERNEL);
-				if (capture) {
-					capture->next =
-						eb->requests[j]->capture_list;
-					capture->vma = vma;
-					eb->requests[j]->capture_list = capture;
-				}
+				if (eb->requests[j]->capture_list)
+					eb->requests[j]->capture_list[eb->capture_count] = vma;
 			}
 		}
 
@@ -3130,6 +3128,14 @@ eb_requests_create(struct i915_execbuffer *eb, struct dma_fence *in_fence,
 			return out_fence;
 		}
 
+		if (eb->capture_count) {
+			eb->requests[i]->capture_list =
+				kvcalloc(eb->capture_count + 1,
+					sizeof(*eb->requests[i]->capture_list),
+					GFP_KERNEL | __GFP_NOWARN);
+		}
+
+
 		/*
 		 * Only the first request added (committed to backend) has to
 		 * take the in fences into account as all subsequent requests
@@ -3197,6 +3203,7 @@ i915_gem_do_execbuffer(struct drm_device *dev,
 
 	eb.fences = NULL;
 	eb.num_fences = 0;
+	eb.capture_count = 0;
 
 	memset(eb.requests, 0, sizeof(struct i915_request *) *
 	       ARRAY_SIZE(eb.requests));
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 2a2d7643b551..45104bb12a98 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -1356,10 +1356,10 @@ capture_user(struct intel_engine_capture_vma *capture,
 	     const struct i915_request *rq,
 	     gfp_t gfp)
 {
-	struct i915_capture_list *c;
+	int i;
 
-	for (c = rq->capture_list; c; c = c->next)
-		capture = capture_vma(capture, c->vma, "user", gfp);
+	for (i = 0; rq->capture_list[i]; i++)
+		capture = capture_vma(capture, rq->capture_list[i], "user", gfp);
 
 	return capture;
 }
@@ -1407,7 +1407,8 @@ intel_engine_coredump_add_request(struct intel_engine_coredump *ee,
 	 * by userspace.
 	 */
 	vma = capture_vma(vma, rq->batch, "batch", gfp);
-	vma = capture_user(vma, rq, gfp);
+	if (rq->capture_list)
+		vma = capture_user(vma, rq, gfp);
 	vma = capture_vma(vma, rq->ring->vma, "ring", gfp);
 	vma = capture_vma(vma, rq->context->state, "HW context", gfp);
 
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index 42cd17357771..9b28e6f97c4b 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -188,15 +188,10 @@ void i915_request_notify_execute_cb_imm(struct i915_request *rq)
 
 static void free_capture_list(struct i915_request *request)
 {
-	struct i915_capture_list *capture;
+	struct i915_vma **capture;
 
 	capture = fetch_and_zero(&request->capture_list);
-	while (capture) {
-		struct i915_capture_list *next = capture->next;
-
-		kfree(capture);
-		capture = next;
-	}
+	kvfree(capture);
 }
 
 static void __i915_request_fill(struct i915_request *rq, u8 val)
diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h
index 3c6e8acd1457..2d04b25dca36 100644
--- a/drivers/gpu/drm/i915/i915_request.h
+++ b/drivers/gpu/drm/i915/i915_request.h
@@ -48,11 +48,6 @@ struct drm_i915_gem_object;
 struct drm_printer;
 struct i915_request;
 
-struct i915_capture_list {
-	struct i915_capture_list *next;
-	struct i915_vma *vma;
-};
-
 #define RQ_TRACE(rq, fmt, ...) do {					\
 	const struct i915_request *rq__ = (rq);				\
 	ENGINE_TRACE(rq__->engine, "fence %llx:%lld, current %d " fmt,	\
@@ -299,7 +294,7 @@ struct i915_request {
 	 * active reference - all objects on this list must also be
 	 * on the active_list (of their final request).
 	 */
-	struct i915_capture_list *capture_list;
+	struct i915_vma **capture_list;
 
 	/** Time at which this request was emitted, in jiffies. */
 	unsigned long emitted_jiffies;
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 06/28] drm/i915: Remove gen6_ppgtt_unpin_all
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:35   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst, Matthew Auld

gen6_ppgtt_unpin_all is unused, kill it.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
---
 drivers/gpu/drm/i915/gt/gen6_ppgtt.c | 11 -----------
 drivers/gpu/drm/i915/gt/gen6_ppgtt.h |  1 -
 2 files changed, 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
index 890191f286e3..9fdbd9d3372b 100644
--- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
+++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
@@ -405,17 +405,6 @@ void gen6_ppgtt_unpin(struct i915_ppgtt *base)
 		i915_vma_unpin(ppgtt->vma);
 }
 
-void gen6_ppgtt_unpin_all(struct i915_ppgtt *base)
-{
-	struct gen6_ppgtt *ppgtt = to_gen6_ppgtt(base);
-
-	if (!atomic_read(&ppgtt->pin_count))
-		return;
-
-	i915_vma_unpin(ppgtt->vma);
-	atomic_set(&ppgtt->pin_count, 0);
-}
-
 struct i915_ppgtt *gen6_ppgtt_create(struct intel_gt *gt)
 {
 	struct i915_ggtt * const ggtt = gt->ggtt;
diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.h b/drivers/gpu/drm/i915/gt/gen6_ppgtt.h
index 6a61a5c3a85a..ab0eecb086dd 100644
--- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.h
+++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.h
@@ -71,7 +71,6 @@ static inline struct gen6_ppgtt *to_gen6_ppgtt(struct i915_ppgtt *base)
 
 int gen6_ppgtt_pin(struct i915_ppgtt *base, struct i915_gem_ww_ctx *ww);
 void gen6_ppgtt_unpin(struct i915_ppgtt *base);
-void gen6_ppgtt_unpin_all(struct i915_ppgtt *base);
 void gen6_ppgtt_enable(struct intel_gt *gt);
 void gen7_ppgtt_enable(struct intel_gt *gt);
 struct i915_ppgtt *gen6_ppgtt_create(struct intel_gt *gt);
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 06/28] drm/i915: Remove gen6_ppgtt_unpin_all
@ 2021-10-21 10:35   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst, Matthew Auld

gen6_ppgtt_unpin_all is unused, kill it.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
---
 drivers/gpu/drm/i915/gt/gen6_ppgtt.c | 11 -----------
 drivers/gpu/drm/i915/gt/gen6_ppgtt.h |  1 -
 2 files changed, 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
index 890191f286e3..9fdbd9d3372b 100644
--- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
+++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
@@ -405,17 +405,6 @@ void gen6_ppgtt_unpin(struct i915_ppgtt *base)
 		i915_vma_unpin(ppgtt->vma);
 }
 
-void gen6_ppgtt_unpin_all(struct i915_ppgtt *base)
-{
-	struct gen6_ppgtt *ppgtt = to_gen6_ppgtt(base);
-
-	if (!atomic_read(&ppgtt->pin_count))
-		return;
-
-	i915_vma_unpin(ppgtt->vma);
-	atomic_set(&ppgtt->pin_count, 0);
-}
-
 struct i915_ppgtt *gen6_ppgtt_create(struct intel_gt *gt)
 {
 	struct i915_ggtt * const ggtt = gt->ggtt;
diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.h b/drivers/gpu/drm/i915/gt/gen6_ppgtt.h
index 6a61a5c3a85a..ab0eecb086dd 100644
--- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.h
+++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.h
@@ -71,7 +71,6 @@ static inline struct gen6_ppgtt *to_gen6_ppgtt(struct i915_ppgtt *base)
 
 int gen6_ppgtt_pin(struct i915_ppgtt *base, struct i915_gem_ww_ctx *ww);
 void gen6_ppgtt_unpin(struct i915_ppgtt *base);
-void gen6_ppgtt_unpin_all(struct i915_ppgtt *base);
 void gen6_ppgtt_enable(struct intel_gt *gt);
 void gen7_ppgtt_enable(struct intel_gt *gt);
 struct i915_ppgtt *gen6_ppgtt_create(struct intel_gt *gt);
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 07/28] drm/i915: Create a dummy object for gen6 ppgtt
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:35   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

We currently have to special case vma->obj being NULL because
of gen6 ppgtt and mock_engine. Fix gen6 ppgtt, so we may soon
be able to remove a few checks. As the object only exists as
a fake object pointing to ggtt, we have no backing storage,
so no real object is created. It just has to look real enough.

Also kill pin_mutex, it's not compatible with ww locking,
and we can use the vm lock instead.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_internal.c |  44 ++++---
 drivers/gpu/drm/i915/gt/gen6_ppgtt.c         | 122 +++++++++++--------
 drivers/gpu/drm/i915/gt/gen6_ppgtt.h         |   1 -
 drivers/gpu/drm/i915/i915_drv.h              |   4 +
 4 files changed, 99 insertions(+), 72 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
index a57a6b7013c2..c5150a1ee3d2 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
@@ -145,24 +145,10 @@ static const struct drm_i915_gem_object_ops i915_gem_object_internal_ops = {
 	.put_pages = i915_gem_object_put_pages_internal,
 };
 
-/**
- * i915_gem_object_create_internal: create an object with volatile pages
- * @i915: the i915 device
- * @size: the size in bytes of backing storage to allocate for the object
- *
- * Creates a new object that wraps some internal memory for private use.
- * This object is not backed by swappable storage, and as such its contents
- * are volatile and only valid whilst pinned. If the object is reaped by the
- * shrinker, its pages and data will be discarded. Equally, it is not a full
- * GEM object and so not valid for access from userspace. This makes it useful
- * for hardware interfaces like ringbuffers (which are pinned from the time
- * the request is written to the time the hardware stops accessing it), but
- * not for contexts (which need to be preserved when not active for later
- * reuse). Note that it is not cleared upon allocation.
- */
 struct drm_i915_gem_object *
-i915_gem_object_create_internal(struct drm_i915_private *i915,
-				phys_addr_t size)
+__i915_gem_object_create_internal(struct drm_i915_private *i915,
+				  const struct drm_i915_gem_object_ops *ops,
+				  phys_addr_t size)
 {
 	static struct lock_class_key lock_class;
 	struct drm_i915_gem_object *obj;
@@ -179,7 +165,7 @@ i915_gem_object_create_internal(struct drm_i915_private *i915,
 		return ERR_PTR(-ENOMEM);
 
 	drm_gem_private_object_init(&i915->drm, &obj->base, size);
-	i915_gem_object_init(obj, &i915_gem_object_internal_ops, &lock_class, 0);
+	i915_gem_object_init(obj, ops, &lock_class, 0);
 	obj->mem_flags |= I915_BO_FLAG_STRUCT_PAGE;
 
 	/*
@@ -199,3 +185,25 @@ i915_gem_object_create_internal(struct drm_i915_private *i915,
 
 	return obj;
 }
+
+/**
+ * i915_gem_object_create_internal: create an object with volatile pages
+ * @i915: the i915 device
+ * @size: the size in bytes of backing storage to allocate for the object
+ *
+ * Creates a new object that wraps some internal memory for private use.
+ * This object is not backed by swappable storage, and as such its contents
+ * are volatile and only valid whilst pinned. If the object is reaped by the
+ * shrinker, its pages and data will be discarded. Equally, it is not a full
+ * GEM object and so not valid for access from userspace. This makes it useful
+ * for hardware interfaces like ringbuffers (which are pinned from the time
+ * the request is written to the time the hardware stops accessing it), but
+ * not for contexts (which need to be preserved when not active for later
+ * reuse). Note that it is not cleared upon allocation.
+ */
+struct drm_i915_gem_object *
+i915_gem_object_create_internal(struct drm_i915_private *i915,
+				phys_addr_t size)
+{
+	return __i915_gem_object_create_internal(i915, &i915_gem_object_internal_ops, size);
+}
diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
index 9fdbd9d3372b..5caa1703716e 100644
--- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
+++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
@@ -262,13 +262,10 @@ static void gen6_ppgtt_cleanup(struct i915_address_space *vm)
 {
 	struct gen6_ppgtt *ppgtt = to_gen6_ppgtt(i915_vm_to_ppgtt(vm));
 
-	__i915_vma_put(ppgtt->vma);
-
 	gen6_ppgtt_free_pd(ppgtt);
 	free_scratch(vm);
 
 	mutex_destroy(&ppgtt->flush);
-	mutex_destroy(&ppgtt->pin_mutex);
 
 	free_pd(&ppgtt->base.vm, ppgtt->base.pd);
 }
@@ -331,37 +328,6 @@ static const struct i915_vma_ops pd_vma_ops = {
 	.unbind_vma = pd_vma_unbind,
 };
 
-static struct i915_vma *pd_vma_create(struct gen6_ppgtt *ppgtt, int size)
-{
-	struct i915_ggtt *ggtt = ppgtt->base.vm.gt->ggtt;
-	struct i915_vma *vma;
-
-	GEM_BUG_ON(!IS_ALIGNED(size, I915_GTT_PAGE_SIZE));
-	GEM_BUG_ON(size > ggtt->vm.total);
-
-	vma = i915_vma_alloc();
-	if (!vma)
-		return ERR_PTR(-ENOMEM);
-
-	i915_active_init(&vma->active, NULL, NULL, 0);
-
-	kref_init(&vma->ref);
-	mutex_init(&vma->pages_mutex);
-	vma->vm = i915_vm_get(&ggtt->vm);
-	vma->ops = &pd_vma_ops;
-	vma->private = ppgtt;
-
-	vma->size = size;
-	vma->fence_size = size;
-	atomic_set(&vma->flags, I915_VMA_GGTT);
-	vma->ggtt_view.type = I915_GGTT_VIEW_ROTATED; /* prevent fencing */
-
-	INIT_LIST_HEAD(&vma->obj_link);
-	INIT_LIST_HEAD(&vma->closed_link);
-
-	return vma;
-}
-
 int gen6_ppgtt_pin(struct i915_ppgtt *base, struct i915_gem_ww_ctx *ww)
 {
 	struct gen6_ppgtt *ppgtt = to_gen6_ppgtt(base);
@@ -378,24 +344,84 @@ int gen6_ppgtt_pin(struct i915_ppgtt *base, struct i915_gem_ww_ctx *ww)
 	if (atomic_add_unless(&ppgtt->pin_count, 1, 0))
 		return 0;
 
-	if (mutex_lock_interruptible(&ppgtt->pin_mutex))
-		return -EINTR;
+	/* grab the ppgtt resv to pin the object */
+	err = i915_vm_lock_objects(&ppgtt->base.vm, ww);
+	if (err)
+		return err;
 
 	/*
 	 * PPGTT PDEs reside in the GGTT and consists of 512 entries. The
 	 * allocator works in address space sizes, so it's multiplied by page
 	 * size. We allocate at the top of the GTT to avoid fragmentation.
 	 */
-	err = 0;
-	if (!atomic_read(&ppgtt->pin_count))
+	if (!atomic_read(&ppgtt->pin_count)) {
 		err = i915_ggtt_pin(ppgtt->vma, ww, GEN6_PD_ALIGN, PIN_HIGH);
+
+		GEM_BUG_ON(ppgtt->vma->fence);
+		clear_bit(I915_VMA_CAN_FENCE_BIT, __i915_vma_flags(ppgtt->vma));
+	}
 	if (!err)
 		atomic_inc(&ppgtt->pin_count);
-	mutex_unlock(&ppgtt->pin_mutex);
 
 	return err;
 }
 
+static int pd_dummy_obj_get_pages(struct drm_i915_gem_object *obj)
+{
+	obj->mm.pages = ZERO_SIZE_PTR;
+	return 0;
+}
+
+static void pd_dummy_obj_put_pages(struct drm_i915_gem_object *obj,
+				     struct sg_table *pages)
+{
+}
+
+static const struct drm_i915_gem_object_ops pd_dummy_obj_ops = {
+	.name = "pd_dummy_obj",
+	.flags = I915_GEM_OBJECT_IS_SHRINKABLE,
+	.get_pages = pd_dummy_obj_get_pages,
+	.put_pages = pd_dummy_obj_put_pages,
+};
+
+static struct i915_page_directory *
+gen6_alloc_top_pd(struct gen6_ppgtt *ppgtt)
+{
+	struct i915_ggtt * const ggtt = ppgtt->base.vm.gt->ggtt;
+	struct i915_page_directory *pd;
+	int err;
+
+	pd = __alloc_pd(I915_PDES);
+	if (unlikely(!pd))
+		return ERR_PTR(-ENOMEM);
+
+	pd->pt.base = __i915_gem_object_create_internal(ppgtt->base.vm.gt->i915, &pd_dummy_obj_ops, I915_PDES * SZ_4K);
+	if (IS_ERR(pd->pt.base)) {
+		err = PTR_ERR(pd->pt.base);
+		pd->pt.base = NULL;
+		goto err_pd;
+	}
+
+	pd->pt.base->base.resv = i915_vm_resv_get(&ppgtt->base.vm);
+	pd->pt.base->shares_resv_from = &ppgtt->base.vm;
+
+	ppgtt->vma = i915_vma_instance(pd->pt.base, &ggtt->vm, NULL);
+	if (IS_ERR(ppgtt->vma)) {
+		err = PTR_ERR(ppgtt->vma);
+		ppgtt->vma = NULL;
+		goto err_pd;
+	}
+
+	/* The dummy object we create is special, override ops.. */
+	ppgtt->vma->ops = &pd_vma_ops;
+	ppgtt->vma->private = ppgtt;
+	return pd;
+
+err_pd:
+	free_pd(&ppgtt->base.vm, pd);
+	return ERR_PTR(err);
+}
+
 void gen6_ppgtt_unpin(struct i915_ppgtt *base)
 {
 	struct gen6_ppgtt *ppgtt = to_gen6_ppgtt(base);
@@ -416,7 +442,6 @@ struct i915_ppgtt *gen6_ppgtt_create(struct intel_gt *gt)
 		return ERR_PTR(-ENOMEM);
 
 	mutex_init(&ppgtt->flush);
-	mutex_init(&ppgtt->pin_mutex);
 
 	ppgtt_init(&ppgtt->base, gt, 0);
 	ppgtt->base.vm.pd_shift = ilog2(SZ_4K * SZ_4K / sizeof(gen6_pte_t));
@@ -431,19 +456,13 @@ struct i915_ppgtt *gen6_ppgtt_create(struct intel_gt *gt)
 	ppgtt->base.vm.alloc_pt_dma = alloc_pt_dma;
 	ppgtt->base.vm.pte_encode = ggtt->vm.pte_encode;
 
-	ppgtt->base.pd = __alloc_pd(I915_PDES);
-	if (!ppgtt->base.pd) {
-		err = -ENOMEM;
-		goto err_free;
-	}
-
 	err = gen6_ppgtt_init_scratch(ppgtt);
 	if (err)
-		goto err_pd;
+		goto err_free;
 
-	ppgtt->vma = pd_vma_create(ppgtt, GEN6_PD_SIZE);
-	if (IS_ERR(ppgtt->vma)) {
-		err = PTR_ERR(ppgtt->vma);
+	ppgtt->base.pd = gen6_alloc_top_pd(ppgtt);
+	if (IS_ERR(ppgtt->base.pd)) {
+		err = PTR_ERR(ppgtt->base.pd);
 		goto err_scratch;
 	}
 
@@ -451,10 +470,7 @@ struct i915_ppgtt *gen6_ppgtt_create(struct intel_gt *gt)
 
 err_scratch:
 	free_scratch(&ppgtt->base.vm);
-err_pd:
-	free_pd(&ppgtt->base.vm, ppgtt->base.pd);
 err_free:
-	mutex_destroy(&ppgtt->pin_mutex);
 	kfree(ppgtt);
 	return ERR_PTR(err);
 }
diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.h b/drivers/gpu/drm/i915/gt/gen6_ppgtt.h
index ab0eecb086dd..5e5cf2ec3309 100644
--- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.h
+++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.h
@@ -19,7 +19,6 @@ struct gen6_ppgtt {
 	u32 pp_dir;
 
 	atomic_t pin_count;
-	struct mutex pin_mutex;
 
 	bool scan_for_unused_pt;
 };
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 12256218634f..a8d733a7e1d9 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1933,6 +1933,10 @@ int i915_gem_evict_vm(struct i915_address_space *vm);
 struct drm_i915_gem_object *
 i915_gem_object_create_internal(struct drm_i915_private *dev_priv,
 				phys_addr_t size);
+struct drm_i915_gem_object *
+__i915_gem_object_create_internal(struct drm_i915_private *dev_priv,
+				  const struct drm_i915_gem_object_ops *ops,
+				  phys_addr_t size);
 
 /* i915_gem_tiling.c */
 static inline bool i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj)
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 07/28] drm/i915: Create a dummy object for gen6 ppgtt
@ 2021-10-21 10:35   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

We currently have to special case vma->obj being NULL because
of gen6 ppgtt and mock_engine. Fix gen6 ppgtt, so we may soon
be able to remove a few checks. As the object only exists as
a fake object pointing to ggtt, we have no backing storage,
so no real object is created. It just has to look real enough.

Also kill pin_mutex, it's not compatible with ww locking,
and we can use the vm lock instead.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_internal.c |  44 ++++---
 drivers/gpu/drm/i915/gt/gen6_ppgtt.c         | 122 +++++++++++--------
 drivers/gpu/drm/i915/gt/gen6_ppgtt.h         |   1 -
 drivers/gpu/drm/i915/i915_drv.h              |   4 +
 4 files changed, 99 insertions(+), 72 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
index a57a6b7013c2..c5150a1ee3d2 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
@@ -145,24 +145,10 @@ static const struct drm_i915_gem_object_ops i915_gem_object_internal_ops = {
 	.put_pages = i915_gem_object_put_pages_internal,
 };
 
-/**
- * i915_gem_object_create_internal: create an object with volatile pages
- * @i915: the i915 device
- * @size: the size in bytes of backing storage to allocate for the object
- *
- * Creates a new object that wraps some internal memory for private use.
- * This object is not backed by swappable storage, and as such its contents
- * are volatile and only valid whilst pinned. If the object is reaped by the
- * shrinker, its pages and data will be discarded. Equally, it is not a full
- * GEM object and so not valid for access from userspace. This makes it useful
- * for hardware interfaces like ringbuffers (which are pinned from the time
- * the request is written to the time the hardware stops accessing it), but
- * not for contexts (which need to be preserved when not active for later
- * reuse). Note that it is not cleared upon allocation.
- */
 struct drm_i915_gem_object *
-i915_gem_object_create_internal(struct drm_i915_private *i915,
-				phys_addr_t size)
+__i915_gem_object_create_internal(struct drm_i915_private *i915,
+				  const struct drm_i915_gem_object_ops *ops,
+				  phys_addr_t size)
 {
 	static struct lock_class_key lock_class;
 	struct drm_i915_gem_object *obj;
@@ -179,7 +165,7 @@ i915_gem_object_create_internal(struct drm_i915_private *i915,
 		return ERR_PTR(-ENOMEM);
 
 	drm_gem_private_object_init(&i915->drm, &obj->base, size);
-	i915_gem_object_init(obj, &i915_gem_object_internal_ops, &lock_class, 0);
+	i915_gem_object_init(obj, ops, &lock_class, 0);
 	obj->mem_flags |= I915_BO_FLAG_STRUCT_PAGE;
 
 	/*
@@ -199,3 +185,25 @@ i915_gem_object_create_internal(struct drm_i915_private *i915,
 
 	return obj;
 }
+
+/**
+ * i915_gem_object_create_internal: create an object with volatile pages
+ * @i915: the i915 device
+ * @size: the size in bytes of backing storage to allocate for the object
+ *
+ * Creates a new object that wraps some internal memory for private use.
+ * This object is not backed by swappable storage, and as such its contents
+ * are volatile and only valid whilst pinned. If the object is reaped by the
+ * shrinker, its pages and data will be discarded. Equally, it is not a full
+ * GEM object and so not valid for access from userspace. This makes it useful
+ * for hardware interfaces like ringbuffers (which are pinned from the time
+ * the request is written to the time the hardware stops accessing it), but
+ * not for contexts (which need to be preserved when not active for later
+ * reuse). Note that it is not cleared upon allocation.
+ */
+struct drm_i915_gem_object *
+i915_gem_object_create_internal(struct drm_i915_private *i915,
+				phys_addr_t size)
+{
+	return __i915_gem_object_create_internal(i915, &i915_gem_object_internal_ops, size);
+}
diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
index 9fdbd9d3372b..5caa1703716e 100644
--- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
+++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
@@ -262,13 +262,10 @@ static void gen6_ppgtt_cleanup(struct i915_address_space *vm)
 {
 	struct gen6_ppgtt *ppgtt = to_gen6_ppgtt(i915_vm_to_ppgtt(vm));
 
-	__i915_vma_put(ppgtt->vma);
-
 	gen6_ppgtt_free_pd(ppgtt);
 	free_scratch(vm);
 
 	mutex_destroy(&ppgtt->flush);
-	mutex_destroy(&ppgtt->pin_mutex);
 
 	free_pd(&ppgtt->base.vm, ppgtt->base.pd);
 }
@@ -331,37 +328,6 @@ static const struct i915_vma_ops pd_vma_ops = {
 	.unbind_vma = pd_vma_unbind,
 };
 
-static struct i915_vma *pd_vma_create(struct gen6_ppgtt *ppgtt, int size)
-{
-	struct i915_ggtt *ggtt = ppgtt->base.vm.gt->ggtt;
-	struct i915_vma *vma;
-
-	GEM_BUG_ON(!IS_ALIGNED(size, I915_GTT_PAGE_SIZE));
-	GEM_BUG_ON(size > ggtt->vm.total);
-
-	vma = i915_vma_alloc();
-	if (!vma)
-		return ERR_PTR(-ENOMEM);
-
-	i915_active_init(&vma->active, NULL, NULL, 0);
-
-	kref_init(&vma->ref);
-	mutex_init(&vma->pages_mutex);
-	vma->vm = i915_vm_get(&ggtt->vm);
-	vma->ops = &pd_vma_ops;
-	vma->private = ppgtt;
-
-	vma->size = size;
-	vma->fence_size = size;
-	atomic_set(&vma->flags, I915_VMA_GGTT);
-	vma->ggtt_view.type = I915_GGTT_VIEW_ROTATED; /* prevent fencing */
-
-	INIT_LIST_HEAD(&vma->obj_link);
-	INIT_LIST_HEAD(&vma->closed_link);
-
-	return vma;
-}
-
 int gen6_ppgtt_pin(struct i915_ppgtt *base, struct i915_gem_ww_ctx *ww)
 {
 	struct gen6_ppgtt *ppgtt = to_gen6_ppgtt(base);
@@ -378,24 +344,84 @@ int gen6_ppgtt_pin(struct i915_ppgtt *base, struct i915_gem_ww_ctx *ww)
 	if (atomic_add_unless(&ppgtt->pin_count, 1, 0))
 		return 0;
 
-	if (mutex_lock_interruptible(&ppgtt->pin_mutex))
-		return -EINTR;
+	/* grab the ppgtt resv to pin the object */
+	err = i915_vm_lock_objects(&ppgtt->base.vm, ww);
+	if (err)
+		return err;
 
 	/*
 	 * PPGTT PDEs reside in the GGTT and consists of 512 entries. The
 	 * allocator works in address space sizes, so it's multiplied by page
 	 * size. We allocate at the top of the GTT to avoid fragmentation.
 	 */
-	err = 0;
-	if (!atomic_read(&ppgtt->pin_count))
+	if (!atomic_read(&ppgtt->pin_count)) {
 		err = i915_ggtt_pin(ppgtt->vma, ww, GEN6_PD_ALIGN, PIN_HIGH);
+
+		GEM_BUG_ON(ppgtt->vma->fence);
+		clear_bit(I915_VMA_CAN_FENCE_BIT, __i915_vma_flags(ppgtt->vma));
+	}
 	if (!err)
 		atomic_inc(&ppgtt->pin_count);
-	mutex_unlock(&ppgtt->pin_mutex);
 
 	return err;
 }
 
+static int pd_dummy_obj_get_pages(struct drm_i915_gem_object *obj)
+{
+	obj->mm.pages = ZERO_SIZE_PTR;
+	return 0;
+}
+
+static void pd_dummy_obj_put_pages(struct drm_i915_gem_object *obj,
+				     struct sg_table *pages)
+{
+}
+
+static const struct drm_i915_gem_object_ops pd_dummy_obj_ops = {
+	.name = "pd_dummy_obj",
+	.flags = I915_GEM_OBJECT_IS_SHRINKABLE,
+	.get_pages = pd_dummy_obj_get_pages,
+	.put_pages = pd_dummy_obj_put_pages,
+};
+
+static struct i915_page_directory *
+gen6_alloc_top_pd(struct gen6_ppgtt *ppgtt)
+{
+	struct i915_ggtt * const ggtt = ppgtt->base.vm.gt->ggtt;
+	struct i915_page_directory *pd;
+	int err;
+
+	pd = __alloc_pd(I915_PDES);
+	if (unlikely(!pd))
+		return ERR_PTR(-ENOMEM);
+
+	pd->pt.base = __i915_gem_object_create_internal(ppgtt->base.vm.gt->i915, &pd_dummy_obj_ops, I915_PDES * SZ_4K);
+	if (IS_ERR(pd->pt.base)) {
+		err = PTR_ERR(pd->pt.base);
+		pd->pt.base = NULL;
+		goto err_pd;
+	}
+
+	pd->pt.base->base.resv = i915_vm_resv_get(&ppgtt->base.vm);
+	pd->pt.base->shares_resv_from = &ppgtt->base.vm;
+
+	ppgtt->vma = i915_vma_instance(pd->pt.base, &ggtt->vm, NULL);
+	if (IS_ERR(ppgtt->vma)) {
+		err = PTR_ERR(ppgtt->vma);
+		ppgtt->vma = NULL;
+		goto err_pd;
+	}
+
+	/* The dummy object we create is special, override ops.. */
+	ppgtt->vma->ops = &pd_vma_ops;
+	ppgtt->vma->private = ppgtt;
+	return pd;
+
+err_pd:
+	free_pd(&ppgtt->base.vm, pd);
+	return ERR_PTR(err);
+}
+
 void gen6_ppgtt_unpin(struct i915_ppgtt *base)
 {
 	struct gen6_ppgtt *ppgtt = to_gen6_ppgtt(base);
@@ -416,7 +442,6 @@ struct i915_ppgtt *gen6_ppgtt_create(struct intel_gt *gt)
 		return ERR_PTR(-ENOMEM);
 
 	mutex_init(&ppgtt->flush);
-	mutex_init(&ppgtt->pin_mutex);
 
 	ppgtt_init(&ppgtt->base, gt, 0);
 	ppgtt->base.vm.pd_shift = ilog2(SZ_4K * SZ_4K / sizeof(gen6_pte_t));
@@ -431,19 +456,13 @@ struct i915_ppgtt *gen6_ppgtt_create(struct intel_gt *gt)
 	ppgtt->base.vm.alloc_pt_dma = alloc_pt_dma;
 	ppgtt->base.vm.pte_encode = ggtt->vm.pte_encode;
 
-	ppgtt->base.pd = __alloc_pd(I915_PDES);
-	if (!ppgtt->base.pd) {
-		err = -ENOMEM;
-		goto err_free;
-	}
-
 	err = gen6_ppgtt_init_scratch(ppgtt);
 	if (err)
-		goto err_pd;
+		goto err_free;
 
-	ppgtt->vma = pd_vma_create(ppgtt, GEN6_PD_SIZE);
-	if (IS_ERR(ppgtt->vma)) {
-		err = PTR_ERR(ppgtt->vma);
+	ppgtt->base.pd = gen6_alloc_top_pd(ppgtt);
+	if (IS_ERR(ppgtt->base.pd)) {
+		err = PTR_ERR(ppgtt->base.pd);
 		goto err_scratch;
 	}
 
@@ -451,10 +470,7 @@ struct i915_ppgtt *gen6_ppgtt_create(struct intel_gt *gt)
 
 err_scratch:
 	free_scratch(&ppgtt->base.vm);
-err_pd:
-	free_pd(&ppgtt->base.vm, ppgtt->base.pd);
 err_free:
-	mutex_destroy(&ppgtt->pin_mutex);
 	kfree(ppgtt);
 	return ERR_PTR(err);
 }
diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.h b/drivers/gpu/drm/i915/gt/gen6_ppgtt.h
index ab0eecb086dd..5e5cf2ec3309 100644
--- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.h
+++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.h
@@ -19,7 +19,6 @@ struct gen6_ppgtt {
 	u32 pp_dir;
 
 	atomic_t pin_count;
-	struct mutex pin_mutex;
 
 	bool scan_for_unused_pt;
 };
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 12256218634f..a8d733a7e1d9 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1933,6 +1933,10 @@ int i915_gem_evict_vm(struct i915_address_space *vm);
 struct drm_i915_gem_object *
 i915_gem_object_create_internal(struct drm_i915_private *dev_priv,
 				phys_addr_t size);
+struct drm_i915_gem_object *
+__i915_gem_object_create_internal(struct drm_i915_private *dev_priv,
+				  const struct drm_i915_gem_object_ops *ops,
+				  phys_addr_t size);
 
 /* i915_gem_tiling.c */
 static inline bool i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj)
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 08/28] drm/i915: Create a full object for mock_ring, v2.
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:35   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

This allows us to finally get rid of all the assumptions that vma->obj is NULL.

Changes since v1:
- Ensure the mock_ring vma is pinned to prevent a fault.
- Pin it high to avoid failure in evict_for_vma selftest.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/gt/mock_engine.c | 38 ++++++++++++++++++++-------
 1 file changed, 28 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/mock_engine.c b/drivers/gpu/drm/i915/gt/mock_engine.c
index 8b89215afe46..bb99fc03f503 100644
--- a/drivers/gpu/drm/i915/gt/mock_engine.c
+++ b/drivers/gpu/drm/i915/gt/mock_engine.c
@@ -35,9 +35,31 @@ static void mock_timeline_unpin(struct intel_timeline *tl)
 	atomic_dec(&tl->pin_count);
 }
 
+static struct i915_vma *create_ring_vma(struct i915_ggtt *ggtt, int size)
+{
+	struct i915_address_space *vm = &ggtt->vm;
+	struct drm_i915_private *i915 = vm->i915;
+	struct drm_i915_gem_object *obj;
+	struct i915_vma *vma;
+
+	obj = i915_gem_object_create_internal(i915, size);
+	if (IS_ERR(obj))
+		return ERR_CAST(obj);
+
+	vma = i915_vma_instance(obj, vm, NULL);
+	if (IS_ERR(vma))
+		goto err;
+
+	return vma;
+
+err:
+	i915_gem_object_put(obj);
+	return vma;
+}
+
 static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
 {
-	const unsigned long sz = PAGE_SIZE / 2;
+	const unsigned long sz = PAGE_SIZE;
 	struct intel_ring *ring;
 
 	ring = kzalloc(sizeof(*ring) + sz, GFP_KERNEL);
@@ -50,15 +72,11 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
 	ring->vaddr = (void *)(ring + 1);
 	atomic_set(&ring->pin_count, 1);
 
-	ring->vma = i915_vma_alloc();
-	if (!ring->vma) {
+	ring->vma = create_ring_vma(engine->gt->ggtt, PAGE_SIZE);
+	if (IS_ERR(ring->vma)) {
 		kfree(ring);
 		return NULL;
 	}
-	i915_active_init(&ring->vma->active, NULL, NULL, 0);
-	__set_bit(I915_VMA_GGTT_BIT, __i915_vma_flags(ring->vma));
-	__set_bit(DRM_MM_NODE_ALLOCATED_BIT, &ring->vma->node.flags);
-	ring->vma->node.size = sz;
 
 	intel_ring_update_space(ring);
 
@@ -67,8 +85,7 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
 
 static void mock_ring_free(struct intel_ring *ring)
 {
-	i915_active_fini(&ring->vma->active);
-	i915_vma_free(ring->vma);
+	i915_vma_put(ring->vma);
 
 	kfree(ring);
 }
@@ -125,6 +142,7 @@ static void mock_context_unpin(struct intel_context *ce)
 
 static void mock_context_post_unpin(struct intel_context *ce)
 {
+	i915_vma_unpin(ce->ring->vma);
 }
 
 static void mock_context_destroy(struct kref *ref)
@@ -169,7 +187,7 @@ static int mock_context_alloc(struct intel_context *ce)
 static int mock_context_pre_pin(struct intel_context *ce,
 				struct i915_gem_ww_ctx *ww, void **unused)
 {
-	return 0;
+	return i915_vma_pin_ww(ce->ring->vma, ww, 0, 0, PIN_GLOBAL | PIN_HIGH);
 }
 
 static int mock_context_pin(struct intel_context *ce, void *unused)
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 08/28] drm/i915: Create a full object for mock_ring, v2.
@ 2021-10-21 10:35   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

This allows us to finally get rid of all the assumptions that vma->obj is NULL.

Changes since v1:
- Ensure the mock_ring vma is pinned to prevent a fault.
- Pin it high to avoid failure in evict_for_vma selftest.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/gt/mock_engine.c | 38 ++++++++++++++++++++-------
 1 file changed, 28 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/mock_engine.c b/drivers/gpu/drm/i915/gt/mock_engine.c
index 8b89215afe46..bb99fc03f503 100644
--- a/drivers/gpu/drm/i915/gt/mock_engine.c
+++ b/drivers/gpu/drm/i915/gt/mock_engine.c
@@ -35,9 +35,31 @@ static void mock_timeline_unpin(struct intel_timeline *tl)
 	atomic_dec(&tl->pin_count);
 }
 
+static struct i915_vma *create_ring_vma(struct i915_ggtt *ggtt, int size)
+{
+	struct i915_address_space *vm = &ggtt->vm;
+	struct drm_i915_private *i915 = vm->i915;
+	struct drm_i915_gem_object *obj;
+	struct i915_vma *vma;
+
+	obj = i915_gem_object_create_internal(i915, size);
+	if (IS_ERR(obj))
+		return ERR_CAST(obj);
+
+	vma = i915_vma_instance(obj, vm, NULL);
+	if (IS_ERR(vma))
+		goto err;
+
+	return vma;
+
+err:
+	i915_gem_object_put(obj);
+	return vma;
+}
+
 static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
 {
-	const unsigned long sz = PAGE_SIZE / 2;
+	const unsigned long sz = PAGE_SIZE;
 	struct intel_ring *ring;
 
 	ring = kzalloc(sizeof(*ring) + sz, GFP_KERNEL);
@@ -50,15 +72,11 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
 	ring->vaddr = (void *)(ring + 1);
 	atomic_set(&ring->pin_count, 1);
 
-	ring->vma = i915_vma_alloc();
-	if (!ring->vma) {
+	ring->vma = create_ring_vma(engine->gt->ggtt, PAGE_SIZE);
+	if (IS_ERR(ring->vma)) {
 		kfree(ring);
 		return NULL;
 	}
-	i915_active_init(&ring->vma->active, NULL, NULL, 0);
-	__set_bit(I915_VMA_GGTT_BIT, __i915_vma_flags(ring->vma));
-	__set_bit(DRM_MM_NODE_ALLOCATED_BIT, &ring->vma->node.flags);
-	ring->vma->node.size = sz;
 
 	intel_ring_update_space(ring);
 
@@ -67,8 +85,7 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
 
 static void mock_ring_free(struct intel_ring *ring)
 {
-	i915_active_fini(&ring->vma->active);
-	i915_vma_free(ring->vma);
+	i915_vma_put(ring->vma);
 
 	kfree(ring);
 }
@@ -125,6 +142,7 @@ static void mock_context_unpin(struct intel_context *ce)
 
 static void mock_context_post_unpin(struct intel_context *ce)
 {
+	i915_vma_unpin(ce->ring->vma);
 }
 
 static void mock_context_destroy(struct kref *ref)
@@ -169,7 +187,7 @@ static int mock_context_alloc(struct intel_context *ce)
 static int mock_context_pre_pin(struct intel_context *ce,
 				struct i915_gem_ww_ctx *ww, void **unused)
 {
-	return 0;
+	return i915_vma_pin_ww(ce->ring->vma, ww, 0, 0, PIN_GLOBAL | PIN_HIGH);
 }
 
 static int mock_context_pin(struct intel_context *ce, void *unused)
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 09/28] drm/i915: vma is always backed by an object.
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:35   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

vma->obj and vma->resv are now never NULL, and some checks can be removed.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/gt/intel_context.c       |  2 +-
 .../gpu/drm/i915/gt/intel_ring_submission.c   |  2 +-
 drivers/gpu/drm/i915/i915_vma.c               | 48 ++++++++-----------
 drivers/gpu/drm/i915/i915_vma.h               |  3 --
 4 files changed, 22 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c
index 5634d14052bc..e0220ac0e9b6 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -219,7 +219,7 @@ int __intel_context_do_pin_ww(struct intel_context *ce,
 	 */
 
 	err = i915_gem_object_lock(ce->timeline->hwsp_ggtt->obj, ww);
-	if (!err && ce->ring->vma->obj)
+	if (!err)
 		err = i915_gem_object_lock(ce->ring->vma->obj, ww);
 	if (!err && ce->state)
 		err = i915_gem_object_lock(ce->state->obj, ww);
diff --git a/drivers/gpu/drm/i915/gt/intel_ring_submission.c b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
index 586dca1731ce..3e6fac0340ef 100644
--- a/drivers/gpu/drm/i915/gt/intel_ring_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
@@ -1357,7 +1357,7 @@ int intel_ring_submission_setup(struct intel_engine_cs *engine)
 	err = i915_gem_object_lock(timeline->hwsp_ggtt->obj, &ww);
 	if (!err && gen7_wa_vma)
 		err = i915_gem_object_lock(gen7_wa_vma->obj, &ww);
-	if (!err && engine->legacy.ring->vma->obj)
+	if (!err)
 		err = i915_gem_object_lock(engine->legacy.ring->vma->obj, &ww);
 	if (!err)
 		err = intel_timeline_pin(timeline, &ww);
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 1187f1956c20..aebfc232b58b 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -40,12 +40,12 @@
 
 static struct kmem_cache *slab_vmas;
 
-struct i915_vma *i915_vma_alloc(void)
+static struct i915_vma *i915_vma_alloc(void)
 {
 	return kmem_cache_zalloc(slab_vmas, GFP_KERNEL);
 }
 
-void i915_vma_free(struct i915_vma *vma)
+static void i915_vma_free(struct i915_vma *vma)
 {
 	return kmem_cache_free(slab_vmas, vma);
 }
@@ -426,10 +426,8 @@ int i915_vma_bind(struct i915_vma *vma,
 
 		work->base.dma.error = 0; /* enable the queue_work() */
 
-		if (vma->obj) {
-			__i915_gem_object_pin_pages(vma->obj);
-			work->pinned = i915_gem_object_get(vma->obj);
-		}
+		__i915_gem_object_pin_pages(vma->obj);
+		work->pinned = i915_gem_object_get(vma->obj);
 	} else {
 		vma->ops->bind_vma(vma->vm, NULL, vma, cache_level, bind_flags);
 	}
@@ -670,7 +668,7 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
 	}
 
 	color = 0;
-	if (vma->obj && i915_vm_has_cache_coloring(vma->vm))
+	if (i915_vm_has_cache_coloring(vma->vm))
 		color = vma->obj->cache_level;
 
 	if (flags & PIN_OFFSET_FIXED) {
@@ -795,17 +793,14 @@ static bool try_qad_pin(struct i915_vma *vma, unsigned int flags)
 static int vma_get_pages(struct i915_vma *vma)
 {
 	int err = 0;
-	bool pinned_pages = false;
+	bool pinned_pages = true;
 
 	if (atomic_add_unless(&vma->pages_count, 1, 0))
 		return 0;
 
-	if (vma->obj) {
-		err = i915_gem_object_pin_pages(vma->obj);
-		if (err)
-			return err;
-		pinned_pages = true;
-	}
+	err = i915_gem_object_pin_pages(vma->obj);
+	if (err)
+		return err;
 
 	/* Allocations ahoy! */
 	if (mutex_lock_interruptible(&vma->pages_mutex)) {
@@ -838,8 +833,8 @@ static void __vma_put_pages(struct i915_vma *vma, unsigned int count)
 	if (atomic_sub_return(count, &vma->pages_count) == 0) {
 		vma->ops->clear_pages(vma);
 		GEM_BUG_ON(vma->pages);
-		if (vma->obj)
-			i915_gem_object_unpin_pages(vma->obj);
+
+		i915_gem_object_unpin_pages(vma->obj);
 	}
 	mutex_unlock(&vma->pages_mutex);
 }
@@ -875,7 +870,7 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 	int err;
 
 #ifdef CONFIG_PROVE_LOCKING
-	if (debug_locks && !WARN_ON(!ww) && vma->resv)
+	if (debug_locks && !WARN_ON(!ww))
 		assert_vma_held(vma);
 #endif
 
@@ -983,7 +978,7 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 
 	GEM_BUG_ON(!vma->pages);
 	err = i915_vma_bind(vma,
-			    vma->obj ? vma->obj->cache_level : 0,
+			    vma->obj->cache_level,
 			    flags, work);
 	if (err)
 		goto err_remove;
@@ -1037,7 +1032,7 @@ int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 	GEM_BUG_ON(!i915_vma_is_ggtt(vma));
 
 #ifdef CONFIG_LOCKDEP
-	WARN_ON(!ww && vma->resv && dma_resv_held(vma->resv));
+	WARN_ON(!ww && dma_resv_held(vma->resv));
 #endif
 
 	do {
@@ -1116,6 +1111,7 @@ void i915_vma_reopen(struct i915_vma *vma)
 void i915_vma_release(struct kref *ref)
 {
 	struct i915_vma *vma = container_of(ref, typeof(*vma), ref);
+	struct drm_i915_gem_object *obj = vma->obj;
 
 	if (drm_mm_node_allocated(&vma->node)) {
 		mutex_lock(&vma->vm->mutex);
@@ -1126,15 +1122,11 @@ void i915_vma_release(struct kref *ref)
 	}
 	GEM_BUG_ON(i915_vma_is_active(vma));
 
-	if (vma->obj) {
-		struct drm_i915_gem_object *obj = vma->obj;
-
-		spin_lock(&obj->vma.lock);
-		list_del(&vma->obj_link);
-		if (!RB_EMPTY_NODE(&vma->obj_node))
-			rb_erase(&vma->obj_node, &obj->vma.tree);
-		spin_unlock(&obj->vma.lock);
-	}
+	spin_lock(&obj->vma.lock);
+	list_del(&vma->obj_link);
+	if (!RB_EMPTY_NODE(&vma->obj_node))
+		rb_erase(&vma->obj_node, &obj->vma.tree);
+	spin_unlock(&obj->vma.lock);
 
 	__i915_vma_remove_closed(vma);
 	i915_vm_put(vma->vm);
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index b882fd7b5f99..423e0df81c87 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -416,9 +416,6 @@ static inline void i915_vma_clear_scanout(struct i915_vma *vma)
 	list_for_each_entry(V, &(OBJ)->vma.list, obj_link)		\
 		for_each_until(!i915_vma_is_ggtt(V))
 
-struct i915_vma *i915_vma_alloc(void);
-void i915_vma_free(struct i915_vma *vma);
-
 struct i915_vma *i915_vma_make_unshrinkable(struct i915_vma *vma);
 void i915_vma_make_shrinkable(struct i915_vma *vma);
 void i915_vma_make_purgeable(struct i915_vma *vma);
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 09/28] drm/i915: vma is always backed by an object.
@ 2021-10-21 10:35   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

vma->obj and vma->resv are now never NULL, and some checks can be removed.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/gt/intel_context.c       |  2 +-
 .../gpu/drm/i915/gt/intel_ring_submission.c   |  2 +-
 drivers/gpu/drm/i915/i915_vma.c               | 48 ++++++++-----------
 drivers/gpu/drm/i915/i915_vma.h               |  3 --
 4 files changed, 22 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c
index 5634d14052bc..e0220ac0e9b6 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -219,7 +219,7 @@ int __intel_context_do_pin_ww(struct intel_context *ce,
 	 */
 
 	err = i915_gem_object_lock(ce->timeline->hwsp_ggtt->obj, ww);
-	if (!err && ce->ring->vma->obj)
+	if (!err)
 		err = i915_gem_object_lock(ce->ring->vma->obj, ww);
 	if (!err && ce->state)
 		err = i915_gem_object_lock(ce->state->obj, ww);
diff --git a/drivers/gpu/drm/i915/gt/intel_ring_submission.c b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
index 586dca1731ce..3e6fac0340ef 100644
--- a/drivers/gpu/drm/i915/gt/intel_ring_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
@@ -1357,7 +1357,7 @@ int intel_ring_submission_setup(struct intel_engine_cs *engine)
 	err = i915_gem_object_lock(timeline->hwsp_ggtt->obj, &ww);
 	if (!err && gen7_wa_vma)
 		err = i915_gem_object_lock(gen7_wa_vma->obj, &ww);
-	if (!err && engine->legacy.ring->vma->obj)
+	if (!err)
 		err = i915_gem_object_lock(engine->legacy.ring->vma->obj, &ww);
 	if (!err)
 		err = intel_timeline_pin(timeline, &ww);
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 1187f1956c20..aebfc232b58b 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -40,12 +40,12 @@
 
 static struct kmem_cache *slab_vmas;
 
-struct i915_vma *i915_vma_alloc(void)
+static struct i915_vma *i915_vma_alloc(void)
 {
 	return kmem_cache_zalloc(slab_vmas, GFP_KERNEL);
 }
 
-void i915_vma_free(struct i915_vma *vma)
+static void i915_vma_free(struct i915_vma *vma)
 {
 	return kmem_cache_free(slab_vmas, vma);
 }
@@ -426,10 +426,8 @@ int i915_vma_bind(struct i915_vma *vma,
 
 		work->base.dma.error = 0; /* enable the queue_work() */
 
-		if (vma->obj) {
-			__i915_gem_object_pin_pages(vma->obj);
-			work->pinned = i915_gem_object_get(vma->obj);
-		}
+		__i915_gem_object_pin_pages(vma->obj);
+		work->pinned = i915_gem_object_get(vma->obj);
 	} else {
 		vma->ops->bind_vma(vma->vm, NULL, vma, cache_level, bind_flags);
 	}
@@ -670,7 +668,7 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
 	}
 
 	color = 0;
-	if (vma->obj && i915_vm_has_cache_coloring(vma->vm))
+	if (i915_vm_has_cache_coloring(vma->vm))
 		color = vma->obj->cache_level;
 
 	if (flags & PIN_OFFSET_FIXED) {
@@ -795,17 +793,14 @@ static bool try_qad_pin(struct i915_vma *vma, unsigned int flags)
 static int vma_get_pages(struct i915_vma *vma)
 {
 	int err = 0;
-	bool pinned_pages = false;
+	bool pinned_pages = true;
 
 	if (atomic_add_unless(&vma->pages_count, 1, 0))
 		return 0;
 
-	if (vma->obj) {
-		err = i915_gem_object_pin_pages(vma->obj);
-		if (err)
-			return err;
-		pinned_pages = true;
-	}
+	err = i915_gem_object_pin_pages(vma->obj);
+	if (err)
+		return err;
 
 	/* Allocations ahoy! */
 	if (mutex_lock_interruptible(&vma->pages_mutex)) {
@@ -838,8 +833,8 @@ static void __vma_put_pages(struct i915_vma *vma, unsigned int count)
 	if (atomic_sub_return(count, &vma->pages_count) == 0) {
 		vma->ops->clear_pages(vma);
 		GEM_BUG_ON(vma->pages);
-		if (vma->obj)
-			i915_gem_object_unpin_pages(vma->obj);
+
+		i915_gem_object_unpin_pages(vma->obj);
 	}
 	mutex_unlock(&vma->pages_mutex);
 }
@@ -875,7 +870,7 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 	int err;
 
 #ifdef CONFIG_PROVE_LOCKING
-	if (debug_locks && !WARN_ON(!ww) && vma->resv)
+	if (debug_locks && !WARN_ON(!ww))
 		assert_vma_held(vma);
 #endif
 
@@ -983,7 +978,7 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 
 	GEM_BUG_ON(!vma->pages);
 	err = i915_vma_bind(vma,
-			    vma->obj ? vma->obj->cache_level : 0,
+			    vma->obj->cache_level,
 			    flags, work);
 	if (err)
 		goto err_remove;
@@ -1037,7 +1032,7 @@ int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 	GEM_BUG_ON(!i915_vma_is_ggtt(vma));
 
 #ifdef CONFIG_LOCKDEP
-	WARN_ON(!ww && vma->resv && dma_resv_held(vma->resv));
+	WARN_ON(!ww && dma_resv_held(vma->resv));
 #endif
 
 	do {
@@ -1116,6 +1111,7 @@ void i915_vma_reopen(struct i915_vma *vma)
 void i915_vma_release(struct kref *ref)
 {
 	struct i915_vma *vma = container_of(ref, typeof(*vma), ref);
+	struct drm_i915_gem_object *obj = vma->obj;
 
 	if (drm_mm_node_allocated(&vma->node)) {
 		mutex_lock(&vma->vm->mutex);
@@ -1126,15 +1122,11 @@ void i915_vma_release(struct kref *ref)
 	}
 	GEM_BUG_ON(i915_vma_is_active(vma));
 
-	if (vma->obj) {
-		struct drm_i915_gem_object *obj = vma->obj;
-
-		spin_lock(&obj->vma.lock);
-		list_del(&vma->obj_link);
-		if (!RB_EMPTY_NODE(&vma->obj_node))
-			rb_erase(&vma->obj_node, &obj->vma.tree);
-		spin_unlock(&obj->vma.lock);
-	}
+	spin_lock(&obj->vma.lock);
+	list_del(&vma->obj_link);
+	if (!RB_EMPTY_NODE(&vma->obj_node))
+		rb_erase(&vma->obj_node, &obj->vma.tree);
+	spin_unlock(&obj->vma.lock);
 
 	__i915_vma_remove_closed(vma);
 	i915_vm_put(vma->vm);
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index b882fd7b5f99..423e0df81c87 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -416,9 +416,6 @@ static inline void i915_vma_clear_scanout(struct i915_vma *vma)
 	list_for_each_entry(V, &(OBJ)->vma.list, obj_link)		\
 		for_each_until(!i915_vma_is_ggtt(V))
 
-struct i915_vma *i915_vma_alloc(void);
-void i915_vma_free(struct i915_vma *vma);
-
 struct i915_vma *i915_vma_make_unshrinkable(struct i915_vma *vma);
 void i915_vma_make_shrinkable(struct i915_vma *vma);
 void i915_vma_make_purgeable(struct i915_vma *vma);
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 10/28] drm/i915: Change shrink ordering to use locking around unbinding.
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:35   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst, Niranjana Vishwanathapura

Call drop_pages with the gem object lock held, instead of the other
way around. This will allow us to drop the vma bindings with the
gem object lock held.

We plan to require the object lock for unpinning in the future,
and this is an easy target.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_shrinker.c | 42 ++++++++++----------
 1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
index af3eb7fd951d..d3f29a66cb36 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
@@ -36,8 +36,8 @@ static bool can_release_pages(struct drm_i915_gem_object *obj)
 	return swap_available() || obj->mm.madv == I915_MADV_DONTNEED;
 }
 
-static bool unsafe_drop_pages(struct drm_i915_gem_object *obj,
-			      unsigned long shrink, bool trylock_vm)
+static int drop_pages(struct drm_i915_gem_object *obj,
+		       unsigned long shrink, bool trylock_vm)
 {
 	unsigned long flags;
 
@@ -208,26 +208,28 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww,
 
 			spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
 
-			err = 0;
-			if (unsafe_drop_pages(obj, shrink, trylock_vm)) {
-				/* May arrive from get_pages on another bo */
-				if (!ww) {
-					if (!i915_gem_object_trylock(obj))
-						goto skip;
-				} else {
-					err = i915_gem_object_lock(obj, ww);
-					if (err)
-						goto skip;
-				}
-
-				if (!__i915_gem_object_put_pages(obj)) {
-					try_to_writeback(obj, shrink);
-					count += obj->base.size >> PAGE_SHIFT;
-				}
-				if (!ww)
-					i915_gem_object_unlock(obj);
+			/* May arrive from get_pages on another bo */
+			if (!ww) {
+				if (!i915_gem_object_trylock(obj))
+					goto skip;
+			} else {
+				err = i915_gem_object_lock(obj, ww);
+				if (err)
+					goto skip;
 			}
 
+			if (drop_pages(obj, shrink, trylock_vm) &&
+			    !__i915_gem_object_put_pages(obj)) {
+				try_to_writeback(obj, shrink);
+				count += obj->base.size >> PAGE_SHIFT;
+			}
+
+			if (dma_resv_test_signaled(obj->base.resv, true))
+				dma_resv_add_excl_fence(obj->base.resv, NULL);
+
+			if (!ww)
+				i915_gem_object_unlock(obj);
+
 			scanned += obj->base.size >> PAGE_SHIFT;
 skip:
 			i915_gem_object_put(obj);
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 10/28] drm/i915: Change shrink ordering to use locking around unbinding.
@ 2021-10-21 10:35   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst, Niranjana Vishwanathapura

Call drop_pages with the gem object lock held, instead of the other
way around. This will allow us to drop the vma bindings with the
gem object lock held.

We plan to require the object lock for unpinning in the future,
and this is an easy target.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_shrinker.c | 42 ++++++++++----------
 1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
index af3eb7fd951d..d3f29a66cb36 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
@@ -36,8 +36,8 @@ static bool can_release_pages(struct drm_i915_gem_object *obj)
 	return swap_available() || obj->mm.madv == I915_MADV_DONTNEED;
 }
 
-static bool unsafe_drop_pages(struct drm_i915_gem_object *obj,
-			      unsigned long shrink, bool trylock_vm)
+static int drop_pages(struct drm_i915_gem_object *obj,
+		       unsigned long shrink, bool trylock_vm)
 {
 	unsigned long flags;
 
@@ -208,26 +208,28 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww,
 
 			spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
 
-			err = 0;
-			if (unsafe_drop_pages(obj, shrink, trylock_vm)) {
-				/* May arrive from get_pages on another bo */
-				if (!ww) {
-					if (!i915_gem_object_trylock(obj))
-						goto skip;
-				} else {
-					err = i915_gem_object_lock(obj, ww);
-					if (err)
-						goto skip;
-				}
-
-				if (!__i915_gem_object_put_pages(obj)) {
-					try_to_writeback(obj, shrink);
-					count += obj->base.size >> PAGE_SHIFT;
-				}
-				if (!ww)
-					i915_gem_object_unlock(obj);
+			/* May arrive from get_pages on another bo */
+			if (!ww) {
+				if (!i915_gem_object_trylock(obj))
+					goto skip;
+			} else {
+				err = i915_gem_object_lock(obj, ww);
+				if (err)
+					goto skip;
 			}
 
+			if (drop_pages(obj, shrink, trylock_vm) &&
+			    !__i915_gem_object_put_pages(obj)) {
+				try_to_writeback(obj, shrink);
+				count += obj->base.size >> PAGE_SHIFT;
+			}
+
+			if (dma_resv_test_signaled(obj->base.resv, true))
+				dma_resv_add_excl_fence(obj->base.resv, NULL);
+
+			if (!ww)
+				i915_gem_object_unlock(obj);
+
 			scanned += obj->base.size >> PAGE_SHIFT;
 skip:
 			i915_gem_object_put(obj);
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 11/28] drm/i915/pm: Move CONTEXT_VALID_BIT check
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:35   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst, Niranjana Vishwanathapura

Resetting will clear the CONTEXT_VALID_BIT, so wait until after that to test.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 drivers/gpu/drm/i915/gt/intel_engine_pm.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.c b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
index a1334b48dde7..849fbb229bd3 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
@@ -52,8 +52,6 @@ static int __engine_unpark(struct intel_wakeref *wf)
 	/* Discard stale context state from across idling */
 	ce = engine->kernel_context;
 	if (ce) {
-		GEM_BUG_ON(test_bit(CONTEXT_VALID_BIT, &ce->flags));
-
 		/* Flush all pending HW writes before we touch the context */
 		while (unlikely(intel_context_inflight(ce)))
 			intel_engine_flush_submission(engine);
@@ -68,6 +66,9 @@ static int __engine_unpark(struct intel_wakeref *wf)
 			 ce->timeline->seqno,
 			 READ_ONCE(*ce->timeline->hwsp_seqno),
 			 ce->ring->emit);
+
+		GEM_BUG_ON(test_bit(CONTEXT_VALID_BIT, &ce->flags));
+
 		GEM_BUG_ON(ce->timeline->seqno !=
 			   READ_ONCE(*ce->timeline->hwsp_seqno));
 	}
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 11/28] drm/i915/pm: Move CONTEXT_VALID_BIT check
@ 2021-10-21 10:35   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst, Niranjana Vishwanathapura

Resetting will clear the CONTEXT_VALID_BIT, so wait until after that to test.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 drivers/gpu/drm/i915/gt/intel_engine_pm.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.c b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
index a1334b48dde7..849fbb229bd3 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
@@ -52,8 +52,6 @@ static int __engine_unpark(struct intel_wakeref *wf)
 	/* Discard stale context state from across idling */
 	ce = engine->kernel_context;
 	if (ce) {
-		GEM_BUG_ON(test_bit(CONTEXT_VALID_BIT, &ce->flags));
-
 		/* Flush all pending HW writes before we touch the context */
 		while (unlikely(intel_context_inflight(ce)))
 			intel_engine_flush_submission(engine);
@@ -68,6 +66,9 @@ static int __engine_unpark(struct intel_wakeref *wf)
 			 ce->timeline->seqno,
 			 READ_ONCE(*ce->timeline->hwsp_seqno),
 			 ce->ring->emit);
+
+		GEM_BUG_ON(test_bit(CONTEXT_VALID_BIT, &ce->flags));
+
 		GEM_BUG_ON(ce->timeline->seqno !=
 			   READ_ONCE(*ce->timeline->hwsp_seqno));
 	}
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 12/28] drm/i915: Remove resv from i915_vma
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:35   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst, Niranjana Vishwanathapura

It's just an alias to vma->obj->base.resv, no need to duplicate it.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 4 ++--
 drivers/gpu/drm/i915/i915_vma.c                | 9 ++++-----
 drivers/gpu/drm/i915/i915_vma.h                | 6 +++---
 drivers/gpu/drm/i915/i915_vma_types.h          | 1 -
 4 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index eaacadd2d2e5..e614591ca510 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -1007,7 +1007,7 @@ static int eb_validate_vmas(struct i915_execbuffer *eb)
 		}
 
 		if (!(ev->flags & EXEC_OBJECT_WRITE)) {
-			err = dma_resv_reserve_shared(vma->resv, 1);
+			err = dma_resv_reserve_shared(vma->obj->base.resv, 1);
 			if (err)
 				return err;
 		}
@@ -2173,7 +2173,7 @@ static int eb_parse(struct i915_execbuffer *eb)
 		goto err_trampoline;
 	}
 
-	err = dma_resv_reserve_shared(shadow->resv, 1);
+	err = dma_resv_reserve_shared(shadow->obj->base.resv, 1);
 	if (err)
 		goto err_trampoline;
 
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index aebfc232b58b..ac09b685678a 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -116,7 +116,6 @@ vma_create(struct drm_i915_gem_object *obj,
 	vma->vm = i915_vm_get(vm);
 	vma->ops = &vm->vma_ops;
 	vma->obj = obj;
-	vma->resv = obj->base.resv;
 	vma->size = obj->base.size;
 	vma->display_alignment = I915_GTT_MIN_ALIGNMENT;
 
@@ -1032,7 +1031,7 @@ int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 	GEM_BUG_ON(!i915_vma_is_ggtt(vma));
 
 #ifdef CONFIG_LOCKDEP
-	WARN_ON(!ww && dma_resv_held(vma->resv));
+	WARN_ON(!ww && dma_resv_held(vma->obj->base.resv));
 #endif
 
 	do {
@@ -1251,19 +1250,19 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
 		}
 
 		if (fence) {
-			dma_resv_add_excl_fence(vma->resv, fence);
+			dma_resv_add_excl_fence(vma->obj->base.resv, fence);
 			obj->write_domain = I915_GEM_DOMAIN_RENDER;
 			obj->read_domains = 0;
 		}
 	} else {
 		if (!(flags & __EXEC_OBJECT_NO_RESERVE)) {
-			err = dma_resv_reserve_shared(vma->resv, 1);
+			err = dma_resv_reserve_shared(vma->obj->base.resv, 1);
 			if (unlikely(err))
 				return err;
 		}
 
 		if (fence) {
-			dma_resv_add_shared_fence(vma->resv, fence);
+			dma_resv_add_shared_fence(vma->obj->base.resv, fence);
 			obj->write_domain = 0;
 		}
 	}
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 423e0df81c87..9a931ecb09e5 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -232,16 +232,16 @@ static inline void __i915_vma_put(struct i915_vma *vma)
 	kref_put(&vma->ref, i915_vma_release);
 }
 
-#define assert_vma_held(vma) dma_resv_assert_held((vma)->resv)
+#define assert_vma_held(vma) dma_resv_assert_held((vma)->obj->base.resv)
 
 static inline void i915_vma_lock(struct i915_vma *vma)
 {
-	dma_resv_lock(vma->resv, NULL);
+	dma_resv_lock(vma->obj->base.resv, NULL);
 }
 
 static inline void i915_vma_unlock(struct i915_vma *vma)
 {
-	dma_resv_unlock(vma->resv);
+	dma_resv_unlock(vma->obj->base.resv);
 }
 
 int __must_check
diff --git a/drivers/gpu/drm/i915/i915_vma_types.h b/drivers/gpu/drm/i915/i915_vma_types.h
index 80e93bf00f2e..8a0decb19bcc 100644
--- a/drivers/gpu/drm/i915/i915_vma_types.h
+++ b/drivers/gpu/drm/i915/i915_vma_types.h
@@ -178,7 +178,6 @@ struct i915_vma {
 	const struct i915_vma_ops *ops;
 
 	struct drm_i915_gem_object *obj;
-	struct dma_resv *resv; /** Alias of obj->resv */
 
 	struct sg_table *pages;
 	void __iomem *iomap;
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 12/28] drm/i915: Remove resv from i915_vma
@ 2021-10-21 10:35   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst, Niranjana Vishwanathapura

It's just an alias to vma->obj->base.resv, no need to duplicate it.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 4 ++--
 drivers/gpu/drm/i915/i915_vma.c                | 9 ++++-----
 drivers/gpu/drm/i915/i915_vma.h                | 6 +++---
 drivers/gpu/drm/i915/i915_vma_types.h          | 1 -
 4 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index eaacadd2d2e5..e614591ca510 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -1007,7 +1007,7 @@ static int eb_validate_vmas(struct i915_execbuffer *eb)
 		}
 
 		if (!(ev->flags & EXEC_OBJECT_WRITE)) {
-			err = dma_resv_reserve_shared(vma->resv, 1);
+			err = dma_resv_reserve_shared(vma->obj->base.resv, 1);
 			if (err)
 				return err;
 		}
@@ -2173,7 +2173,7 @@ static int eb_parse(struct i915_execbuffer *eb)
 		goto err_trampoline;
 	}
 
-	err = dma_resv_reserve_shared(shadow->resv, 1);
+	err = dma_resv_reserve_shared(shadow->obj->base.resv, 1);
 	if (err)
 		goto err_trampoline;
 
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index aebfc232b58b..ac09b685678a 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -116,7 +116,6 @@ vma_create(struct drm_i915_gem_object *obj,
 	vma->vm = i915_vm_get(vm);
 	vma->ops = &vm->vma_ops;
 	vma->obj = obj;
-	vma->resv = obj->base.resv;
 	vma->size = obj->base.size;
 	vma->display_alignment = I915_GTT_MIN_ALIGNMENT;
 
@@ -1032,7 +1031,7 @@ int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 	GEM_BUG_ON(!i915_vma_is_ggtt(vma));
 
 #ifdef CONFIG_LOCKDEP
-	WARN_ON(!ww && dma_resv_held(vma->resv));
+	WARN_ON(!ww && dma_resv_held(vma->obj->base.resv));
 #endif
 
 	do {
@@ -1251,19 +1250,19 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
 		}
 
 		if (fence) {
-			dma_resv_add_excl_fence(vma->resv, fence);
+			dma_resv_add_excl_fence(vma->obj->base.resv, fence);
 			obj->write_domain = I915_GEM_DOMAIN_RENDER;
 			obj->read_domains = 0;
 		}
 	} else {
 		if (!(flags & __EXEC_OBJECT_NO_RESERVE)) {
-			err = dma_resv_reserve_shared(vma->resv, 1);
+			err = dma_resv_reserve_shared(vma->obj->base.resv, 1);
 			if (unlikely(err))
 				return err;
 		}
 
 		if (fence) {
-			dma_resv_add_shared_fence(vma->resv, fence);
+			dma_resv_add_shared_fence(vma->obj->base.resv, fence);
 			obj->write_domain = 0;
 		}
 	}
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 423e0df81c87..9a931ecb09e5 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -232,16 +232,16 @@ static inline void __i915_vma_put(struct i915_vma *vma)
 	kref_put(&vma->ref, i915_vma_release);
 }
 
-#define assert_vma_held(vma) dma_resv_assert_held((vma)->resv)
+#define assert_vma_held(vma) dma_resv_assert_held((vma)->obj->base.resv)
 
 static inline void i915_vma_lock(struct i915_vma *vma)
 {
-	dma_resv_lock(vma->resv, NULL);
+	dma_resv_lock(vma->obj->base.resv, NULL);
 }
 
 static inline void i915_vma_unlock(struct i915_vma *vma)
 {
-	dma_resv_unlock(vma->resv);
+	dma_resv_unlock(vma->obj->base.resv);
 }
 
 int __must_check
diff --git a/drivers/gpu/drm/i915/i915_vma_types.h b/drivers/gpu/drm/i915/i915_vma_types.h
index 80e93bf00f2e..8a0decb19bcc 100644
--- a/drivers/gpu/drm/i915/i915_vma_types.h
+++ b/drivers/gpu/drm/i915/i915_vma_types.h
@@ -178,7 +178,6 @@ struct i915_vma {
 	const struct i915_vma_ops *ops;
 
 	struct drm_i915_gem_object *obj;
-	struct dma_resv *resv; /** Alias of obj->resv */
 
 	struct sg_table *pages;
 	void __iomem *iomap;
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 13/28] drm/i915: Remove pages_mutex and intel_gtt->vma_ops.set/clear_pages members
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:35   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

Big delta, but boils down to moving set_pages to i915_vma.c, and removing
the special handling, all callers use the defaults anyway. We only remap
in ggtt, so default case will fall through.

Because we still don't require locking in i915_vma_unpin(), handle this by
using xchg in get_pages(), as it's locked with obj->mutex, and cmpxchg in
unpin, which only fails if we race a against a new pin.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_dpt.c      |   2 -
 drivers/gpu/drm/i915/gt/gen6_ppgtt.c          |  15 -
 drivers/gpu/drm/i915/gt/intel_ggtt.c          | 345 ----------------
 drivers/gpu/drm/i915/gt/intel_gtt.c           |  13 -
 drivers/gpu/drm/i915/gt/intel_gtt.h           |   7 -
 drivers/gpu/drm/i915/gt/intel_ppgtt.c         |  12 -
 drivers/gpu/drm/i915/i915_vma.c               | 388 ++++++++++++++++--
 drivers/gpu/drm/i915/i915_vma.h               |   3 +
 drivers/gpu/drm/i915/i915_vma_types.h         |   1 -
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c |  12 +-
 drivers/gpu/drm/i915/selftests/mock_gtt.c     |   4 -
 11 files changed, 368 insertions(+), 434 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c
index 8f7b1f7534a4..ef428f3fc538 100644
--- a/drivers/gpu/drm/i915/display/intel_dpt.c
+++ b/drivers/gpu/drm/i915/display/intel_dpt.c
@@ -221,8 +221,6 @@ intel_dpt_create(struct intel_framebuffer *fb)
 
 	vm->vma_ops.bind_vma    = dpt_bind_vma;
 	vm->vma_ops.unbind_vma  = dpt_unbind_vma;
-	vm->vma_ops.set_pages   = ggtt_set_pages;
-	vm->vma_ops.clear_pages = clear_pages;
 
 	vm->pte_encode = gen8_ggtt_pte_encode;
 
diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
index 5caa1703716e..5c048b4ccd4d 100644
--- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
+++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
@@ -270,19 +270,6 @@ static void gen6_ppgtt_cleanup(struct i915_address_space *vm)
 	free_pd(&ppgtt->base.vm, ppgtt->base.pd);
 }
 
-static int pd_vma_set_pages(struct i915_vma *vma)
-{
-	vma->pages = ERR_PTR(-ENODEV);
-	return 0;
-}
-
-static void pd_vma_clear_pages(struct i915_vma *vma)
-{
-	GEM_BUG_ON(!vma->pages);
-
-	vma->pages = NULL;
-}
-
 static void pd_vma_bind(struct i915_address_space *vm,
 			struct i915_vm_pt_stash *stash,
 			struct i915_vma *vma,
@@ -322,8 +309,6 @@ static void pd_vma_unbind(struct i915_address_space *vm, struct i915_vma *vma)
 }
 
 static const struct i915_vma_ops pd_vma_ops = {
-	.set_pages = pd_vma_set_pages,
-	.clear_pages = pd_vma_clear_pages,
 	.bind_vma = pd_vma_bind,
 	.unbind_vma = pd_vma_unbind,
 };
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index f17383e76eb7..6da57199bb33 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -20,9 +20,6 @@
 #include "intel_gtt.h"
 #include "gen8_ppgtt.h"
 
-static int
-i915_get_ggtt_vma_pages(struct i915_vma *vma);
-
 static void i915_ggtt_color_adjust(const struct drm_mm_node *node,
 				   unsigned long color,
 				   u64 *start,
@@ -875,21 +872,6 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, u64 size)
 	return 0;
 }
 
-int ggtt_set_pages(struct i915_vma *vma)
-{
-	int ret;
-
-	GEM_BUG_ON(vma->pages);
-
-	ret = i915_get_ggtt_vma_pages(vma);
-	if (ret)
-		return ret;
-
-	vma->page_sizes = vma->obj->mm.page_sizes;
-
-	return 0;
-}
-
 static void gen6_gmch_remove(struct i915_address_space *vm)
 {
 	struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
@@ -950,8 +932,6 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
 
 	ggtt->vm.vma_ops.bind_vma    = ggtt_bind_vma;
 	ggtt->vm.vma_ops.unbind_vma  = ggtt_unbind_vma;
-	ggtt->vm.vma_ops.set_pages   = ggtt_set_pages;
-	ggtt->vm.vma_ops.clear_pages = clear_pages;
 
 	ggtt->vm.pte_encode = gen8_ggtt_pte_encode;
 
@@ -1100,8 +1080,6 @@ static int gen6_gmch_probe(struct i915_ggtt *ggtt)
 
 	ggtt->vm.vma_ops.bind_vma    = ggtt_bind_vma;
 	ggtt->vm.vma_ops.unbind_vma  = ggtt_unbind_vma;
-	ggtt->vm.vma_ops.set_pages   = ggtt_set_pages;
-	ggtt->vm.vma_ops.clear_pages = clear_pages;
 
 	return ggtt_probe_common(ggtt, size);
 }
@@ -1145,8 +1123,6 @@ static int i915_gmch_probe(struct i915_ggtt *ggtt)
 
 	ggtt->vm.vma_ops.bind_vma    = ggtt_bind_vma;
 	ggtt->vm.vma_ops.unbind_vma  = ggtt_unbind_vma;
-	ggtt->vm.vma_ops.set_pages   = ggtt_set_pages;
-	ggtt->vm.vma_ops.clear_pages = clear_pages;
 
 	if (unlikely(ggtt->do_idle_maps))
 		drm_notice(&i915->drm,
@@ -1294,324 +1270,3 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 
 	intel_ggtt_restore_fences(ggtt);
 }
-
-static struct scatterlist *
-rotate_pages(struct drm_i915_gem_object *obj, unsigned int offset,
-	     unsigned int width, unsigned int height,
-	     unsigned int src_stride, unsigned int dst_stride,
-	     struct sg_table *st, struct scatterlist *sg)
-{
-	unsigned int column, row;
-	unsigned int src_idx;
-
-	for (column = 0; column < width; column++) {
-		unsigned int left;
-
-		src_idx = src_stride * (height - 1) + column + offset;
-		for (row = 0; row < height; row++) {
-			st->nents++;
-			/*
-			 * We don't need the pages, but need to initialize
-			 * the entries so the sg list can be happily traversed.
-			 * The only thing we need are DMA addresses.
-			 */
-			sg_set_page(sg, NULL, I915_GTT_PAGE_SIZE, 0);
-			sg_dma_address(sg) =
-				i915_gem_object_get_dma_address(obj, src_idx);
-			sg_dma_len(sg) = I915_GTT_PAGE_SIZE;
-			sg = sg_next(sg);
-			src_idx -= src_stride;
-		}
-
-		left = (dst_stride - height) * I915_GTT_PAGE_SIZE;
-
-		if (!left)
-			continue;
-
-		st->nents++;
-
-		/*
-		 * The DE ignores the PTEs for the padding tiles, the sg entry
-		 * here is just a conenience to indicate how many padding PTEs
-		 * to insert at this spot.
-		 */
-		sg_set_page(sg, NULL, left, 0);
-		sg_dma_address(sg) = 0;
-		sg_dma_len(sg) = left;
-		sg = sg_next(sg);
-	}
-
-	return sg;
-}
-
-static noinline struct sg_table *
-intel_rotate_pages(struct intel_rotation_info *rot_info,
-		   struct drm_i915_gem_object *obj)
-{
-	unsigned int size = intel_rotation_info_size(rot_info);
-	struct drm_i915_private *i915 = to_i915(obj->base.dev);
-	struct sg_table *st;
-	struct scatterlist *sg;
-	int ret = -ENOMEM;
-	int i;
-
-	/* Allocate target SG list. */
-	st = kmalloc(sizeof(*st), GFP_KERNEL);
-	if (!st)
-		goto err_st_alloc;
-
-	ret = sg_alloc_table(st, size, GFP_KERNEL);
-	if (ret)
-		goto err_sg_alloc;
-
-	st->nents = 0;
-	sg = st->sgl;
-
-	for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++)
-		sg = rotate_pages(obj, rot_info->plane[i].offset,
-				  rot_info->plane[i].width, rot_info->plane[i].height,
-				  rot_info->plane[i].src_stride,
-				  rot_info->plane[i].dst_stride,
-				  st, sg);
-
-	return st;
-
-err_sg_alloc:
-	kfree(st);
-err_st_alloc:
-
-	drm_dbg(&i915->drm, "Failed to create rotated mapping for object size %zu! (%ux%u tiles, %u pages)\n",
-		obj->base.size, rot_info->plane[0].width,
-		rot_info->plane[0].height, size);
-
-	return ERR_PTR(ret);
-}
-
-static struct scatterlist *
-remap_pages(struct drm_i915_gem_object *obj,
-	    unsigned int offset, unsigned int alignment_pad,
-	    unsigned int width, unsigned int height,
-	    unsigned int src_stride, unsigned int dst_stride,
-	    struct sg_table *st, struct scatterlist *sg)
-{
-	unsigned int row;
-
-	if (alignment_pad) {
-		st->nents++;
-
-		/*
-		 * The DE ignores the PTEs for the padding tiles, the sg entry
-		 * here is just a convenience to indicate how many padding PTEs
-		 * to insert at this spot.
-		 */
-		sg_set_page(sg, NULL, alignment_pad * 4096, 0);
-		sg_dma_address(sg) = 0;
-		sg_dma_len(sg) = alignment_pad * 4096;
-		sg = sg_next(sg);
-	}
-
-	for (row = 0; row < height; row++) {
-		unsigned int left = width * I915_GTT_PAGE_SIZE;
-
-		while (left) {
-			dma_addr_t addr;
-			unsigned int length;
-
-			/*
-			 * We don't need the pages, but need to initialize
-			 * the entries so the sg list can be happily traversed.
-			 * The only thing we need are DMA addresses.
-			 */
-
-			addr = i915_gem_object_get_dma_address_len(obj, offset, &length);
-
-			length = min(left, length);
-
-			st->nents++;
-
-			sg_set_page(sg, NULL, length, 0);
-			sg_dma_address(sg) = addr;
-			sg_dma_len(sg) = length;
-			sg = sg_next(sg);
-
-			offset += length / I915_GTT_PAGE_SIZE;
-			left -= length;
-		}
-
-		offset += src_stride - width;
-
-		left = (dst_stride - width) * I915_GTT_PAGE_SIZE;
-
-		if (!left)
-			continue;
-
-		st->nents++;
-
-		/*
-		 * The DE ignores the PTEs for the padding tiles, the sg entry
-		 * here is just a conenience to indicate how many padding PTEs
-		 * to insert at this spot.
-		 */
-		sg_set_page(sg, NULL, left, 0);
-		sg_dma_address(sg) = 0;
-		sg_dma_len(sg) = left;
-		sg = sg_next(sg);
-	}
-
-	return sg;
-}
-
-static noinline struct sg_table *
-intel_remap_pages(struct intel_remapped_info *rem_info,
-		  struct drm_i915_gem_object *obj)
-{
-	unsigned int size = intel_remapped_info_size(rem_info);
-	struct drm_i915_private *i915 = to_i915(obj->base.dev);
-	struct sg_table *st;
-	struct scatterlist *sg;
-	unsigned int gtt_offset = 0;
-	int ret = -ENOMEM;
-	int i;
-
-	/* Allocate target SG list. */
-	st = kmalloc(sizeof(*st), GFP_KERNEL);
-	if (!st)
-		goto err_st_alloc;
-
-	ret = sg_alloc_table(st, size, GFP_KERNEL);
-	if (ret)
-		goto err_sg_alloc;
-
-	st->nents = 0;
-	sg = st->sgl;
-
-	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
-		unsigned int alignment_pad = 0;
-
-		if (rem_info->plane_alignment)
-			alignment_pad = ALIGN(gtt_offset, rem_info->plane_alignment) - gtt_offset;
-
-		sg = remap_pages(obj,
-				 rem_info->plane[i].offset, alignment_pad,
-				 rem_info->plane[i].width, rem_info->plane[i].height,
-				 rem_info->plane[i].src_stride, rem_info->plane[i].dst_stride,
-				 st, sg);
-
-		gtt_offset += alignment_pad +
-			      rem_info->plane[i].dst_stride * rem_info->plane[i].height;
-	}
-
-	i915_sg_trim(st);
-
-	return st;
-
-err_sg_alloc:
-	kfree(st);
-err_st_alloc:
-
-	drm_dbg(&i915->drm, "Failed to create remapped mapping for object size %zu! (%ux%u tiles, %u pages)\n",
-		obj->base.size, rem_info->plane[0].width,
-		rem_info->plane[0].height, size);
-
-	return ERR_PTR(ret);
-}
-
-static noinline struct sg_table *
-intel_partial_pages(const struct i915_ggtt_view *view,
-		    struct drm_i915_gem_object *obj)
-{
-	struct sg_table *st;
-	struct scatterlist *sg, *iter;
-	unsigned int count = view->partial.size;
-	unsigned int offset;
-	int ret = -ENOMEM;
-
-	st = kmalloc(sizeof(*st), GFP_KERNEL);
-	if (!st)
-		goto err_st_alloc;
-
-	ret = sg_alloc_table(st, count, GFP_KERNEL);
-	if (ret)
-		goto err_sg_alloc;
-
-	iter = i915_gem_object_get_sg_dma(obj, view->partial.offset, &offset);
-	GEM_BUG_ON(!iter);
-
-	sg = st->sgl;
-	st->nents = 0;
-	do {
-		unsigned int len;
-
-		len = min(sg_dma_len(iter) - (offset << PAGE_SHIFT),
-			  count << PAGE_SHIFT);
-		sg_set_page(sg, NULL, len, 0);
-		sg_dma_address(sg) =
-			sg_dma_address(iter) + (offset << PAGE_SHIFT);
-		sg_dma_len(sg) = len;
-
-		st->nents++;
-		count -= len >> PAGE_SHIFT;
-		if (count == 0) {
-			sg_mark_end(sg);
-			i915_sg_trim(st); /* Drop any unused tail entries. */
-
-			return st;
-		}
-
-		sg = __sg_next(sg);
-		iter = __sg_next(iter);
-		offset = 0;
-	} while (1);
-
-err_sg_alloc:
-	kfree(st);
-err_st_alloc:
-	return ERR_PTR(ret);
-}
-
-static int
-i915_get_ggtt_vma_pages(struct i915_vma *vma)
-{
-	int ret;
-
-	/*
-	 * The vma->pages are only valid within the lifespan of the borrowed
-	 * obj->mm.pages. When the obj->mm.pages sg_table is regenerated, so
-	 * must be the vma->pages. A simple rule is that vma->pages must only
-	 * be accessed when the obj->mm.pages are pinned.
-	 */
-	GEM_BUG_ON(!i915_gem_object_has_pinned_pages(vma->obj));
-
-	switch (vma->ggtt_view.type) {
-	default:
-		GEM_BUG_ON(vma->ggtt_view.type);
-		fallthrough;
-	case I915_GGTT_VIEW_NORMAL:
-		vma->pages = vma->obj->mm.pages;
-		return 0;
-
-	case I915_GGTT_VIEW_ROTATED:
-		vma->pages =
-			intel_rotate_pages(&vma->ggtt_view.rotated, vma->obj);
-		break;
-
-	case I915_GGTT_VIEW_REMAPPED:
-		vma->pages =
-			intel_remap_pages(&vma->ggtt_view.remapped, vma->obj);
-		break;
-
-	case I915_GGTT_VIEW_PARTIAL:
-		vma->pages = intel_partial_pages(&vma->ggtt_view, vma->obj);
-		break;
-	}
-
-	ret = 0;
-	if (IS_ERR(vma->pages)) {
-		ret = PTR_ERR(vma->pages);
-		vma->pages = NULL;
-		drm_err(&vma->vm->i915->drm,
-			"Failed to get pages for VMA view type %u (%d)!\n",
-			vma->ggtt_view.type, ret);
-	}
-	return ret;
-}
diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c b/drivers/gpu/drm/i915/gt/intel_gtt.c
index 67d14afa6623..12eed5fcb17a 100644
--- a/drivers/gpu/drm/i915/gt/intel_gtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gtt.c
@@ -221,19 +221,6 @@ void i915_address_space_init(struct i915_address_space *vm, int subclass)
 	INIT_LIST_HEAD(&vm->bound_list);
 }
 
-void clear_pages(struct i915_vma *vma)
-{
-	GEM_BUG_ON(!vma->pages);
-
-	if (vma->pages != vma->obj->mm.pages) {
-		sg_free_table(vma->pages);
-		kfree(vma->pages);
-	}
-	vma->pages = NULL;
-
-	memset(&vma->page_sizes, 0, sizeof(vma->page_sizes));
-}
-
 void *__px_vaddr(struct drm_i915_gem_object *p)
 {
 	enum i915_map_type type;
diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.h b/drivers/gpu/drm/i915/gt/intel_gtt.h
index bc6750263359..306e7645fdc5 100644
--- a/drivers/gpu/drm/i915/gt/intel_gtt.h
+++ b/drivers/gpu/drm/i915/gt/intel_gtt.h
@@ -206,9 +206,6 @@ struct i915_vma_ops {
 	 */
 	void (*unbind_vma)(struct i915_address_space *vm,
 			   struct i915_vma *vma);
-
-	int (*set_pages)(struct i915_vma *vma);
-	void (*clear_pages)(struct i915_vma *vma);
 };
 
 struct i915_address_space {
@@ -594,10 +591,6 @@ release_pd_entry(struct i915_page_directory * const pd,
 		 const struct drm_i915_gem_object * const scratch);
 void gen6_ggtt_invalidate(struct i915_ggtt *ggtt);
 
-int ggtt_set_pages(struct i915_vma *vma);
-int ppgtt_set_pages(struct i915_vma *vma);
-void clear_pages(struct i915_vma *vma);
-
 void ppgtt_bind_vma(struct i915_address_space *vm,
 		    struct i915_vm_pt_stash *stash,
 		    struct i915_vma *vma,
diff --git a/drivers/gpu/drm/i915/gt/intel_ppgtt.c b/drivers/gpu/drm/i915/gt/intel_ppgtt.c
index 4396bfd630d8..083b3090c69c 100644
--- a/drivers/gpu/drm/i915/gt/intel_ppgtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ppgtt.c
@@ -289,16 +289,6 @@ void i915_vm_free_pt_stash(struct i915_address_space *vm,
 	}
 }
 
-int ppgtt_set_pages(struct i915_vma *vma)
-{
-	GEM_BUG_ON(vma->pages);
-
-	vma->pages = vma->obj->mm.pages;
-	vma->page_sizes = vma->obj->mm.page_sizes;
-
-	return 0;
-}
-
 void ppgtt_init(struct i915_ppgtt *ppgtt, struct intel_gt *gt,
 		unsigned long lmem_pt_obj_flags)
 {
@@ -315,6 +305,4 @@ void ppgtt_init(struct i915_ppgtt *ppgtt, struct intel_gt *gt,
 
 	ppgtt->vm.vma_ops.bind_vma    = ppgtt_bind_vma;
 	ppgtt->vm.vma_ops.unbind_vma  = ppgtt_unbind_vma;
-	ppgtt->vm.vma_ops.set_pages   = ppgtt_set_pages;
-	ppgtt->vm.vma_ops.clear_pages = clear_pages;
 }
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index ac09b685678a..bacc8d68e495 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -112,7 +112,6 @@ vma_create(struct drm_i915_gem_object *obj,
 		return ERR_PTR(-ENOMEM);
 
 	kref_init(&vma->ref);
-	mutex_init(&vma->pages_mutex);
 	vma->vm = i915_vm_get(vm);
 	vma->ops = &vm->vma_ops;
 	vma->obj = obj;
@@ -789,10 +788,343 @@ static bool try_qad_pin(struct i915_vma *vma, unsigned int flags)
 	return pinned;
 }
 
-static int vma_get_pages(struct i915_vma *vma)
+
+
+static struct scatterlist *
+rotate_pages(struct drm_i915_gem_object *obj, unsigned int offset,
+	     unsigned int width, unsigned int height,
+	     unsigned int src_stride, unsigned int dst_stride,
+	     struct sg_table *st, struct scatterlist *sg)
 {
-	int err = 0;
-	bool pinned_pages = true;
+	unsigned int column, row;
+	unsigned int src_idx;
+
+	for (column = 0; column < width; column++) {
+		unsigned int left;
+
+		src_idx = src_stride * (height - 1) + column + offset;
+		for (row = 0; row < height; row++) {
+			st->nents++;
+			/*
+			 * We don't need the pages, but need to initialize
+			 * the entries so the sg list can be happily traversed.
+			 * The only thing we need are DMA addresses.
+			 */
+			sg_set_page(sg, NULL, I915_GTT_PAGE_SIZE, 0);
+			sg_dma_address(sg) =
+				i915_gem_object_get_dma_address(obj, src_idx);
+			sg_dma_len(sg) = I915_GTT_PAGE_SIZE;
+			sg = sg_next(sg);
+			src_idx -= src_stride;
+		}
+
+		left = (dst_stride - height) * I915_GTT_PAGE_SIZE;
+
+		if (!left)
+			continue;
+
+		st->nents++;
+
+		/*
+		 * The DE ignores the PTEs for the padding tiles, the sg entry
+		 * here is just a conenience to indicate how many padding PTEs
+		 * to insert at this spot.
+		 */
+		sg_set_page(sg, NULL, left, 0);
+		sg_dma_address(sg) = 0;
+		sg_dma_len(sg) = left;
+		sg = sg_next(sg);
+	}
+
+	return sg;
+}
+
+static noinline struct sg_table *
+intel_rotate_pages(struct intel_rotation_info *rot_info,
+		   struct drm_i915_gem_object *obj)
+{
+	unsigned int size = intel_rotation_info_size(rot_info);
+	struct drm_i915_private *i915 = to_i915(obj->base.dev);
+	struct sg_table *st;
+	struct scatterlist *sg;
+	int ret = -ENOMEM;
+	int i;
+
+	/* Allocate target SG list. */
+	st = kmalloc(sizeof(*st), GFP_KERNEL);
+	if (!st)
+		goto err_st_alloc;
+
+	ret = sg_alloc_table(st, size, GFP_KERNEL);
+	if (ret)
+		goto err_sg_alloc;
+
+	st->nents = 0;
+	sg = st->sgl;
+
+	for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++)
+		sg = rotate_pages(obj, rot_info->plane[i].offset,
+				  rot_info->plane[i].width, rot_info->plane[i].height,
+				  rot_info->plane[i].src_stride,
+				  rot_info->plane[i].dst_stride,
+				  st, sg);
+
+	return st;
+
+err_sg_alloc:
+	kfree(st);
+err_st_alloc:
+
+	drm_dbg(&i915->drm, "Failed to create rotated mapping for object size %zu! (%ux%u tiles, %u pages)\n",
+		obj->base.size, rot_info->plane[0].width,
+		rot_info->plane[0].height, size);
+
+	return ERR_PTR(ret);
+}
+
+static struct scatterlist *
+remap_pages(struct drm_i915_gem_object *obj,
+	    unsigned int offset, unsigned int alignment_pad,
+	    unsigned int width, unsigned int height,
+	    unsigned int src_stride, unsigned int dst_stride,
+	    struct sg_table *st, struct scatterlist *sg)
+{
+	unsigned int row;
+
+	if (alignment_pad) {
+		st->nents++;
+
+		/*
+		 * The DE ignores the PTEs for the padding tiles, the sg entry
+		 * here is just a convenience to indicate how many padding PTEs
+		 * to insert at this spot.
+		 */
+		sg_set_page(sg, NULL, alignment_pad * 4096, 0);
+		sg_dma_address(sg) = 0;
+		sg_dma_len(sg) = alignment_pad * 4096;
+		sg = sg_next(sg);
+	}
+
+	for (row = 0; row < height; row++) {
+		unsigned int left = width * I915_GTT_PAGE_SIZE;
+
+		while (left) {
+			dma_addr_t addr;
+			unsigned int length;
+
+			/*
+			 * We don't need the pages, but need to initialize
+			 * the entries so the sg list can be happily traversed.
+			 * The only thing we need are DMA addresses.
+			 */
+
+			addr = i915_gem_object_get_dma_address_len(obj, offset, &length);
+
+			length = min(left, length);
+
+			st->nents++;
+
+			sg_set_page(sg, NULL, length, 0);
+			sg_dma_address(sg) = addr;
+			sg_dma_len(sg) = length;
+			sg = sg_next(sg);
+
+			offset += length / I915_GTT_PAGE_SIZE;
+			left -= length;
+		}
+
+		offset += src_stride - width;
+
+		left = (dst_stride - width) * I915_GTT_PAGE_SIZE;
+
+		if (!left)
+			continue;
+
+		st->nents++;
+
+		/*
+		 * The DE ignores the PTEs for the padding tiles, the sg entry
+		 * here is just a conenience to indicate how many padding PTEs
+		 * to insert at this spot.
+		 */
+		sg_set_page(sg, NULL, left, 0);
+		sg_dma_address(sg) = 0;
+		sg_dma_len(sg) = left;
+		sg = sg_next(sg);
+	}
+
+	return sg;
+}
+
+static noinline struct sg_table *
+intel_remap_pages(struct intel_remapped_info *rem_info,
+		  struct drm_i915_gem_object *obj)
+{
+	unsigned int size = intel_remapped_info_size(rem_info);
+	struct drm_i915_private *i915 = to_i915(obj->base.dev);
+	struct sg_table *st;
+	struct scatterlist *sg;
+	unsigned int gtt_offset = 0;
+	int ret = -ENOMEM;
+	int i;
+
+	/* Allocate target SG list. */
+	st = kmalloc(sizeof(*st), GFP_KERNEL);
+	if (!st)
+		goto err_st_alloc;
+
+	ret = sg_alloc_table(st, size, GFP_KERNEL);
+	if (ret)
+		goto err_sg_alloc;
+
+	st->nents = 0;
+	sg = st->sgl;
+
+	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
+		unsigned int alignment_pad = 0;
+
+		if (rem_info->plane_alignment)
+			alignment_pad = ALIGN(gtt_offset, rem_info->plane_alignment) - gtt_offset;
+
+		sg = remap_pages(obj,
+				 rem_info->plane[i].offset, alignment_pad,
+				 rem_info->plane[i].width, rem_info->plane[i].height,
+				 rem_info->plane[i].src_stride, rem_info->plane[i].dst_stride,
+				 st, sg);
+
+		gtt_offset += alignment_pad +
+			      rem_info->plane[i].dst_stride * rem_info->plane[i].height;
+	}
+
+	i915_sg_trim(st);
+
+	return st;
+
+err_sg_alloc:
+	kfree(st);
+err_st_alloc:
+
+	drm_dbg(&i915->drm, "Failed to create remapped mapping for object size %zu! (%ux%u tiles, %u pages)\n",
+		obj->base.size, rem_info->plane[0].width,
+		rem_info->plane[0].height, size);
+
+	return ERR_PTR(ret);
+}
+
+static noinline struct sg_table *
+intel_partial_pages(const struct i915_ggtt_view *view,
+		    struct drm_i915_gem_object *obj)
+{
+	struct sg_table *st;
+	struct scatterlist *sg, *iter;
+	unsigned int count = view->partial.size;
+	unsigned int offset;
+	int ret = -ENOMEM;
+
+	st = kmalloc(sizeof(*st), GFP_KERNEL);
+	if (!st)
+		goto err_st_alloc;
+
+	ret = sg_alloc_table(st, count, GFP_KERNEL);
+	if (ret)
+		goto err_sg_alloc;
+
+	iter = i915_gem_object_get_sg_dma(obj, view->partial.offset, &offset);
+	GEM_BUG_ON(!iter);
+
+	sg = st->sgl;
+	st->nents = 0;
+	do {
+		unsigned int len;
+
+		len = min(sg_dma_len(iter) - (offset << PAGE_SHIFT),
+			  count << PAGE_SHIFT);
+		sg_set_page(sg, NULL, len, 0);
+		sg_dma_address(sg) =
+			sg_dma_address(iter) + (offset << PAGE_SHIFT);
+		sg_dma_len(sg) = len;
+
+		st->nents++;
+		count -= len >> PAGE_SHIFT;
+		if (count == 0) {
+			sg_mark_end(sg);
+			i915_sg_trim(st); /* Drop any unused tail entries. */
+
+			return st;
+		}
+
+		sg = __sg_next(sg);
+		iter = __sg_next(iter);
+		offset = 0;
+	} while (1);
+
+err_sg_alloc:
+	kfree(st);
+err_st_alloc:
+	return ERR_PTR(ret);
+}
+
+static int
+__i915_vma_get_pages(struct i915_vma *vma)
+{
+	struct sg_table *pages;
+	int ret;
+
+	/*
+	 * The vma->pages are only valid within the lifespan of the borrowed
+	 * obj->mm.pages. When the obj->mm.pages sg_table is regenerated, so
+	 * must be the vma->pages. A simple rule is that vma->pages must only
+	 * be accessed when the obj->mm.pages are pinned.
+	 */
+	GEM_BUG_ON(!i915_gem_object_has_pinned_pages(vma->obj));
+
+	switch (vma->ggtt_view.type) {
+	default:
+		GEM_BUG_ON(vma->ggtt_view.type);
+		fallthrough;
+	case I915_GGTT_VIEW_NORMAL:
+		pages = vma->obj->mm.pages;
+		break;
+
+	case I915_GGTT_VIEW_ROTATED:
+		pages =
+			intel_rotate_pages(&vma->ggtt_view.rotated, vma->obj);
+		break;
+
+	case I915_GGTT_VIEW_REMAPPED:
+		pages =
+			intel_remap_pages(&vma->ggtt_view.remapped, vma->obj);
+		break;
+
+	case I915_GGTT_VIEW_PARTIAL:
+		pages = intel_partial_pages(&vma->ggtt_view, vma->obj);
+		break;
+	}
+
+	ret = 0;
+	/* gen6 ppgtt doesn't have backing pages, special-case it */
+	if (IS_ERR(pages) && pages != ERR_PTR(-ENODEV)) {
+		ret = PTR_ERR(pages);
+		pages = NULL;
+		drm_err(&vma->vm->i915->drm,
+			"Failed to get pages for VMA view type %u (%d)!\n",
+			vma->ggtt_view.type, ret);
+	}
+
+	pages = xchg(&vma->pages, pages);
+
+	/* did we race against a put_pages? */
+	if (pages && pages != vma->obj->mm.pages) {
+		sg_free_table(vma->pages);
+		kfree(vma->pages);
+	}
+
+	return ret;
+}
+
+I915_SELFTEST_EXPORT int i915_vma_get_pages(struct i915_vma *vma)
+{
+	int err;
 
 	if (atomic_add_unless(&vma->pages_count, 1, 0))
 		return 0;
@@ -801,25 +1133,17 @@ static int vma_get_pages(struct i915_vma *vma)
 	if (err)
 		return err;
 
-	/* Allocations ahoy! */
-	if (mutex_lock_interruptible(&vma->pages_mutex)) {
-		err = -EINTR;
-		goto unpin;
-	}
+	err = __i915_vma_get_pages(vma);
+	if (err)
+		goto err_unpin;
 
-	if (!atomic_read(&vma->pages_count)) {
-		err = vma->ops->set_pages(vma);
-		if (err)
-			goto unlock;
-		pinned_pages = false;
-	}
+	vma->page_sizes = vma->obj->mm.page_sizes;
 	atomic_inc(&vma->pages_count);
 
-unlock:
-	mutex_unlock(&vma->pages_mutex);
-unpin:
-	if (pinned_pages)
-		__i915_gem_object_unpin_pages(vma->obj);
+	return 0;
+
+err_unpin:
+	__i915_gem_object_unpin_pages(vma->obj);
 
 	return err;
 }
@@ -827,18 +1151,22 @@ static int vma_get_pages(struct i915_vma *vma)
 static void __vma_put_pages(struct i915_vma *vma, unsigned int count)
 {
 	/* We allocate under vma_get_pages, so beware the shrinker */
-	mutex_lock_nested(&vma->pages_mutex, SINGLE_DEPTH_NESTING);
+	struct sg_table *pages = READ_ONCE(vma->pages);
+
 	GEM_BUG_ON(atomic_read(&vma->pages_count) < count);
+
 	if (atomic_sub_return(count, &vma->pages_count) == 0) {
-		vma->ops->clear_pages(vma);
-		GEM_BUG_ON(vma->pages);
+		if (pages == cmpxchg(&vma->pages, pages, NULL) &&
+		    pages != vma->obj->mm.pages) {
+			sg_free_table(pages);
+			kfree(pages);
+		}
 
 		i915_gem_object_unpin_pages(vma->obj);
 	}
-	mutex_unlock(&vma->pages_mutex);
 }
 
-static void vma_put_pages(struct i915_vma *vma)
+I915_SELFTEST_EXPORT void i915_vma_put_pages(struct i915_vma *vma)
 {
 	if (atomic_add_unless(&vma->pages_count, -1, 1))
 		return;
@@ -868,10 +1196,8 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 	unsigned int bound;
 	int err;
 
-#ifdef CONFIG_PROVE_LOCKING
-	if (debug_locks && !WARN_ON(!ww))
-		assert_vma_held(vma);
-#endif
+	assert_vma_held(vma);
+	GEM_BUG_ON(!ww);
 
 	BUILD_BUG_ON(PIN_GLOBAL != I915_VMA_GLOBAL_BIND);
 	BUILD_BUG_ON(PIN_USER != I915_VMA_LOCAL_BIND);
@@ -882,7 +1208,7 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 	if (try_qad_pin(vma, flags & I915_VMA_BIND_MASK))
 		return 0;
 
-	err = vma_get_pages(vma);
+	err = i915_vma_get_pages(vma);
 	if (err)
 		return err;
 
@@ -1007,7 +1333,7 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 err_rpm:
 	if (wakeref)
 		intel_runtime_pm_put(&vma->vm->i915->runtime_pm, wakeref);
-	vma_put_pages(vma);
+	i915_vma_put_pages(vma);
 	return err;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 9a931ecb09e5..32719431b3df 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -431,4 +431,7 @@ static inline int i915_vma_sync(struct i915_vma *vma)
 void i915_vma_module_exit(void);
 int i915_vma_module_init(void);
 
+I915_SELFTEST_DECLARE(int i915_vma_get_pages(struct i915_vma *vma));
+I915_SELFTEST_DECLARE(void i915_vma_put_pages(struct i915_vma *vma));
+
 #endif
diff --git a/drivers/gpu/drm/i915/i915_vma_types.h b/drivers/gpu/drm/i915/i915_vma_types.h
index 8a0decb19bcc..412d3e78a30d 100644
--- a/drivers/gpu/drm/i915/i915_vma_types.h
+++ b/drivers/gpu/drm/i915/i915_vma_types.h
@@ -261,7 +261,6 @@ struct i915_vma {
 #define I915_VMA_PAGES_BIAS 24
 #define I915_VMA_PAGES_ACTIVE (BIT(24) | 1)
 	atomic_t pages_count; /* number of active binds to the pages */
-	struct mutex pages_mutex; /* protect acquire/release of backing pages */
 
 	/**
 	 * Support different GGTT views into the same object.
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 46f4236039a9..4574fb51b656 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -1953,7 +1953,9 @@ static int igt_cs_tlb(void *arg)
 				goto end;
 			}
 
-			err = vma->ops->set_pages(vma);
+			i915_gem_object_lock(bbe, NULL);
+			err = i915_vma_get_pages(vma);
+			i915_gem_object_unlock(bbe);
 			if (err)
 				goto end;
 
@@ -1994,7 +1996,7 @@ static int igt_cs_tlb(void *arg)
 				i915_request_put(rq);
 			}
 
-			vma->ops->clear_pages(vma);
+			i915_vma_put_pages(vma);
 
 			err = context_sync(ce);
 			if (err) {
@@ -2009,7 +2011,9 @@ static int igt_cs_tlb(void *arg)
 				goto end;
 			}
 
-			err = vma->ops->set_pages(vma);
+			i915_gem_object_lock(act, NULL);
+			err = i915_vma_get_pages(vma);
+			i915_gem_object_unlock(act);
 			if (err)
 				goto end;
 
@@ -2047,7 +2051,7 @@ static int igt_cs_tlb(void *arg)
 			}
 			end_spin(batch, count - 1);
 
-			vma->ops->clear_pages(vma);
+			i915_vma_put_pages(vma);
 
 			err = context_sync(ce);
 			if (err) {
diff --git a/drivers/gpu/drm/i915/selftests/mock_gtt.c b/drivers/gpu/drm/i915/selftests/mock_gtt.c
index cc047ec594f9..096679014d99 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gtt.c
@@ -86,8 +86,6 @@ struct i915_ppgtt *mock_ppgtt(struct drm_i915_private *i915, const char *name)
 
 	ppgtt->vm.vma_ops.bind_vma    = mock_bind_ppgtt;
 	ppgtt->vm.vma_ops.unbind_vma  = mock_unbind_ppgtt;
-	ppgtt->vm.vma_ops.set_pages   = ppgtt_set_pages;
-	ppgtt->vm.vma_ops.clear_pages = clear_pages;
 
 	return ppgtt;
 }
@@ -126,8 +124,6 @@ void mock_init_ggtt(struct drm_i915_private *i915, struct i915_ggtt *ggtt)
 
 	ggtt->vm.vma_ops.bind_vma    = mock_bind_ggtt;
 	ggtt->vm.vma_ops.unbind_vma  = mock_unbind_ggtt;
-	ggtt->vm.vma_ops.set_pages   = ggtt_set_pages;
-	ggtt->vm.vma_ops.clear_pages = clear_pages;
 
 	i915_address_space_init(&ggtt->vm, VM_CLASS_GGTT);
 	i915->gt.ggtt = ggtt;
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 13/28] drm/i915: Remove pages_mutex and intel_gtt->vma_ops.set/clear_pages members
@ 2021-10-21 10:35   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

Big delta, but boils down to moving set_pages to i915_vma.c, and removing
the special handling, all callers use the defaults anyway. We only remap
in ggtt, so default case will fall through.

Because we still don't require locking in i915_vma_unpin(), handle this by
using xchg in get_pages(), as it's locked with obj->mutex, and cmpxchg in
unpin, which only fails if we race a against a new pin.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_dpt.c      |   2 -
 drivers/gpu/drm/i915/gt/gen6_ppgtt.c          |  15 -
 drivers/gpu/drm/i915/gt/intel_ggtt.c          | 345 ----------------
 drivers/gpu/drm/i915/gt/intel_gtt.c           |  13 -
 drivers/gpu/drm/i915/gt/intel_gtt.h           |   7 -
 drivers/gpu/drm/i915/gt/intel_ppgtt.c         |  12 -
 drivers/gpu/drm/i915/i915_vma.c               | 388 ++++++++++++++++--
 drivers/gpu/drm/i915/i915_vma.h               |   3 +
 drivers/gpu/drm/i915/i915_vma_types.h         |   1 -
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c |  12 +-
 drivers/gpu/drm/i915/selftests/mock_gtt.c     |   4 -
 11 files changed, 368 insertions(+), 434 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c
index 8f7b1f7534a4..ef428f3fc538 100644
--- a/drivers/gpu/drm/i915/display/intel_dpt.c
+++ b/drivers/gpu/drm/i915/display/intel_dpt.c
@@ -221,8 +221,6 @@ intel_dpt_create(struct intel_framebuffer *fb)
 
 	vm->vma_ops.bind_vma    = dpt_bind_vma;
 	vm->vma_ops.unbind_vma  = dpt_unbind_vma;
-	vm->vma_ops.set_pages   = ggtt_set_pages;
-	vm->vma_ops.clear_pages = clear_pages;
 
 	vm->pte_encode = gen8_ggtt_pte_encode;
 
diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
index 5caa1703716e..5c048b4ccd4d 100644
--- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
+++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
@@ -270,19 +270,6 @@ static void gen6_ppgtt_cleanup(struct i915_address_space *vm)
 	free_pd(&ppgtt->base.vm, ppgtt->base.pd);
 }
 
-static int pd_vma_set_pages(struct i915_vma *vma)
-{
-	vma->pages = ERR_PTR(-ENODEV);
-	return 0;
-}
-
-static void pd_vma_clear_pages(struct i915_vma *vma)
-{
-	GEM_BUG_ON(!vma->pages);
-
-	vma->pages = NULL;
-}
-
 static void pd_vma_bind(struct i915_address_space *vm,
 			struct i915_vm_pt_stash *stash,
 			struct i915_vma *vma,
@@ -322,8 +309,6 @@ static void pd_vma_unbind(struct i915_address_space *vm, struct i915_vma *vma)
 }
 
 static const struct i915_vma_ops pd_vma_ops = {
-	.set_pages = pd_vma_set_pages,
-	.clear_pages = pd_vma_clear_pages,
 	.bind_vma = pd_vma_bind,
 	.unbind_vma = pd_vma_unbind,
 };
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index f17383e76eb7..6da57199bb33 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -20,9 +20,6 @@
 #include "intel_gtt.h"
 #include "gen8_ppgtt.h"
 
-static int
-i915_get_ggtt_vma_pages(struct i915_vma *vma);
-
 static void i915_ggtt_color_adjust(const struct drm_mm_node *node,
 				   unsigned long color,
 				   u64 *start,
@@ -875,21 +872,6 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, u64 size)
 	return 0;
 }
 
-int ggtt_set_pages(struct i915_vma *vma)
-{
-	int ret;
-
-	GEM_BUG_ON(vma->pages);
-
-	ret = i915_get_ggtt_vma_pages(vma);
-	if (ret)
-		return ret;
-
-	vma->page_sizes = vma->obj->mm.page_sizes;
-
-	return 0;
-}
-
 static void gen6_gmch_remove(struct i915_address_space *vm)
 {
 	struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
@@ -950,8 +932,6 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
 
 	ggtt->vm.vma_ops.bind_vma    = ggtt_bind_vma;
 	ggtt->vm.vma_ops.unbind_vma  = ggtt_unbind_vma;
-	ggtt->vm.vma_ops.set_pages   = ggtt_set_pages;
-	ggtt->vm.vma_ops.clear_pages = clear_pages;
 
 	ggtt->vm.pte_encode = gen8_ggtt_pte_encode;
 
@@ -1100,8 +1080,6 @@ static int gen6_gmch_probe(struct i915_ggtt *ggtt)
 
 	ggtt->vm.vma_ops.bind_vma    = ggtt_bind_vma;
 	ggtt->vm.vma_ops.unbind_vma  = ggtt_unbind_vma;
-	ggtt->vm.vma_ops.set_pages   = ggtt_set_pages;
-	ggtt->vm.vma_ops.clear_pages = clear_pages;
 
 	return ggtt_probe_common(ggtt, size);
 }
@@ -1145,8 +1123,6 @@ static int i915_gmch_probe(struct i915_ggtt *ggtt)
 
 	ggtt->vm.vma_ops.bind_vma    = ggtt_bind_vma;
 	ggtt->vm.vma_ops.unbind_vma  = ggtt_unbind_vma;
-	ggtt->vm.vma_ops.set_pages   = ggtt_set_pages;
-	ggtt->vm.vma_ops.clear_pages = clear_pages;
 
 	if (unlikely(ggtt->do_idle_maps))
 		drm_notice(&i915->drm,
@@ -1294,324 +1270,3 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 
 	intel_ggtt_restore_fences(ggtt);
 }
-
-static struct scatterlist *
-rotate_pages(struct drm_i915_gem_object *obj, unsigned int offset,
-	     unsigned int width, unsigned int height,
-	     unsigned int src_stride, unsigned int dst_stride,
-	     struct sg_table *st, struct scatterlist *sg)
-{
-	unsigned int column, row;
-	unsigned int src_idx;
-
-	for (column = 0; column < width; column++) {
-		unsigned int left;
-
-		src_idx = src_stride * (height - 1) + column + offset;
-		for (row = 0; row < height; row++) {
-			st->nents++;
-			/*
-			 * We don't need the pages, but need to initialize
-			 * the entries so the sg list can be happily traversed.
-			 * The only thing we need are DMA addresses.
-			 */
-			sg_set_page(sg, NULL, I915_GTT_PAGE_SIZE, 0);
-			sg_dma_address(sg) =
-				i915_gem_object_get_dma_address(obj, src_idx);
-			sg_dma_len(sg) = I915_GTT_PAGE_SIZE;
-			sg = sg_next(sg);
-			src_idx -= src_stride;
-		}
-
-		left = (dst_stride - height) * I915_GTT_PAGE_SIZE;
-
-		if (!left)
-			continue;
-
-		st->nents++;
-
-		/*
-		 * The DE ignores the PTEs for the padding tiles, the sg entry
-		 * here is just a conenience to indicate how many padding PTEs
-		 * to insert at this spot.
-		 */
-		sg_set_page(sg, NULL, left, 0);
-		sg_dma_address(sg) = 0;
-		sg_dma_len(sg) = left;
-		sg = sg_next(sg);
-	}
-
-	return sg;
-}
-
-static noinline struct sg_table *
-intel_rotate_pages(struct intel_rotation_info *rot_info,
-		   struct drm_i915_gem_object *obj)
-{
-	unsigned int size = intel_rotation_info_size(rot_info);
-	struct drm_i915_private *i915 = to_i915(obj->base.dev);
-	struct sg_table *st;
-	struct scatterlist *sg;
-	int ret = -ENOMEM;
-	int i;
-
-	/* Allocate target SG list. */
-	st = kmalloc(sizeof(*st), GFP_KERNEL);
-	if (!st)
-		goto err_st_alloc;
-
-	ret = sg_alloc_table(st, size, GFP_KERNEL);
-	if (ret)
-		goto err_sg_alloc;
-
-	st->nents = 0;
-	sg = st->sgl;
-
-	for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++)
-		sg = rotate_pages(obj, rot_info->plane[i].offset,
-				  rot_info->plane[i].width, rot_info->plane[i].height,
-				  rot_info->plane[i].src_stride,
-				  rot_info->plane[i].dst_stride,
-				  st, sg);
-
-	return st;
-
-err_sg_alloc:
-	kfree(st);
-err_st_alloc:
-
-	drm_dbg(&i915->drm, "Failed to create rotated mapping for object size %zu! (%ux%u tiles, %u pages)\n",
-		obj->base.size, rot_info->plane[0].width,
-		rot_info->plane[0].height, size);
-
-	return ERR_PTR(ret);
-}
-
-static struct scatterlist *
-remap_pages(struct drm_i915_gem_object *obj,
-	    unsigned int offset, unsigned int alignment_pad,
-	    unsigned int width, unsigned int height,
-	    unsigned int src_stride, unsigned int dst_stride,
-	    struct sg_table *st, struct scatterlist *sg)
-{
-	unsigned int row;
-
-	if (alignment_pad) {
-		st->nents++;
-
-		/*
-		 * The DE ignores the PTEs for the padding tiles, the sg entry
-		 * here is just a convenience to indicate how many padding PTEs
-		 * to insert at this spot.
-		 */
-		sg_set_page(sg, NULL, alignment_pad * 4096, 0);
-		sg_dma_address(sg) = 0;
-		sg_dma_len(sg) = alignment_pad * 4096;
-		sg = sg_next(sg);
-	}
-
-	for (row = 0; row < height; row++) {
-		unsigned int left = width * I915_GTT_PAGE_SIZE;
-
-		while (left) {
-			dma_addr_t addr;
-			unsigned int length;
-
-			/*
-			 * We don't need the pages, but need to initialize
-			 * the entries so the sg list can be happily traversed.
-			 * The only thing we need are DMA addresses.
-			 */
-
-			addr = i915_gem_object_get_dma_address_len(obj, offset, &length);
-
-			length = min(left, length);
-
-			st->nents++;
-
-			sg_set_page(sg, NULL, length, 0);
-			sg_dma_address(sg) = addr;
-			sg_dma_len(sg) = length;
-			sg = sg_next(sg);
-
-			offset += length / I915_GTT_PAGE_SIZE;
-			left -= length;
-		}
-
-		offset += src_stride - width;
-
-		left = (dst_stride - width) * I915_GTT_PAGE_SIZE;
-
-		if (!left)
-			continue;
-
-		st->nents++;
-
-		/*
-		 * The DE ignores the PTEs for the padding tiles, the sg entry
-		 * here is just a conenience to indicate how many padding PTEs
-		 * to insert at this spot.
-		 */
-		sg_set_page(sg, NULL, left, 0);
-		sg_dma_address(sg) = 0;
-		sg_dma_len(sg) = left;
-		sg = sg_next(sg);
-	}
-
-	return sg;
-}
-
-static noinline struct sg_table *
-intel_remap_pages(struct intel_remapped_info *rem_info,
-		  struct drm_i915_gem_object *obj)
-{
-	unsigned int size = intel_remapped_info_size(rem_info);
-	struct drm_i915_private *i915 = to_i915(obj->base.dev);
-	struct sg_table *st;
-	struct scatterlist *sg;
-	unsigned int gtt_offset = 0;
-	int ret = -ENOMEM;
-	int i;
-
-	/* Allocate target SG list. */
-	st = kmalloc(sizeof(*st), GFP_KERNEL);
-	if (!st)
-		goto err_st_alloc;
-
-	ret = sg_alloc_table(st, size, GFP_KERNEL);
-	if (ret)
-		goto err_sg_alloc;
-
-	st->nents = 0;
-	sg = st->sgl;
-
-	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
-		unsigned int alignment_pad = 0;
-
-		if (rem_info->plane_alignment)
-			alignment_pad = ALIGN(gtt_offset, rem_info->plane_alignment) - gtt_offset;
-
-		sg = remap_pages(obj,
-				 rem_info->plane[i].offset, alignment_pad,
-				 rem_info->plane[i].width, rem_info->plane[i].height,
-				 rem_info->plane[i].src_stride, rem_info->plane[i].dst_stride,
-				 st, sg);
-
-		gtt_offset += alignment_pad +
-			      rem_info->plane[i].dst_stride * rem_info->plane[i].height;
-	}
-
-	i915_sg_trim(st);
-
-	return st;
-
-err_sg_alloc:
-	kfree(st);
-err_st_alloc:
-
-	drm_dbg(&i915->drm, "Failed to create remapped mapping for object size %zu! (%ux%u tiles, %u pages)\n",
-		obj->base.size, rem_info->plane[0].width,
-		rem_info->plane[0].height, size);
-
-	return ERR_PTR(ret);
-}
-
-static noinline struct sg_table *
-intel_partial_pages(const struct i915_ggtt_view *view,
-		    struct drm_i915_gem_object *obj)
-{
-	struct sg_table *st;
-	struct scatterlist *sg, *iter;
-	unsigned int count = view->partial.size;
-	unsigned int offset;
-	int ret = -ENOMEM;
-
-	st = kmalloc(sizeof(*st), GFP_KERNEL);
-	if (!st)
-		goto err_st_alloc;
-
-	ret = sg_alloc_table(st, count, GFP_KERNEL);
-	if (ret)
-		goto err_sg_alloc;
-
-	iter = i915_gem_object_get_sg_dma(obj, view->partial.offset, &offset);
-	GEM_BUG_ON(!iter);
-
-	sg = st->sgl;
-	st->nents = 0;
-	do {
-		unsigned int len;
-
-		len = min(sg_dma_len(iter) - (offset << PAGE_SHIFT),
-			  count << PAGE_SHIFT);
-		sg_set_page(sg, NULL, len, 0);
-		sg_dma_address(sg) =
-			sg_dma_address(iter) + (offset << PAGE_SHIFT);
-		sg_dma_len(sg) = len;
-
-		st->nents++;
-		count -= len >> PAGE_SHIFT;
-		if (count == 0) {
-			sg_mark_end(sg);
-			i915_sg_trim(st); /* Drop any unused tail entries. */
-
-			return st;
-		}
-
-		sg = __sg_next(sg);
-		iter = __sg_next(iter);
-		offset = 0;
-	} while (1);
-
-err_sg_alloc:
-	kfree(st);
-err_st_alloc:
-	return ERR_PTR(ret);
-}
-
-static int
-i915_get_ggtt_vma_pages(struct i915_vma *vma)
-{
-	int ret;
-
-	/*
-	 * The vma->pages are only valid within the lifespan of the borrowed
-	 * obj->mm.pages. When the obj->mm.pages sg_table is regenerated, so
-	 * must be the vma->pages. A simple rule is that vma->pages must only
-	 * be accessed when the obj->mm.pages are pinned.
-	 */
-	GEM_BUG_ON(!i915_gem_object_has_pinned_pages(vma->obj));
-
-	switch (vma->ggtt_view.type) {
-	default:
-		GEM_BUG_ON(vma->ggtt_view.type);
-		fallthrough;
-	case I915_GGTT_VIEW_NORMAL:
-		vma->pages = vma->obj->mm.pages;
-		return 0;
-
-	case I915_GGTT_VIEW_ROTATED:
-		vma->pages =
-			intel_rotate_pages(&vma->ggtt_view.rotated, vma->obj);
-		break;
-
-	case I915_GGTT_VIEW_REMAPPED:
-		vma->pages =
-			intel_remap_pages(&vma->ggtt_view.remapped, vma->obj);
-		break;
-
-	case I915_GGTT_VIEW_PARTIAL:
-		vma->pages = intel_partial_pages(&vma->ggtt_view, vma->obj);
-		break;
-	}
-
-	ret = 0;
-	if (IS_ERR(vma->pages)) {
-		ret = PTR_ERR(vma->pages);
-		vma->pages = NULL;
-		drm_err(&vma->vm->i915->drm,
-			"Failed to get pages for VMA view type %u (%d)!\n",
-			vma->ggtt_view.type, ret);
-	}
-	return ret;
-}
diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c b/drivers/gpu/drm/i915/gt/intel_gtt.c
index 67d14afa6623..12eed5fcb17a 100644
--- a/drivers/gpu/drm/i915/gt/intel_gtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gtt.c
@@ -221,19 +221,6 @@ void i915_address_space_init(struct i915_address_space *vm, int subclass)
 	INIT_LIST_HEAD(&vm->bound_list);
 }
 
-void clear_pages(struct i915_vma *vma)
-{
-	GEM_BUG_ON(!vma->pages);
-
-	if (vma->pages != vma->obj->mm.pages) {
-		sg_free_table(vma->pages);
-		kfree(vma->pages);
-	}
-	vma->pages = NULL;
-
-	memset(&vma->page_sizes, 0, sizeof(vma->page_sizes));
-}
-
 void *__px_vaddr(struct drm_i915_gem_object *p)
 {
 	enum i915_map_type type;
diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.h b/drivers/gpu/drm/i915/gt/intel_gtt.h
index bc6750263359..306e7645fdc5 100644
--- a/drivers/gpu/drm/i915/gt/intel_gtt.h
+++ b/drivers/gpu/drm/i915/gt/intel_gtt.h
@@ -206,9 +206,6 @@ struct i915_vma_ops {
 	 */
 	void (*unbind_vma)(struct i915_address_space *vm,
 			   struct i915_vma *vma);
-
-	int (*set_pages)(struct i915_vma *vma);
-	void (*clear_pages)(struct i915_vma *vma);
 };
 
 struct i915_address_space {
@@ -594,10 +591,6 @@ release_pd_entry(struct i915_page_directory * const pd,
 		 const struct drm_i915_gem_object * const scratch);
 void gen6_ggtt_invalidate(struct i915_ggtt *ggtt);
 
-int ggtt_set_pages(struct i915_vma *vma);
-int ppgtt_set_pages(struct i915_vma *vma);
-void clear_pages(struct i915_vma *vma);
-
 void ppgtt_bind_vma(struct i915_address_space *vm,
 		    struct i915_vm_pt_stash *stash,
 		    struct i915_vma *vma,
diff --git a/drivers/gpu/drm/i915/gt/intel_ppgtt.c b/drivers/gpu/drm/i915/gt/intel_ppgtt.c
index 4396bfd630d8..083b3090c69c 100644
--- a/drivers/gpu/drm/i915/gt/intel_ppgtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ppgtt.c
@@ -289,16 +289,6 @@ void i915_vm_free_pt_stash(struct i915_address_space *vm,
 	}
 }
 
-int ppgtt_set_pages(struct i915_vma *vma)
-{
-	GEM_BUG_ON(vma->pages);
-
-	vma->pages = vma->obj->mm.pages;
-	vma->page_sizes = vma->obj->mm.page_sizes;
-
-	return 0;
-}
-
 void ppgtt_init(struct i915_ppgtt *ppgtt, struct intel_gt *gt,
 		unsigned long lmem_pt_obj_flags)
 {
@@ -315,6 +305,4 @@ void ppgtt_init(struct i915_ppgtt *ppgtt, struct intel_gt *gt,
 
 	ppgtt->vm.vma_ops.bind_vma    = ppgtt_bind_vma;
 	ppgtt->vm.vma_ops.unbind_vma  = ppgtt_unbind_vma;
-	ppgtt->vm.vma_ops.set_pages   = ppgtt_set_pages;
-	ppgtt->vm.vma_ops.clear_pages = clear_pages;
 }
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index ac09b685678a..bacc8d68e495 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -112,7 +112,6 @@ vma_create(struct drm_i915_gem_object *obj,
 		return ERR_PTR(-ENOMEM);
 
 	kref_init(&vma->ref);
-	mutex_init(&vma->pages_mutex);
 	vma->vm = i915_vm_get(vm);
 	vma->ops = &vm->vma_ops;
 	vma->obj = obj;
@@ -789,10 +788,343 @@ static bool try_qad_pin(struct i915_vma *vma, unsigned int flags)
 	return pinned;
 }
 
-static int vma_get_pages(struct i915_vma *vma)
+
+
+static struct scatterlist *
+rotate_pages(struct drm_i915_gem_object *obj, unsigned int offset,
+	     unsigned int width, unsigned int height,
+	     unsigned int src_stride, unsigned int dst_stride,
+	     struct sg_table *st, struct scatterlist *sg)
 {
-	int err = 0;
-	bool pinned_pages = true;
+	unsigned int column, row;
+	unsigned int src_idx;
+
+	for (column = 0; column < width; column++) {
+		unsigned int left;
+
+		src_idx = src_stride * (height - 1) + column + offset;
+		for (row = 0; row < height; row++) {
+			st->nents++;
+			/*
+			 * We don't need the pages, but need to initialize
+			 * the entries so the sg list can be happily traversed.
+			 * The only thing we need are DMA addresses.
+			 */
+			sg_set_page(sg, NULL, I915_GTT_PAGE_SIZE, 0);
+			sg_dma_address(sg) =
+				i915_gem_object_get_dma_address(obj, src_idx);
+			sg_dma_len(sg) = I915_GTT_PAGE_SIZE;
+			sg = sg_next(sg);
+			src_idx -= src_stride;
+		}
+
+		left = (dst_stride - height) * I915_GTT_PAGE_SIZE;
+
+		if (!left)
+			continue;
+
+		st->nents++;
+
+		/*
+		 * The DE ignores the PTEs for the padding tiles, the sg entry
+		 * here is just a conenience to indicate how many padding PTEs
+		 * to insert at this spot.
+		 */
+		sg_set_page(sg, NULL, left, 0);
+		sg_dma_address(sg) = 0;
+		sg_dma_len(sg) = left;
+		sg = sg_next(sg);
+	}
+
+	return sg;
+}
+
+static noinline struct sg_table *
+intel_rotate_pages(struct intel_rotation_info *rot_info,
+		   struct drm_i915_gem_object *obj)
+{
+	unsigned int size = intel_rotation_info_size(rot_info);
+	struct drm_i915_private *i915 = to_i915(obj->base.dev);
+	struct sg_table *st;
+	struct scatterlist *sg;
+	int ret = -ENOMEM;
+	int i;
+
+	/* Allocate target SG list. */
+	st = kmalloc(sizeof(*st), GFP_KERNEL);
+	if (!st)
+		goto err_st_alloc;
+
+	ret = sg_alloc_table(st, size, GFP_KERNEL);
+	if (ret)
+		goto err_sg_alloc;
+
+	st->nents = 0;
+	sg = st->sgl;
+
+	for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++)
+		sg = rotate_pages(obj, rot_info->plane[i].offset,
+				  rot_info->plane[i].width, rot_info->plane[i].height,
+				  rot_info->plane[i].src_stride,
+				  rot_info->plane[i].dst_stride,
+				  st, sg);
+
+	return st;
+
+err_sg_alloc:
+	kfree(st);
+err_st_alloc:
+
+	drm_dbg(&i915->drm, "Failed to create rotated mapping for object size %zu! (%ux%u tiles, %u pages)\n",
+		obj->base.size, rot_info->plane[0].width,
+		rot_info->plane[0].height, size);
+
+	return ERR_PTR(ret);
+}
+
+static struct scatterlist *
+remap_pages(struct drm_i915_gem_object *obj,
+	    unsigned int offset, unsigned int alignment_pad,
+	    unsigned int width, unsigned int height,
+	    unsigned int src_stride, unsigned int dst_stride,
+	    struct sg_table *st, struct scatterlist *sg)
+{
+	unsigned int row;
+
+	if (alignment_pad) {
+		st->nents++;
+
+		/*
+		 * The DE ignores the PTEs for the padding tiles, the sg entry
+		 * here is just a convenience to indicate how many padding PTEs
+		 * to insert at this spot.
+		 */
+		sg_set_page(sg, NULL, alignment_pad * 4096, 0);
+		sg_dma_address(sg) = 0;
+		sg_dma_len(sg) = alignment_pad * 4096;
+		sg = sg_next(sg);
+	}
+
+	for (row = 0; row < height; row++) {
+		unsigned int left = width * I915_GTT_PAGE_SIZE;
+
+		while (left) {
+			dma_addr_t addr;
+			unsigned int length;
+
+			/*
+			 * We don't need the pages, but need to initialize
+			 * the entries so the sg list can be happily traversed.
+			 * The only thing we need are DMA addresses.
+			 */
+
+			addr = i915_gem_object_get_dma_address_len(obj, offset, &length);
+
+			length = min(left, length);
+
+			st->nents++;
+
+			sg_set_page(sg, NULL, length, 0);
+			sg_dma_address(sg) = addr;
+			sg_dma_len(sg) = length;
+			sg = sg_next(sg);
+
+			offset += length / I915_GTT_PAGE_SIZE;
+			left -= length;
+		}
+
+		offset += src_stride - width;
+
+		left = (dst_stride - width) * I915_GTT_PAGE_SIZE;
+
+		if (!left)
+			continue;
+
+		st->nents++;
+
+		/*
+		 * The DE ignores the PTEs for the padding tiles, the sg entry
+		 * here is just a conenience to indicate how many padding PTEs
+		 * to insert at this spot.
+		 */
+		sg_set_page(sg, NULL, left, 0);
+		sg_dma_address(sg) = 0;
+		sg_dma_len(sg) = left;
+		sg = sg_next(sg);
+	}
+
+	return sg;
+}
+
+static noinline struct sg_table *
+intel_remap_pages(struct intel_remapped_info *rem_info,
+		  struct drm_i915_gem_object *obj)
+{
+	unsigned int size = intel_remapped_info_size(rem_info);
+	struct drm_i915_private *i915 = to_i915(obj->base.dev);
+	struct sg_table *st;
+	struct scatterlist *sg;
+	unsigned int gtt_offset = 0;
+	int ret = -ENOMEM;
+	int i;
+
+	/* Allocate target SG list. */
+	st = kmalloc(sizeof(*st), GFP_KERNEL);
+	if (!st)
+		goto err_st_alloc;
+
+	ret = sg_alloc_table(st, size, GFP_KERNEL);
+	if (ret)
+		goto err_sg_alloc;
+
+	st->nents = 0;
+	sg = st->sgl;
+
+	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
+		unsigned int alignment_pad = 0;
+
+		if (rem_info->plane_alignment)
+			alignment_pad = ALIGN(gtt_offset, rem_info->plane_alignment) - gtt_offset;
+
+		sg = remap_pages(obj,
+				 rem_info->plane[i].offset, alignment_pad,
+				 rem_info->plane[i].width, rem_info->plane[i].height,
+				 rem_info->plane[i].src_stride, rem_info->plane[i].dst_stride,
+				 st, sg);
+
+		gtt_offset += alignment_pad +
+			      rem_info->plane[i].dst_stride * rem_info->plane[i].height;
+	}
+
+	i915_sg_trim(st);
+
+	return st;
+
+err_sg_alloc:
+	kfree(st);
+err_st_alloc:
+
+	drm_dbg(&i915->drm, "Failed to create remapped mapping for object size %zu! (%ux%u tiles, %u pages)\n",
+		obj->base.size, rem_info->plane[0].width,
+		rem_info->plane[0].height, size);
+
+	return ERR_PTR(ret);
+}
+
+static noinline struct sg_table *
+intel_partial_pages(const struct i915_ggtt_view *view,
+		    struct drm_i915_gem_object *obj)
+{
+	struct sg_table *st;
+	struct scatterlist *sg, *iter;
+	unsigned int count = view->partial.size;
+	unsigned int offset;
+	int ret = -ENOMEM;
+
+	st = kmalloc(sizeof(*st), GFP_KERNEL);
+	if (!st)
+		goto err_st_alloc;
+
+	ret = sg_alloc_table(st, count, GFP_KERNEL);
+	if (ret)
+		goto err_sg_alloc;
+
+	iter = i915_gem_object_get_sg_dma(obj, view->partial.offset, &offset);
+	GEM_BUG_ON(!iter);
+
+	sg = st->sgl;
+	st->nents = 0;
+	do {
+		unsigned int len;
+
+		len = min(sg_dma_len(iter) - (offset << PAGE_SHIFT),
+			  count << PAGE_SHIFT);
+		sg_set_page(sg, NULL, len, 0);
+		sg_dma_address(sg) =
+			sg_dma_address(iter) + (offset << PAGE_SHIFT);
+		sg_dma_len(sg) = len;
+
+		st->nents++;
+		count -= len >> PAGE_SHIFT;
+		if (count == 0) {
+			sg_mark_end(sg);
+			i915_sg_trim(st); /* Drop any unused tail entries. */
+
+			return st;
+		}
+
+		sg = __sg_next(sg);
+		iter = __sg_next(iter);
+		offset = 0;
+	} while (1);
+
+err_sg_alloc:
+	kfree(st);
+err_st_alloc:
+	return ERR_PTR(ret);
+}
+
+static int
+__i915_vma_get_pages(struct i915_vma *vma)
+{
+	struct sg_table *pages;
+	int ret;
+
+	/*
+	 * The vma->pages are only valid within the lifespan of the borrowed
+	 * obj->mm.pages. When the obj->mm.pages sg_table is regenerated, so
+	 * must be the vma->pages. A simple rule is that vma->pages must only
+	 * be accessed when the obj->mm.pages are pinned.
+	 */
+	GEM_BUG_ON(!i915_gem_object_has_pinned_pages(vma->obj));
+
+	switch (vma->ggtt_view.type) {
+	default:
+		GEM_BUG_ON(vma->ggtt_view.type);
+		fallthrough;
+	case I915_GGTT_VIEW_NORMAL:
+		pages = vma->obj->mm.pages;
+		break;
+
+	case I915_GGTT_VIEW_ROTATED:
+		pages =
+			intel_rotate_pages(&vma->ggtt_view.rotated, vma->obj);
+		break;
+
+	case I915_GGTT_VIEW_REMAPPED:
+		pages =
+			intel_remap_pages(&vma->ggtt_view.remapped, vma->obj);
+		break;
+
+	case I915_GGTT_VIEW_PARTIAL:
+		pages = intel_partial_pages(&vma->ggtt_view, vma->obj);
+		break;
+	}
+
+	ret = 0;
+	/* gen6 ppgtt doesn't have backing pages, special-case it */
+	if (IS_ERR(pages) && pages != ERR_PTR(-ENODEV)) {
+		ret = PTR_ERR(pages);
+		pages = NULL;
+		drm_err(&vma->vm->i915->drm,
+			"Failed to get pages for VMA view type %u (%d)!\n",
+			vma->ggtt_view.type, ret);
+	}
+
+	pages = xchg(&vma->pages, pages);
+
+	/* did we race against a put_pages? */
+	if (pages && pages != vma->obj->mm.pages) {
+		sg_free_table(vma->pages);
+		kfree(vma->pages);
+	}
+
+	return ret;
+}
+
+I915_SELFTEST_EXPORT int i915_vma_get_pages(struct i915_vma *vma)
+{
+	int err;
 
 	if (atomic_add_unless(&vma->pages_count, 1, 0))
 		return 0;
@@ -801,25 +1133,17 @@ static int vma_get_pages(struct i915_vma *vma)
 	if (err)
 		return err;
 
-	/* Allocations ahoy! */
-	if (mutex_lock_interruptible(&vma->pages_mutex)) {
-		err = -EINTR;
-		goto unpin;
-	}
+	err = __i915_vma_get_pages(vma);
+	if (err)
+		goto err_unpin;
 
-	if (!atomic_read(&vma->pages_count)) {
-		err = vma->ops->set_pages(vma);
-		if (err)
-			goto unlock;
-		pinned_pages = false;
-	}
+	vma->page_sizes = vma->obj->mm.page_sizes;
 	atomic_inc(&vma->pages_count);
 
-unlock:
-	mutex_unlock(&vma->pages_mutex);
-unpin:
-	if (pinned_pages)
-		__i915_gem_object_unpin_pages(vma->obj);
+	return 0;
+
+err_unpin:
+	__i915_gem_object_unpin_pages(vma->obj);
 
 	return err;
 }
@@ -827,18 +1151,22 @@ static int vma_get_pages(struct i915_vma *vma)
 static void __vma_put_pages(struct i915_vma *vma, unsigned int count)
 {
 	/* We allocate under vma_get_pages, so beware the shrinker */
-	mutex_lock_nested(&vma->pages_mutex, SINGLE_DEPTH_NESTING);
+	struct sg_table *pages = READ_ONCE(vma->pages);
+
 	GEM_BUG_ON(atomic_read(&vma->pages_count) < count);
+
 	if (atomic_sub_return(count, &vma->pages_count) == 0) {
-		vma->ops->clear_pages(vma);
-		GEM_BUG_ON(vma->pages);
+		if (pages == cmpxchg(&vma->pages, pages, NULL) &&
+		    pages != vma->obj->mm.pages) {
+			sg_free_table(pages);
+			kfree(pages);
+		}
 
 		i915_gem_object_unpin_pages(vma->obj);
 	}
-	mutex_unlock(&vma->pages_mutex);
 }
 
-static void vma_put_pages(struct i915_vma *vma)
+I915_SELFTEST_EXPORT void i915_vma_put_pages(struct i915_vma *vma)
 {
 	if (atomic_add_unless(&vma->pages_count, -1, 1))
 		return;
@@ -868,10 +1196,8 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 	unsigned int bound;
 	int err;
 
-#ifdef CONFIG_PROVE_LOCKING
-	if (debug_locks && !WARN_ON(!ww))
-		assert_vma_held(vma);
-#endif
+	assert_vma_held(vma);
+	GEM_BUG_ON(!ww);
 
 	BUILD_BUG_ON(PIN_GLOBAL != I915_VMA_GLOBAL_BIND);
 	BUILD_BUG_ON(PIN_USER != I915_VMA_LOCAL_BIND);
@@ -882,7 +1208,7 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 	if (try_qad_pin(vma, flags & I915_VMA_BIND_MASK))
 		return 0;
 
-	err = vma_get_pages(vma);
+	err = i915_vma_get_pages(vma);
 	if (err)
 		return err;
 
@@ -1007,7 +1333,7 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 err_rpm:
 	if (wakeref)
 		intel_runtime_pm_put(&vma->vm->i915->runtime_pm, wakeref);
-	vma_put_pages(vma);
+	i915_vma_put_pages(vma);
 	return err;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 9a931ecb09e5..32719431b3df 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -431,4 +431,7 @@ static inline int i915_vma_sync(struct i915_vma *vma)
 void i915_vma_module_exit(void);
 int i915_vma_module_init(void);
 
+I915_SELFTEST_DECLARE(int i915_vma_get_pages(struct i915_vma *vma));
+I915_SELFTEST_DECLARE(void i915_vma_put_pages(struct i915_vma *vma));
+
 #endif
diff --git a/drivers/gpu/drm/i915/i915_vma_types.h b/drivers/gpu/drm/i915/i915_vma_types.h
index 8a0decb19bcc..412d3e78a30d 100644
--- a/drivers/gpu/drm/i915/i915_vma_types.h
+++ b/drivers/gpu/drm/i915/i915_vma_types.h
@@ -261,7 +261,6 @@ struct i915_vma {
 #define I915_VMA_PAGES_BIAS 24
 #define I915_VMA_PAGES_ACTIVE (BIT(24) | 1)
 	atomic_t pages_count; /* number of active binds to the pages */
-	struct mutex pages_mutex; /* protect acquire/release of backing pages */
 
 	/**
 	 * Support different GGTT views into the same object.
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 46f4236039a9..4574fb51b656 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -1953,7 +1953,9 @@ static int igt_cs_tlb(void *arg)
 				goto end;
 			}
 
-			err = vma->ops->set_pages(vma);
+			i915_gem_object_lock(bbe, NULL);
+			err = i915_vma_get_pages(vma);
+			i915_gem_object_unlock(bbe);
 			if (err)
 				goto end;
 
@@ -1994,7 +1996,7 @@ static int igt_cs_tlb(void *arg)
 				i915_request_put(rq);
 			}
 
-			vma->ops->clear_pages(vma);
+			i915_vma_put_pages(vma);
 
 			err = context_sync(ce);
 			if (err) {
@@ -2009,7 +2011,9 @@ static int igt_cs_tlb(void *arg)
 				goto end;
 			}
 
-			err = vma->ops->set_pages(vma);
+			i915_gem_object_lock(act, NULL);
+			err = i915_vma_get_pages(vma);
+			i915_gem_object_unlock(act);
 			if (err)
 				goto end;
 
@@ -2047,7 +2051,7 @@ static int igt_cs_tlb(void *arg)
 			}
 			end_spin(batch, count - 1);
 
-			vma->ops->clear_pages(vma);
+			i915_vma_put_pages(vma);
 
 			err = context_sync(ce);
 			if (err) {
diff --git a/drivers/gpu/drm/i915/selftests/mock_gtt.c b/drivers/gpu/drm/i915/selftests/mock_gtt.c
index cc047ec594f9..096679014d99 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gtt.c
@@ -86,8 +86,6 @@ struct i915_ppgtt *mock_ppgtt(struct drm_i915_private *i915, const char *name)
 
 	ppgtt->vm.vma_ops.bind_vma    = mock_bind_ppgtt;
 	ppgtt->vm.vma_ops.unbind_vma  = mock_unbind_ppgtt;
-	ppgtt->vm.vma_ops.set_pages   = ppgtt_set_pages;
-	ppgtt->vm.vma_ops.clear_pages = clear_pages;
 
 	return ppgtt;
 }
@@ -126,8 +124,6 @@ void mock_init_ggtt(struct drm_i915_private *i915, struct i915_ggtt *ggtt)
 
 	ggtt->vm.vma_ops.bind_vma    = mock_bind_ggtt;
 	ggtt->vm.vma_ops.unbind_vma  = mock_unbind_ggtt;
-	ggtt->vm.vma_ops.set_pages   = ggtt_set_pages;
-	ggtt->vm.vma_ops.clear_pages = clear_pages;
 
 	i915_address_space_init(&ggtt->vm, VM_CLASS_GGTT);
 	i915->gt.ggtt = ggtt;
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 14/28] drm/i915: Take object lock in i915_ggtt_pin if ww is not set
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:35   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

i915_vma_wait_for_bind needs the vma lock held, fix the caller.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_vma.c | 40 +++++++++++++++++++++++----------
 1 file changed, 28 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index bacc8d68e495..2877dcd62acb 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -1348,23 +1348,15 @@ static void flush_idle_contexts(struct intel_gt *gt)
 	intel_gt_wait_for_idle(gt, MAX_SCHEDULE_TIMEOUT);
 }
 
-int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
-		  u32 align, unsigned int flags)
+static int __i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
+			   u32 align, unsigned int flags)
 {
 	struct i915_address_space *vm = vma->vm;
 	int err;
 
-	GEM_BUG_ON(!i915_vma_is_ggtt(vma));
-
-#ifdef CONFIG_LOCKDEP
-	WARN_ON(!ww && dma_resv_held(vma->obj->base.resv));
-#endif
-
 	do {
-		if (ww)
-			err = i915_vma_pin_ww(vma, ww, 0, align, flags | PIN_GLOBAL);
-		else
-			err = i915_vma_pin(vma, 0, align, flags | PIN_GLOBAL);
+		err = i915_vma_pin_ww(vma, ww, 0, align, flags | PIN_GLOBAL);
+
 		if (err != -ENOSPC) {
 			if (!err) {
 				err = i915_vma_wait_for_bind(vma);
@@ -1383,6 +1375,30 @@ int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 	} while (1);
 }
 
+int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
+		  u32 align, unsigned int flags)
+{
+	struct i915_gem_ww_ctx _ww;
+	int err;
+
+	GEM_BUG_ON(!i915_vma_is_ggtt(vma));
+
+	if (ww)
+		return __i915_ggtt_pin(vma, ww, align, flags);
+
+#ifdef CONFIG_LOCKDEP
+	WARN_ON(dma_resv_held(vma->obj->base.resv));
+#endif
+
+	for_i915_gem_ww(&_ww, err, true) {
+		err = i915_gem_object_lock(vma->obj, &_ww);
+		if (!err)
+			err = __i915_ggtt_pin(vma, &_ww, align, flags);
+	}
+
+	return err;
+}
+
 static void __vma_close(struct i915_vma *vma, struct intel_gt *gt)
 {
 	/*
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 14/28] drm/i915: Take object lock in i915_ggtt_pin if ww is not set
@ 2021-10-21 10:35   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

i915_vma_wait_for_bind needs the vma lock held, fix the caller.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_vma.c | 40 +++++++++++++++++++++++----------
 1 file changed, 28 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index bacc8d68e495..2877dcd62acb 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -1348,23 +1348,15 @@ static void flush_idle_contexts(struct intel_gt *gt)
 	intel_gt_wait_for_idle(gt, MAX_SCHEDULE_TIMEOUT);
 }
 
-int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
-		  u32 align, unsigned int flags)
+static int __i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
+			   u32 align, unsigned int flags)
 {
 	struct i915_address_space *vm = vma->vm;
 	int err;
 
-	GEM_BUG_ON(!i915_vma_is_ggtt(vma));
-
-#ifdef CONFIG_LOCKDEP
-	WARN_ON(!ww && dma_resv_held(vma->obj->base.resv));
-#endif
-
 	do {
-		if (ww)
-			err = i915_vma_pin_ww(vma, ww, 0, align, flags | PIN_GLOBAL);
-		else
-			err = i915_vma_pin(vma, 0, align, flags | PIN_GLOBAL);
+		err = i915_vma_pin_ww(vma, ww, 0, align, flags | PIN_GLOBAL);
+
 		if (err != -ENOSPC) {
 			if (!err) {
 				err = i915_vma_wait_for_bind(vma);
@@ -1383,6 +1375,30 @@ int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 	} while (1);
 }
 
+int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
+		  u32 align, unsigned int flags)
+{
+	struct i915_gem_ww_ctx _ww;
+	int err;
+
+	GEM_BUG_ON(!i915_vma_is_ggtt(vma));
+
+	if (ww)
+		return __i915_ggtt_pin(vma, ww, align, flags);
+
+#ifdef CONFIG_LOCKDEP
+	WARN_ON(dma_resv_held(vma->obj->base.resv));
+#endif
+
+	for_i915_gem_ww(&_ww, err, true) {
+		err = i915_gem_object_lock(vma->obj, &_ww);
+		if (!err)
+			err = __i915_ggtt_pin(vma, &_ww, align, flags);
+	}
+
+	return err;
+}
+
 static void __vma_close(struct i915_vma *vma, struct intel_gt *gt)
 {
 	/*
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 15/28] drm/i915: Add lock for unbinding to i915_gem_object_ggtt_pin_ww
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:35   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 981e383d1a5d..6aa9e465b48e 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -931,7 +931,14 @@ i915_gem_object_ggtt_pin_ww(struct drm_i915_gem_object *obj,
 			goto new_vma;
 		}
 
-		ret = i915_vma_unbind(vma);
+		ret = 0;
+		if (!ww)
+			ret = i915_gem_object_lock_interruptible(obj, NULL);
+		if (!ret) {
+			ret = i915_vma_unbind(vma);
+			if (!ww)
+				i915_gem_object_unlock(obj);
+		}
 		if (ret)
 			return ERR_PTR(ret);
 	}
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 15/28] drm/i915: Add lock for unbinding to i915_gem_object_ggtt_pin_ww
@ 2021-10-21 10:35   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 981e383d1a5d..6aa9e465b48e 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -931,7 +931,14 @@ i915_gem_object_ggtt_pin_ww(struct drm_i915_gem_object *obj,
 			goto new_vma;
 		}
 
-		ret = i915_vma_unbind(vma);
+		ret = 0;
+		if (!ww)
+			ret = i915_gem_object_lock_interruptible(obj, NULL);
+		if (!ret) {
+			ret = i915_vma_unbind(vma);
+			if (!ww)
+				i915_gem_object_unlock(obj);
+		}
 		if (ret)
 			return ERR_PTR(ret);
 	}
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 16/28] drm/i915: Rework context handling in hugepages selftests
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:35   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

In the next commit, we don't evict when refcount = 0, so we need to
call drain freed objects, because we want to pin new bo's in the same
place, causing a test failure.

Furthermore, since each subtest is separated, it's a lot better to use
i915_live_selftests, so each subtest starts with a clean slate, and a
clean address space.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 .../gpu/drm/i915/gem/selftests/huge_pages.c   | 127 +++++++++++-------
 1 file changed, 79 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index b2003133deaf..493509f90b35 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -22,6 +22,21 @@
 #include "selftests/mock_region.h"
 #include "selftests/i915_random.h"
 
+struct i915_gem_context *hugepage_ctx(struct drm_i915_private *i915, struct file *file)
+{
+	struct i915_gem_context *ctx = live_context(i915, file);
+	struct i915_address_space *vm;
+
+	if (IS_ERR(ctx))
+		return ctx;
+
+	vm = ctx->vm;
+	if (vm)
+		WRITE_ONCE(vm->scrub_64K, true);
+
+	return ctx;
+}
+
 static const unsigned int page_sizes[] = {
 	I915_GTT_PAGE_SIZE_2M,
 	I915_GTT_PAGE_SIZE_64K,
@@ -959,6 +974,8 @@ static int igt_mock_ppgtt_64K(void *arg)
 			__i915_gem_object_put_pages(obj);
 			i915_gem_object_unlock(obj);
 			i915_gem_object_put(obj);
+
+			i915_gem_drain_freed_objects(i915);
 		}
 	}
 
@@ -1080,10 +1097,6 @@ static int __igt_write_huge(struct intel_context *ce,
 	if (IS_ERR(vma))
 		return PTR_ERR(vma);
 
-	err = i915_vma_unbind(vma);
-	if (err)
-		return err;
-
 	err = i915_vma_pin(vma, size, 0, flags | offset);
 	if (err) {
 		/*
@@ -1117,7 +1130,7 @@ static int __igt_write_huge(struct intel_context *ce,
 	return err;
 }
 
-static int igt_write_huge(struct i915_gem_context *ctx,
+static int igt_write_huge(struct drm_i915_private *i915,
 			  struct drm_i915_gem_object *obj)
 {
 	struct i915_gem_engines *engines;
@@ -1127,6 +1140,8 @@ static int igt_write_huge(struct i915_gem_context *ctx,
 	IGT_TIMEOUT(end_time);
 	unsigned int max_page_size;
 	unsigned int count;
+	struct i915_gem_context *ctx;
+	struct file *file;
 	u64 max;
 	u64 num;
 	u64 size;
@@ -1134,6 +1149,16 @@ static int igt_write_huge(struct i915_gem_context *ctx,
 	int i, n;
 	int err = 0;
 
+	file = mock_file(i915);
+	if (IS_ERR(file))
+		return PTR_ERR(file);
+
+	ctx = hugepage_ctx(i915, file);
+	if (IS_ERR(ctx)) {
+		err = PTR_ERR(ctx);
+		goto out;
+	}
+
 	GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
 
 	size = obj->base.size;
@@ -1153,7 +1178,7 @@ static int igt_write_huge(struct i915_gem_context *ctx,
 	}
 	i915_gem_context_unlock_engines(ctx);
 	if (!n)
-		return 0;
+		goto out;
 
 	/*
 	 * To keep things interesting when alternating between engines in our
@@ -1215,6 +1240,8 @@ static int igt_write_huge(struct i915_gem_context *ctx,
 
 	kfree(order);
 
+out:
+	fput(file);
 	return err;
 }
 
@@ -1277,8 +1304,7 @@ static u32 igt_random_size(struct rnd_state *prng,
 
 static int igt_ppgtt_smoke_huge(void *arg)
 {
-	struct i915_gem_context *ctx = arg;
-	struct drm_i915_private *i915 = ctx->i915;
+	struct drm_i915_private *i915 = arg;
 	struct drm_i915_gem_object *obj;
 	I915_RND_STATE(prng);
 	struct {
@@ -1302,6 +1328,7 @@ static int igt_ppgtt_smoke_huge(void *arg)
 		u32 min = backends[i].min;
 		u32 max = backends[i].max;
 		u32 size = max;
+
 try_again:
 		size = igt_random_size(&prng, min, rounddown_pow_of_two(size));
 
@@ -1336,7 +1363,7 @@ static int igt_ppgtt_smoke_huge(void *arg)
 			goto out_unpin;
 		}
 
-		err = igt_write_huge(ctx, obj);
+		err = igt_write_huge(i915, obj);
 		if (err) {
 			pr_err("%s write-huge failed with size=%u, i=%d\n",
 			       __func__, size, i);
@@ -1363,8 +1390,7 @@ static int igt_ppgtt_smoke_huge(void *arg)
 
 static int igt_ppgtt_sanity_check(void *arg)
 {
-	struct i915_gem_context *ctx = arg;
-	struct drm_i915_private *i915 = ctx->i915;
+	struct drm_i915_private *i915 = arg;
 	unsigned int supported = INTEL_INFO(i915)->page_sizes;
 	struct {
 		igt_create_fn fn;
@@ -1431,7 +1457,7 @@ static int igt_ppgtt_sanity_check(void *arg)
 			if (pages)
 				obj->mm.page_sizes.sg = pages;
 
-			err = igt_write_huge(ctx, obj);
+			err = igt_write_huge(i915, obj);
 
 			i915_gem_object_lock(obj, NULL);
 			i915_gem_object_unpin_pages(obj);
@@ -1458,15 +1484,27 @@ static int igt_ppgtt_sanity_check(void *arg)
 
 static int igt_tmpfs_fallback(void *arg)
 {
-	struct i915_gem_context *ctx = arg;
-	struct drm_i915_private *i915 = ctx->i915;
+	struct drm_i915_private *i915 = arg;
+	struct i915_address_space *vm;
+	struct i915_gem_context *ctx;
 	struct vfsmount *gemfs = i915->mm.gemfs;
-	struct i915_address_space *vm = i915_gem_context_get_eb_vm(ctx);
 	struct drm_i915_gem_object *obj;
 	struct i915_vma *vma;
+	struct file *file;
 	u32 *vaddr;
 	int err = 0;
 
+	file = mock_file(i915);
+	if (IS_ERR(file))
+		return PTR_ERR(file);
+
+	ctx = hugepage_ctx(i915, file);
+	if (IS_ERR(ctx)) {
+		err = PTR_ERR(ctx);
+		goto out;
+	}
+	vm = i915_gem_context_get_eb_vm(ctx);
+
 	/*
 	 * Make sure that we don't burst into a ball of flames upon falling back
 	 * to tmpfs, which we rely on if on the off-chance we encouter a failure
@@ -1510,33 +1548,47 @@ static int igt_tmpfs_fallback(void *arg)
 	i915->mm.gemfs = gemfs;
 
 	i915_vm_put(vm);
+out:
+	fput(file);
 	return err;
 }
 
 static int igt_shrink_thp(void *arg)
 {
-	struct i915_gem_context *ctx = arg;
-	struct drm_i915_private *i915 = ctx->i915;
-	struct i915_address_space *vm = i915_gem_context_get_eb_vm(ctx);
+	struct drm_i915_private *i915 = arg;
+	struct i915_address_space *vm;
+	struct i915_gem_context *ctx;
 	struct drm_i915_gem_object *obj;
 	struct i915_gem_engines_iter it;
 	struct intel_context *ce;
 	struct i915_vma *vma;
+	struct file *file;
 	unsigned int flags = PIN_USER;
 	unsigned int n;
 	bool should_swap;
-	int err = 0;
+	int err;
+
+	if (!igt_can_allocate_thp(i915)) {
+		pr_info("missing THP support, skipping\n");
+		return 0;
+	}
+
+	file = mock_file(i915);
+	if (IS_ERR(file))
+		return PTR_ERR(file);
+
+	ctx = hugepage_ctx(i915, file);
+	if (IS_ERR(ctx)) {
+		err = PTR_ERR(ctx);
+		goto out;
+	}
+	vm = i915_gem_context_get_eb_vm(ctx);
 
 	/*
 	 * Sanity check shrinking huge-paged object -- make sure nothing blows
 	 * up.
 	 */
 
-	if (!igt_can_allocate_thp(i915)) {
-		pr_info("missing THP support, skipping\n");
-		goto out_vm;
-	}
-
 	obj = i915_gem_object_create_shmem(i915, SZ_2M);
 	if (IS_ERR(obj)) {
 		err = PTR_ERR(obj);
@@ -1626,7 +1678,8 @@ static int igt_shrink_thp(void *arg)
 	i915_gem_object_put(obj);
 out_vm:
 	i915_vm_put(vm);
-
+out:
+	fput(file);
 	return err;
 }
 
@@ -1687,10 +1740,6 @@ int i915_gem_huge_page_live_selftests(struct drm_i915_private *i915)
 		SUBTEST(igt_ppgtt_smoke_huge),
 		SUBTEST(igt_ppgtt_sanity_check),
 	};
-	struct i915_gem_context *ctx;
-	struct i915_address_space *vm;
-	struct file *file;
-	int err;
 
 	if (!HAS_PPGTT(i915)) {
 		pr_info("PPGTT not supported, skipping live-selftests\n");
@@ -1700,23 +1749,5 @@ int i915_gem_huge_page_live_selftests(struct drm_i915_private *i915)
 	if (intel_gt_is_wedged(&i915->gt))
 		return 0;
 
-	file = mock_file(i915);
-	if (IS_ERR(file))
-		return PTR_ERR(file);
-
-	ctx = live_context(i915, file);
-	if (IS_ERR(ctx)) {
-		err = PTR_ERR(ctx);
-		goto out_file;
-	}
-
-	vm = ctx->vm;
-	if (vm)
-		WRITE_ONCE(vm->scrub_64K, true);
-
-	err = i915_subtests(tests, ctx);
-
-out_file:
-	fput(file);
-	return err;
+	return i915_live_subtests(tests, i915);
 }
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 16/28] drm/i915: Rework context handling in hugepages selftests
@ 2021-10-21 10:35   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

In the next commit, we don't evict when refcount = 0, so we need to
call drain freed objects, because we want to pin new bo's in the same
place, causing a test failure.

Furthermore, since each subtest is separated, it's a lot better to use
i915_live_selftests, so each subtest starts with a clean slate, and a
clean address space.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 .../gpu/drm/i915/gem/selftests/huge_pages.c   | 127 +++++++++++-------
 1 file changed, 79 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index b2003133deaf..493509f90b35 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -22,6 +22,21 @@
 #include "selftests/mock_region.h"
 #include "selftests/i915_random.h"
 
+struct i915_gem_context *hugepage_ctx(struct drm_i915_private *i915, struct file *file)
+{
+	struct i915_gem_context *ctx = live_context(i915, file);
+	struct i915_address_space *vm;
+
+	if (IS_ERR(ctx))
+		return ctx;
+
+	vm = ctx->vm;
+	if (vm)
+		WRITE_ONCE(vm->scrub_64K, true);
+
+	return ctx;
+}
+
 static const unsigned int page_sizes[] = {
 	I915_GTT_PAGE_SIZE_2M,
 	I915_GTT_PAGE_SIZE_64K,
@@ -959,6 +974,8 @@ static int igt_mock_ppgtt_64K(void *arg)
 			__i915_gem_object_put_pages(obj);
 			i915_gem_object_unlock(obj);
 			i915_gem_object_put(obj);
+
+			i915_gem_drain_freed_objects(i915);
 		}
 	}
 
@@ -1080,10 +1097,6 @@ static int __igt_write_huge(struct intel_context *ce,
 	if (IS_ERR(vma))
 		return PTR_ERR(vma);
 
-	err = i915_vma_unbind(vma);
-	if (err)
-		return err;
-
 	err = i915_vma_pin(vma, size, 0, flags | offset);
 	if (err) {
 		/*
@@ -1117,7 +1130,7 @@ static int __igt_write_huge(struct intel_context *ce,
 	return err;
 }
 
-static int igt_write_huge(struct i915_gem_context *ctx,
+static int igt_write_huge(struct drm_i915_private *i915,
 			  struct drm_i915_gem_object *obj)
 {
 	struct i915_gem_engines *engines;
@@ -1127,6 +1140,8 @@ static int igt_write_huge(struct i915_gem_context *ctx,
 	IGT_TIMEOUT(end_time);
 	unsigned int max_page_size;
 	unsigned int count;
+	struct i915_gem_context *ctx;
+	struct file *file;
 	u64 max;
 	u64 num;
 	u64 size;
@@ -1134,6 +1149,16 @@ static int igt_write_huge(struct i915_gem_context *ctx,
 	int i, n;
 	int err = 0;
 
+	file = mock_file(i915);
+	if (IS_ERR(file))
+		return PTR_ERR(file);
+
+	ctx = hugepage_ctx(i915, file);
+	if (IS_ERR(ctx)) {
+		err = PTR_ERR(ctx);
+		goto out;
+	}
+
 	GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
 
 	size = obj->base.size;
@@ -1153,7 +1178,7 @@ static int igt_write_huge(struct i915_gem_context *ctx,
 	}
 	i915_gem_context_unlock_engines(ctx);
 	if (!n)
-		return 0;
+		goto out;
 
 	/*
 	 * To keep things interesting when alternating between engines in our
@@ -1215,6 +1240,8 @@ static int igt_write_huge(struct i915_gem_context *ctx,
 
 	kfree(order);
 
+out:
+	fput(file);
 	return err;
 }
 
@@ -1277,8 +1304,7 @@ static u32 igt_random_size(struct rnd_state *prng,
 
 static int igt_ppgtt_smoke_huge(void *arg)
 {
-	struct i915_gem_context *ctx = arg;
-	struct drm_i915_private *i915 = ctx->i915;
+	struct drm_i915_private *i915 = arg;
 	struct drm_i915_gem_object *obj;
 	I915_RND_STATE(prng);
 	struct {
@@ -1302,6 +1328,7 @@ static int igt_ppgtt_smoke_huge(void *arg)
 		u32 min = backends[i].min;
 		u32 max = backends[i].max;
 		u32 size = max;
+
 try_again:
 		size = igt_random_size(&prng, min, rounddown_pow_of_two(size));
 
@@ -1336,7 +1363,7 @@ static int igt_ppgtt_smoke_huge(void *arg)
 			goto out_unpin;
 		}
 
-		err = igt_write_huge(ctx, obj);
+		err = igt_write_huge(i915, obj);
 		if (err) {
 			pr_err("%s write-huge failed with size=%u, i=%d\n",
 			       __func__, size, i);
@@ -1363,8 +1390,7 @@ static int igt_ppgtt_smoke_huge(void *arg)
 
 static int igt_ppgtt_sanity_check(void *arg)
 {
-	struct i915_gem_context *ctx = arg;
-	struct drm_i915_private *i915 = ctx->i915;
+	struct drm_i915_private *i915 = arg;
 	unsigned int supported = INTEL_INFO(i915)->page_sizes;
 	struct {
 		igt_create_fn fn;
@@ -1431,7 +1457,7 @@ static int igt_ppgtt_sanity_check(void *arg)
 			if (pages)
 				obj->mm.page_sizes.sg = pages;
 
-			err = igt_write_huge(ctx, obj);
+			err = igt_write_huge(i915, obj);
 
 			i915_gem_object_lock(obj, NULL);
 			i915_gem_object_unpin_pages(obj);
@@ -1458,15 +1484,27 @@ static int igt_ppgtt_sanity_check(void *arg)
 
 static int igt_tmpfs_fallback(void *arg)
 {
-	struct i915_gem_context *ctx = arg;
-	struct drm_i915_private *i915 = ctx->i915;
+	struct drm_i915_private *i915 = arg;
+	struct i915_address_space *vm;
+	struct i915_gem_context *ctx;
 	struct vfsmount *gemfs = i915->mm.gemfs;
-	struct i915_address_space *vm = i915_gem_context_get_eb_vm(ctx);
 	struct drm_i915_gem_object *obj;
 	struct i915_vma *vma;
+	struct file *file;
 	u32 *vaddr;
 	int err = 0;
 
+	file = mock_file(i915);
+	if (IS_ERR(file))
+		return PTR_ERR(file);
+
+	ctx = hugepage_ctx(i915, file);
+	if (IS_ERR(ctx)) {
+		err = PTR_ERR(ctx);
+		goto out;
+	}
+	vm = i915_gem_context_get_eb_vm(ctx);
+
 	/*
 	 * Make sure that we don't burst into a ball of flames upon falling back
 	 * to tmpfs, which we rely on if on the off-chance we encouter a failure
@@ -1510,33 +1548,47 @@ static int igt_tmpfs_fallback(void *arg)
 	i915->mm.gemfs = gemfs;
 
 	i915_vm_put(vm);
+out:
+	fput(file);
 	return err;
 }
 
 static int igt_shrink_thp(void *arg)
 {
-	struct i915_gem_context *ctx = arg;
-	struct drm_i915_private *i915 = ctx->i915;
-	struct i915_address_space *vm = i915_gem_context_get_eb_vm(ctx);
+	struct drm_i915_private *i915 = arg;
+	struct i915_address_space *vm;
+	struct i915_gem_context *ctx;
 	struct drm_i915_gem_object *obj;
 	struct i915_gem_engines_iter it;
 	struct intel_context *ce;
 	struct i915_vma *vma;
+	struct file *file;
 	unsigned int flags = PIN_USER;
 	unsigned int n;
 	bool should_swap;
-	int err = 0;
+	int err;
+
+	if (!igt_can_allocate_thp(i915)) {
+		pr_info("missing THP support, skipping\n");
+		return 0;
+	}
+
+	file = mock_file(i915);
+	if (IS_ERR(file))
+		return PTR_ERR(file);
+
+	ctx = hugepage_ctx(i915, file);
+	if (IS_ERR(ctx)) {
+		err = PTR_ERR(ctx);
+		goto out;
+	}
+	vm = i915_gem_context_get_eb_vm(ctx);
 
 	/*
 	 * Sanity check shrinking huge-paged object -- make sure nothing blows
 	 * up.
 	 */
 
-	if (!igt_can_allocate_thp(i915)) {
-		pr_info("missing THP support, skipping\n");
-		goto out_vm;
-	}
-
 	obj = i915_gem_object_create_shmem(i915, SZ_2M);
 	if (IS_ERR(obj)) {
 		err = PTR_ERR(obj);
@@ -1626,7 +1678,8 @@ static int igt_shrink_thp(void *arg)
 	i915_gem_object_put(obj);
 out_vm:
 	i915_vm_put(vm);
-
+out:
+	fput(file);
 	return err;
 }
 
@@ -1687,10 +1740,6 @@ int i915_gem_huge_page_live_selftests(struct drm_i915_private *i915)
 		SUBTEST(igt_ppgtt_smoke_huge),
 		SUBTEST(igt_ppgtt_sanity_check),
 	};
-	struct i915_gem_context *ctx;
-	struct i915_address_space *vm;
-	struct file *file;
-	int err;
 
 	if (!HAS_PPGTT(i915)) {
 		pr_info("PPGTT not supported, skipping live-selftests\n");
@@ -1700,23 +1749,5 @@ int i915_gem_huge_page_live_selftests(struct drm_i915_private *i915)
 	if (intel_gt_is_wedged(&i915->gt))
 		return 0;
 
-	file = mock_file(i915);
-	if (IS_ERR(file))
-		return PTR_ERR(file);
-
-	ctx = live_context(i915, file);
-	if (IS_ERR(ctx)) {
-		err = PTR_ERR(ctx);
-		goto out_file;
-	}
-
-	vm = ctx->vm;
-	if (vm)
-		WRITE_ONCE(vm->scrub_64K, true);
-
-	err = i915_subtests(tests, ctx);
-
-out_file:
-	fput(file);
-	return err;
+	return i915_live_subtests(tests, i915);
 }
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 17/28] drm/i915: Ensure gem_contexts selftests work with unbind changes.
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:35   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

In the next commit, we don't evict when refcount = 0.

igt_vm_isolation() continuously tries to pin/unpin at same address,
but also calls put() on the object, which means the object may not
be unpinned in time.

Instead of this, re-use the same object over and over, so they can
be unbound as required.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 .../drm/i915/gem/selftests/i915_gem_context.c | 54 +++++++++++--------
 1 file changed, 32 insertions(+), 22 deletions(-)

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 b32f7fed2d9c..3fc595b57cf4 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
@@ -1481,10 +1481,10 @@ static int check_scratch(struct i915_address_space *vm, u64 offset)
 
 static int write_to_scratch(struct i915_gem_context *ctx,
 			    struct intel_engine_cs *engine,
+			    struct drm_i915_gem_object *obj,
 			    u64 offset, u32 value)
 {
 	struct drm_i915_private *i915 = ctx->i915;
-	struct drm_i915_gem_object *obj;
 	struct i915_address_space *vm;
 	struct i915_request *rq;
 	struct i915_vma *vma;
@@ -1497,15 +1497,9 @@ static int write_to_scratch(struct i915_gem_context *ctx,
 	if (err)
 		return err;
 
-	obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
-	if (IS_ERR(obj))
-		return PTR_ERR(obj);
-
 	cmd = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB);
-	if (IS_ERR(cmd)) {
-		err = PTR_ERR(cmd);
-		goto out;
-	}
+	if (IS_ERR(cmd))
+		return PTR_ERR(cmd);
 
 	*cmd++ = MI_STORE_DWORD_IMM_GEN4;
 	if (GRAPHICS_VER(i915) >= 8) {
@@ -1569,17 +1563,19 @@ static int write_to_scratch(struct i915_gem_context *ctx,
 	i915_vma_unpin(vma);
 out_vm:
 	i915_vm_put(vm);
-out:
-	i915_gem_object_put(obj);
+
+	if (!err)
+		err = i915_gem_object_wait(obj, 0, MAX_SCHEDULE_TIMEOUT);
+
 	return err;
 }
 
 static int read_from_scratch(struct i915_gem_context *ctx,
 			     struct intel_engine_cs *engine,
+			     struct drm_i915_gem_object *obj,
 			     u64 offset, u32 *value)
 {
 	struct drm_i915_private *i915 = ctx->i915;
-	struct drm_i915_gem_object *obj;
 	struct i915_address_space *vm;
 	const u32 result = 0x100;
 	struct i915_request *rq;
@@ -1594,10 +1590,6 @@ static int read_from_scratch(struct i915_gem_context *ctx,
 	if (err)
 		return err;
 
-	obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
-	if (IS_ERR(obj))
-		return PTR_ERR(obj);
-
 	if (GRAPHICS_VER(i915) >= 8) {
 		const u32 GPR0 = engine->mmio_base + 0x600;
 
@@ -1615,7 +1607,7 @@ static int read_from_scratch(struct i915_gem_context *ctx,
 		cmd = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB);
 		if (IS_ERR(cmd)) {
 			err = PTR_ERR(cmd);
-			goto out;
+			goto err_unpin;
 		}
 
 		memset(cmd, POISON_INUSE, PAGE_SIZE);
@@ -1651,7 +1643,7 @@ static int read_from_scratch(struct i915_gem_context *ctx,
 		cmd = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB);
 		if (IS_ERR(cmd)) {
 			err = PTR_ERR(cmd);
-			goto out;
+			goto err_unpin;
 		}
 
 		memset(cmd, POISON_INUSE, PAGE_SIZE);
@@ -1722,8 +1714,10 @@ static int read_from_scratch(struct i915_gem_context *ctx,
 	i915_vma_unpin(vma);
 out_vm:
 	i915_vm_put(vm);
-out:
-	i915_gem_object_put(obj);
+
+	if (!err)
+		err = i915_gem_object_wait(obj, 0, MAX_SCHEDULE_TIMEOUT);
+
 	return err;
 }
 
@@ -1765,6 +1759,7 @@ static int igt_vm_isolation(void *arg)
 	u64 vm_total;
 	u32 expected;
 	int err;
+	struct drm_i915_gem_object *obj_a, *obj_b;
 
 	if (GRAPHICS_VER(i915) < 7)
 		return 0;
@@ -1810,6 +1805,18 @@ static int igt_vm_isolation(void *arg)
 	vm_total = ctx_a->vm->total;
 	GEM_BUG_ON(ctx_b->vm->total != vm_total);
 
+	obj_a = i915_gem_object_create_internal(i915, PAGE_SIZE);
+	if (IS_ERR(obj_a)) {
+		err = PTR_ERR(obj_a);
+		goto out_file;
+	}
+
+	obj_b = i915_gem_object_create_internal(i915, PAGE_SIZE);
+	if (IS_ERR(obj_b)) {
+		err = PTR_ERR(obj_b);
+		goto put_a;
+	}
+
 	count = 0;
 	num_engines = 0;
 	for_each_uabi_engine(engine, i915) {
@@ -1832,10 +1839,10 @@ static int igt_vm_isolation(void *arg)
 						   I915_GTT_PAGE_SIZE, vm_total,
 						   sizeof(u32), alignof_dword);
 
-			err = write_to_scratch(ctx_a, engine,
+			err = write_to_scratch(ctx_a, engine, obj_a,
 					       offset, 0xdeadbeef);
 			if (err == 0)
-				err = read_from_scratch(ctx_b, engine,
+				err = read_from_scratch(ctx_b, engine, obj_b,
 							offset, &value);
 			if (err)
 				goto out_file;
@@ -1858,6 +1865,9 @@ static int igt_vm_isolation(void *arg)
 	pr_info("Checked %lu scratch offsets across %lu engines\n",
 		count, num_engines);
 
+	i915_gem_object_put(obj_b);
+put_a:
+	i915_gem_object_put(obj_a);
 out_file:
 	if (igt_live_test_end(&t))
 		err = -EIO;
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 17/28] drm/i915: Ensure gem_contexts selftests work with unbind changes.
@ 2021-10-21 10:35   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

In the next commit, we don't evict when refcount = 0.

igt_vm_isolation() continuously tries to pin/unpin at same address,
but also calls put() on the object, which means the object may not
be unpinned in time.

Instead of this, re-use the same object over and over, so they can
be unbound as required.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 .../drm/i915/gem/selftests/i915_gem_context.c | 54 +++++++++++--------
 1 file changed, 32 insertions(+), 22 deletions(-)

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 b32f7fed2d9c..3fc595b57cf4 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
@@ -1481,10 +1481,10 @@ static int check_scratch(struct i915_address_space *vm, u64 offset)
 
 static int write_to_scratch(struct i915_gem_context *ctx,
 			    struct intel_engine_cs *engine,
+			    struct drm_i915_gem_object *obj,
 			    u64 offset, u32 value)
 {
 	struct drm_i915_private *i915 = ctx->i915;
-	struct drm_i915_gem_object *obj;
 	struct i915_address_space *vm;
 	struct i915_request *rq;
 	struct i915_vma *vma;
@@ -1497,15 +1497,9 @@ static int write_to_scratch(struct i915_gem_context *ctx,
 	if (err)
 		return err;
 
-	obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
-	if (IS_ERR(obj))
-		return PTR_ERR(obj);
-
 	cmd = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB);
-	if (IS_ERR(cmd)) {
-		err = PTR_ERR(cmd);
-		goto out;
-	}
+	if (IS_ERR(cmd))
+		return PTR_ERR(cmd);
 
 	*cmd++ = MI_STORE_DWORD_IMM_GEN4;
 	if (GRAPHICS_VER(i915) >= 8) {
@@ -1569,17 +1563,19 @@ static int write_to_scratch(struct i915_gem_context *ctx,
 	i915_vma_unpin(vma);
 out_vm:
 	i915_vm_put(vm);
-out:
-	i915_gem_object_put(obj);
+
+	if (!err)
+		err = i915_gem_object_wait(obj, 0, MAX_SCHEDULE_TIMEOUT);
+
 	return err;
 }
 
 static int read_from_scratch(struct i915_gem_context *ctx,
 			     struct intel_engine_cs *engine,
+			     struct drm_i915_gem_object *obj,
 			     u64 offset, u32 *value)
 {
 	struct drm_i915_private *i915 = ctx->i915;
-	struct drm_i915_gem_object *obj;
 	struct i915_address_space *vm;
 	const u32 result = 0x100;
 	struct i915_request *rq;
@@ -1594,10 +1590,6 @@ static int read_from_scratch(struct i915_gem_context *ctx,
 	if (err)
 		return err;
 
-	obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
-	if (IS_ERR(obj))
-		return PTR_ERR(obj);
-
 	if (GRAPHICS_VER(i915) >= 8) {
 		const u32 GPR0 = engine->mmio_base + 0x600;
 
@@ -1615,7 +1607,7 @@ static int read_from_scratch(struct i915_gem_context *ctx,
 		cmd = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB);
 		if (IS_ERR(cmd)) {
 			err = PTR_ERR(cmd);
-			goto out;
+			goto err_unpin;
 		}
 
 		memset(cmd, POISON_INUSE, PAGE_SIZE);
@@ -1651,7 +1643,7 @@ static int read_from_scratch(struct i915_gem_context *ctx,
 		cmd = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB);
 		if (IS_ERR(cmd)) {
 			err = PTR_ERR(cmd);
-			goto out;
+			goto err_unpin;
 		}
 
 		memset(cmd, POISON_INUSE, PAGE_SIZE);
@@ -1722,8 +1714,10 @@ static int read_from_scratch(struct i915_gem_context *ctx,
 	i915_vma_unpin(vma);
 out_vm:
 	i915_vm_put(vm);
-out:
-	i915_gem_object_put(obj);
+
+	if (!err)
+		err = i915_gem_object_wait(obj, 0, MAX_SCHEDULE_TIMEOUT);
+
 	return err;
 }
 
@@ -1765,6 +1759,7 @@ static int igt_vm_isolation(void *arg)
 	u64 vm_total;
 	u32 expected;
 	int err;
+	struct drm_i915_gem_object *obj_a, *obj_b;
 
 	if (GRAPHICS_VER(i915) < 7)
 		return 0;
@@ -1810,6 +1805,18 @@ static int igt_vm_isolation(void *arg)
 	vm_total = ctx_a->vm->total;
 	GEM_BUG_ON(ctx_b->vm->total != vm_total);
 
+	obj_a = i915_gem_object_create_internal(i915, PAGE_SIZE);
+	if (IS_ERR(obj_a)) {
+		err = PTR_ERR(obj_a);
+		goto out_file;
+	}
+
+	obj_b = i915_gem_object_create_internal(i915, PAGE_SIZE);
+	if (IS_ERR(obj_b)) {
+		err = PTR_ERR(obj_b);
+		goto put_a;
+	}
+
 	count = 0;
 	num_engines = 0;
 	for_each_uabi_engine(engine, i915) {
@@ -1832,10 +1839,10 @@ static int igt_vm_isolation(void *arg)
 						   I915_GTT_PAGE_SIZE, vm_total,
 						   sizeof(u32), alignof_dword);
 
-			err = write_to_scratch(ctx_a, engine,
+			err = write_to_scratch(ctx_a, engine, obj_a,
 					       offset, 0xdeadbeef);
 			if (err == 0)
-				err = read_from_scratch(ctx_b, engine,
+				err = read_from_scratch(ctx_b, engine, obj_b,
 							offset, &value);
 			if (err)
 				goto out_file;
@@ -1858,6 +1865,9 @@ static int igt_vm_isolation(void *arg)
 	pr_info("Checked %lu scratch offsets across %lu engines\n",
 		count, num_engines);
 
+	i915_gem_object_put(obj_b);
+put_a:
+	i915_gem_object_put(obj_a);
 out_file:
 	if (igt_live_test_end(&t))
 		err = -EIO;
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 18/28] drm/i915: Take trylock during eviction, v2.
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:35   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

Now that freeing objects takes the object lock when destroying the
backing pages, we can confidently take the object lock even for dead
objects.

Use this fact to take the object lock in the shrinker, without requiring
a reference to the object, so all calls to unbind take the object lock.

This is the last step to requiring the object lock for vma_unbind.

Changes since v1:
- No longer require the refcount, as every freed object now holds the lock
  when unbinding VMA's.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_shrinker.c |  6 ++++
 drivers/gpu/drm/i915/i915_gem_evict.c        | 34 +++++++++++++++++---
 2 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
index d3f29a66cb36..34c12e5983eb 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
@@ -403,12 +403,18 @@ i915_gem_shrinker_vmap(struct notifier_block *nb, unsigned long event, void *ptr
 	list_for_each_entry_safe(vma, next,
 				 &i915->ggtt.vm.bound_list, vm_link) {
 		unsigned long count = vma->node.size >> PAGE_SHIFT;
+		struct drm_i915_gem_object *obj = vma->obj;
 
 		if (!vma->iomap || i915_vma_is_active(vma))
 			continue;
 
+		if (!i915_gem_object_trylock(obj))
+			continue;
+
 		if (__i915_vma_unbind(vma) == 0)
 			freed_pages += count;
+
+		i915_gem_object_unlock(obj);
 	}
 	mutex_unlock(&i915->ggtt.vm.mutex);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
index 2b73ddb11c66..286efa462eca 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -58,6 +58,9 @@ mark_free(struct drm_mm_scan *scan,
 	if (i915_vma_is_pinned(vma))
 		return false;
 
+	if (!i915_gem_object_trylock(vma->obj))
+		return false;
+
 	list_add(&vma->evict_link, unwind);
 	return drm_mm_scan_add_block(scan, &vma->node);
 }
@@ -178,6 +181,7 @@ i915_gem_evict_something(struct i915_address_space *vm,
 	list_for_each_entry_safe(vma, next, &eviction_list, evict_link) {
 		ret = drm_mm_scan_remove_block(&scan, &vma->node);
 		BUG_ON(ret);
+		i915_gem_object_unlock(vma->obj);
 	}
 
 	/*
@@ -222,10 +226,12 @@ i915_gem_evict_something(struct i915_address_space *vm,
 	 * of any of our objects, thus corrupting the list).
 	 */
 	list_for_each_entry_safe(vma, next, &eviction_list, evict_link) {
-		if (drm_mm_scan_remove_block(&scan, &vma->node))
+		if (drm_mm_scan_remove_block(&scan, &vma->node)) {
 			__i915_vma_pin(vma);
-		else
+		} else {
 			list_del(&vma->evict_link);
+			i915_gem_object_unlock(vma->obj);
+		}
 	}
 
 	/* Unbinding will emit any required flushes */
@@ -234,16 +240,22 @@ i915_gem_evict_something(struct i915_address_space *vm,
 		__i915_vma_unpin(vma);
 		if (ret == 0)
 			ret = __i915_vma_unbind(vma);
+
+		i915_gem_object_unlock(vma->obj);
 	}
 
 	while (ret == 0 && (node = drm_mm_scan_color_evict(&scan))) {
 		vma = container_of(node, struct i915_vma, node);
 
+
 		/* If we find any non-objects (!vma), we cannot evict them */
-		if (vma->node.color != I915_COLOR_UNEVICTABLE)
+		if (vma->node.color != I915_COLOR_UNEVICTABLE &&
+		    i915_gem_object_trylock(vma->obj)) {
 			ret = __i915_vma_unbind(vma);
-		else
-			ret = -ENOSPC; /* XXX search failed, try again? */
+			i915_gem_object_unlock(vma->obj);
+		} else {
+			ret = -ENOSPC;
+		}
 	}
 
 	return ret;
@@ -333,6 +345,11 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
 			break;
 		}
 
+		if (!i915_gem_object_trylock(vma->obj)) {
+			ret = -ENOSPC;
+			break;
+		}
+
 		/*
 		 * Never show fear in the face of dragons!
 		 *
@@ -350,6 +367,8 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
 		__i915_vma_unpin(vma);
 		if (ret == 0)
 			ret = __i915_vma_unbind(vma);
+
+		i915_gem_object_unlock(vma->obj);
 	}
 
 	return ret;
@@ -393,6 +412,9 @@ int i915_gem_evict_vm(struct i915_address_space *vm)
 			if (i915_vma_is_pinned(vma))
 				continue;
 
+			if (!i915_gem_object_trylock(vma->obj))
+				continue;
+
 			__i915_vma_pin(vma);
 			list_add(&vma->evict_link, &eviction_list);
 		}
@@ -406,6 +428,8 @@ int i915_gem_evict_vm(struct i915_address_space *vm)
 				ret = __i915_vma_unbind(vma);
 			if (ret != -EINTR) /* "Get me out of here!" */
 				ret = 0;
+
+			i915_gem_object_unlock(vma->obj);
 		}
 	} while (ret == 0);
 
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 18/28] drm/i915: Take trylock during eviction, v2.
@ 2021-10-21 10:35   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

Now that freeing objects takes the object lock when destroying the
backing pages, we can confidently take the object lock even for dead
objects.

Use this fact to take the object lock in the shrinker, without requiring
a reference to the object, so all calls to unbind take the object lock.

This is the last step to requiring the object lock for vma_unbind.

Changes since v1:
- No longer require the refcount, as every freed object now holds the lock
  when unbinding VMA's.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_shrinker.c |  6 ++++
 drivers/gpu/drm/i915/i915_gem_evict.c        | 34 +++++++++++++++++---
 2 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
index d3f29a66cb36..34c12e5983eb 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
@@ -403,12 +403,18 @@ i915_gem_shrinker_vmap(struct notifier_block *nb, unsigned long event, void *ptr
 	list_for_each_entry_safe(vma, next,
 				 &i915->ggtt.vm.bound_list, vm_link) {
 		unsigned long count = vma->node.size >> PAGE_SHIFT;
+		struct drm_i915_gem_object *obj = vma->obj;
 
 		if (!vma->iomap || i915_vma_is_active(vma))
 			continue;
 
+		if (!i915_gem_object_trylock(obj))
+			continue;
+
 		if (__i915_vma_unbind(vma) == 0)
 			freed_pages += count;
+
+		i915_gem_object_unlock(obj);
 	}
 	mutex_unlock(&i915->ggtt.vm.mutex);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
index 2b73ddb11c66..286efa462eca 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -58,6 +58,9 @@ mark_free(struct drm_mm_scan *scan,
 	if (i915_vma_is_pinned(vma))
 		return false;
 
+	if (!i915_gem_object_trylock(vma->obj))
+		return false;
+
 	list_add(&vma->evict_link, unwind);
 	return drm_mm_scan_add_block(scan, &vma->node);
 }
@@ -178,6 +181,7 @@ i915_gem_evict_something(struct i915_address_space *vm,
 	list_for_each_entry_safe(vma, next, &eviction_list, evict_link) {
 		ret = drm_mm_scan_remove_block(&scan, &vma->node);
 		BUG_ON(ret);
+		i915_gem_object_unlock(vma->obj);
 	}
 
 	/*
@@ -222,10 +226,12 @@ i915_gem_evict_something(struct i915_address_space *vm,
 	 * of any of our objects, thus corrupting the list).
 	 */
 	list_for_each_entry_safe(vma, next, &eviction_list, evict_link) {
-		if (drm_mm_scan_remove_block(&scan, &vma->node))
+		if (drm_mm_scan_remove_block(&scan, &vma->node)) {
 			__i915_vma_pin(vma);
-		else
+		} else {
 			list_del(&vma->evict_link);
+			i915_gem_object_unlock(vma->obj);
+		}
 	}
 
 	/* Unbinding will emit any required flushes */
@@ -234,16 +240,22 @@ i915_gem_evict_something(struct i915_address_space *vm,
 		__i915_vma_unpin(vma);
 		if (ret == 0)
 			ret = __i915_vma_unbind(vma);
+
+		i915_gem_object_unlock(vma->obj);
 	}
 
 	while (ret == 0 && (node = drm_mm_scan_color_evict(&scan))) {
 		vma = container_of(node, struct i915_vma, node);
 
+
 		/* If we find any non-objects (!vma), we cannot evict them */
-		if (vma->node.color != I915_COLOR_UNEVICTABLE)
+		if (vma->node.color != I915_COLOR_UNEVICTABLE &&
+		    i915_gem_object_trylock(vma->obj)) {
 			ret = __i915_vma_unbind(vma);
-		else
-			ret = -ENOSPC; /* XXX search failed, try again? */
+			i915_gem_object_unlock(vma->obj);
+		} else {
+			ret = -ENOSPC;
+		}
 	}
 
 	return ret;
@@ -333,6 +345,11 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
 			break;
 		}
 
+		if (!i915_gem_object_trylock(vma->obj)) {
+			ret = -ENOSPC;
+			break;
+		}
+
 		/*
 		 * Never show fear in the face of dragons!
 		 *
@@ -350,6 +367,8 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
 		__i915_vma_unpin(vma);
 		if (ret == 0)
 			ret = __i915_vma_unbind(vma);
+
+		i915_gem_object_unlock(vma->obj);
 	}
 
 	return ret;
@@ -393,6 +412,9 @@ int i915_gem_evict_vm(struct i915_address_space *vm)
 			if (i915_vma_is_pinned(vma))
 				continue;
 
+			if (!i915_gem_object_trylock(vma->obj))
+				continue;
+
 			__i915_vma_pin(vma);
 			list_add(&vma->evict_link, &eviction_list);
 		}
@@ -406,6 +428,8 @@ int i915_gem_evict_vm(struct i915_address_space *vm)
 				ret = __i915_vma_unbind(vma);
 			if (ret != -EINTR) /* "Get me out of here!" */
 				ret = 0;
+
+			i915_gem_object_unlock(vma->obj);
 		}
 	} while (ret == 0);
 
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 19/28] drm/i915: Pass trylock context to callers
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:35   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c    |  2 +-
 drivers/gpu/drm/i915/gem/i915_gem_object.h    |  8 ++++--
 drivers/gpu/drm/i915/gem/i915_gem_shrinker.c  |  4 +--
 drivers/gpu/drm/i915/gem/i915_gem_stolen.c    |  2 +-
 drivers/gpu/drm/i915/gt/intel_engine_pm.c     |  2 +-
 drivers/gpu/drm/i915/gt/intel_ggtt.c          |  2 +-
 drivers/gpu/drm/i915/gt/mock_engine.c         |  2 +-
 drivers/gpu/drm/i915/gt/selftest_hangcheck.c  |  2 +-
 drivers/gpu/drm/i915/gt/selftest_migrate.c    |  2 +-
 drivers/gpu/drm/i915/gvt/aperture_gm.c        |  2 +-
 drivers/gpu/drm/i915/i915_drv.h               |  5 +++-
 drivers/gpu/drm/i915/i915_gem_evict.c         | 15 ++++++-----
 drivers/gpu/drm/i915/i915_gem_gtt.c           |  8 +++---
 drivers/gpu/drm/i915/i915_gem_gtt.h           |  3 +++
 drivers/gpu/drm/i915/i915_vgpu.c              |  2 +-
 drivers/gpu/drm/i915/i915_vma.c               | 13 +++++----
 .../gpu/drm/i915/selftests/i915_gem_evict.c   | 27 ++++++++++++-------
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 14 +++++-----
 18 files changed, 70 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index e614591ca510..bbf2a10738f7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -764,7 +764,7 @@ static int eb_reserve(struct i915_execbuffer *eb)
 		case 1:
 			/* Too fragmented, unbind everything and retry */
 			mutex_lock(&eb->context->vm->mutex);
-			err = i915_gem_evict_vm(eb->context->vm);
+			err = i915_gem_evict_vm(eb->context->vm, &eb->ww);
 			mutex_unlock(&eb->context->vm->mutex);
 			if (err)
 				return err;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index 59201801cec5..accd8fad0ed7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -211,9 +211,13 @@ static inline int i915_gem_object_lock_interruptible(struct drm_i915_gem_object
 	return __i915_gem_object_lock(obj, ww, true);
 }
 
-static inline bool i915_gem_object_trylock(struct drm_i915_gem_object *obj)
+static inline bool i915_gem_object_trylock(struct drm_i915_gem_object *obj,
+					   struct i915_gem_ww_ctx *ww)
 {
-	return dma_resv_trylock(obj->base.resv);
+	if (!ww)
+		return dma_resv_trylock(obj->base.resv);
+	else
+		return ww_mutex_trylock(&obj->base.resv->lock, &ww->ctx);
 }
 
 static inline void i915_gem_object_unlock(struct drm_i915_gem_object *obj)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
index 34c12e5983eb..5375f3f9f016 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
@@ -210,7 +210,7 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww,
 
 			/* May arrive from get_pages on another bo */
 			if (!ww) {
-				if (!i915_gem_object_trylock(obj))
+				if (!i915_gem_object_trylock(obj, NULL))
 					goto skip;
 			} else {
 				err = i915_gem_object_lock(obj, ww);
@@ -408,7 +408,7 @@ i915_gem_shrinker_vmap(struct notifier_block *nb, unsigned long event, void *ptr
 		if (!vma->iomap || i915_vma_is_active(vma))
 			continue;
 
-		if (!i915_gem_object_trylock(obj))
+		if (!i915_gem_object_trylock(obj, NULL))
 			continue;
 
 		if (__i915_vma_unbind(vma) == 0)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
index ddd37ccb1362..d629ef5abf9a 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
@@ -653,7 +653,7 @@ static int __i915_gem_object_create_stolen(struct intel_memory_region *mem,
 	cache_level = HAS_LLC(mem->i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
 	i915_gem_object_set_cache_coherency(obj, cache_level);
 
-	if (WARN_ON(!i915_gem_object_trylock(obj)))
+	if (WARN_ON(!i915_gem_object_trylock(obj, NULL)))
 		return -EBUSY;
 
 	i915_gem_object_init_memory_region(obj, mem);
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.c b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
index 849fbb229bd3..d66c8bd50ae3 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
@@ -26,7 +26,7 @@ static void dbg_poison_ce(struct intel_context *ce)
 		int type = i915_coherent_map_type(ce->engine->i915, obj, true);
 		void *map;
 
-		if (!i915_gem_object_trylock(obj))
+		if (!i915_gem_object_trylock(obj, NULL))
 			return;
 
 		map = i915_gem_object_pin_map(obj, type);
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index 6da57199bb33..df29fd992b45 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -487,7 +487,7 @@ static int ggtt_reserve_guc_top(struct i915_ggtt *ggtt)
 	GEM_BUG_ON(ggtt->vm.total <= GUC_GGTT_TOP);
 	size = ggtt->vm.total - GUC_GGTT_TOP;
 
-	ret = i915_gem_gtt_reserve(&ggtt->vm, &ggtt->uc_fw, size,
+	ret = i915_gem_gtt_reserve(&ggtt->vm, NULL, &ggtt->uc_fw, size,
 				   GUC_GGTT_TOP, I915_COLOR_UNEVICTABLE,
 				   PIN_NOEVICT);
 	if (ret)
diff --git a/drivers/gpu/drm/i915/gt/mock_engine.c b/drivers/gpu/drm/i915/gt/mock_engine.c
index bb99fc03f503..240265354274 100644
--- a/drivers/gpu/drm/i915/gt/mock_engine.c
+++ b/drivers/gpu/drm/i915/gt/mock_engine.c
@@ -17,7 +17,7 @@ static int mock_timeline_pin(struct intel_timeline *tl)
 {
 	int err;
 
-	if (WARN_ON(!i915_gem_object_trylock(tl->hwsp_ggtt->obj)))
+	if (WARN_ON(!i915_gem_object_trylock(tl->hwsp_ggtt->obj, NULL)))
 		return -EBUSY;
 
 	err = intel_timeline_pin_map(tl);
diff --git a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
index 7e2d99dd012d..572f942c3c5d 100644
--- a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
+++ b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
@@ -1378,7 +1378,7 @@ static int evict_vma(void *data)
 	complete(&arg->completion);
 
 	mutex_lock(&vm->mutex);
-	err = i915_gem_evict_for_node(vm, &evict, 0);
+	err = i915_gem_evict_for_node(vm, NULL, &evict, 0);
 	mutex_unlock(&vm->mutex);
 
 	return err;
diff --git a/drivers/gpu/drm/i915/gt/selftest_migrate.c b/drivers/gpu/drm/i915/gt/selftest_migrate.c
index 12ef2837c89b..78993c760f12 100644
--- a/drivers/gpu/drm/i915/gt/selftest_migrate.c
+++ b/drivers/gpu/drm/i915/gt/selftest_migrate.c
@@ -464,7 +464,7 @@ create_init_lmem_internal(struct intel_gt *gt, size_t sz, bool try_lmem)
 			return obj;
 	}
 
-	i915_gem_object_trylock(obj);
+	i915_gem_object_trylock(obj, NULL);
 	err = i915_gem_object_pin_pages(obj);
 	if (err) {
 		i915_gem_object_unlock(obj);
diff --git a/drivers/gpu/drm/i915/gvt/aperture_gm.c b/drivers/gpu/drm/i915/gvt/aperture_gm.c
index 0d6d59871308..c08098a167e9 100644
--- a/drivers/gpu/drm/i915/gvt/aperture_gm.c
+++ b/drivers/gpu/drm/i915/gvt/aperture_gm.c
@@ -63,7 +63,7 @@ static int alloc_gm(struct intel_vgpu *vgpu, bool high_gm)
 
 	mutex_lock(&gt->ggtt->vm.mutex);
 	mmio_hw_access_pre(gt);
-	ret = i915_gem_gtt_insert(&gt->ggtt->vm, node,
+	ret = i915_gem_gtt_insert(&gt->ggtt->vm, NULL, node,
 				  size, I915_GTT_PAGE_SIZE,
 				  I915_COLOR_UNEVICTABLE,
 				  start, end, flags);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a8d733a7e1d9..22c891720c6d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1920,14 +1920,17 @@ i915_gem_vm_lookup(struct drm_i915_file_private *file_priv, u32 id)
 
 /* i915_gem_evict.c */
 int __must_check i915_gem_evict_something(struct i915_address_space *vm,
+					  struct i915_gem_ww_ctx *ww,
 					  u64 min_size, u64 alignment,
 					  unsigned long color,
 					  u64 start, u64 end,
 					  unsigned flags);
 int __must_check i915_gem_evict_for_node(struct i915_address_space *vm,
+					 struct i915_gem_ww_ctx *ww,
 					 struct drm_mm_node *node,
 					 unsigned int flags);
-int i915_gem_evict_vm(struct i915_address_space *vm);
+int i915_gem_evict_vm(struct i915_address_space *vm,
+		      struct i915_gem_ww_ctx *ww);
 
 /* i915_gem_internal.c */
 struct drm_i915_gem_object *
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
index 286efa462eca..24f5e3345e43 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -51,6 +51,7 @@ static int ggtt_flush(struct intel_gt *gt)
 
 static bool
 mark_free(struct drm_mm_scan *scan,
+	  struct i915_gem_ww_ctx *ww,
 	  struct i915_vma *vma,
 	  unsigned int flags,
 	  struct list_head *unwind)
@@ -58,7 +59,7 @@ mark_free(struct drm_mm_scan *scan,
 	if (i915_vma_is_pinned(vma))
 		return false;
 
-	if (!i915_gem_object_trylock(vma->obj))
+	if (!i915_gem_object_trylock(vma->obj, ww))
 		return false;
 
 	list_add(&vma->evict_link, unwind);
@@ -101,6 +102,7 @@ static bool defer_evict(struct i915_vma *vma)
  */
 int
 i915_gem_evict_something(struct i915_address_space *vm,
+			 struct i915_gem_ww_ctx *ww,
 			 u64 min_size, u64 alignment,
 			 unsigned long color,
 			 u64 start, u64 end,
@@ -173,7 +175,7 @@ i915_gem_evict_something(struct i915_address_space *vm,
 			continue;
 		}
 
-		if (mark_free(&scan, vma, flags, &eviction_list))
+		if (mark_free(&scan, ww, vma, flags, &eviction_list))
 			goto found;
 	}
 
@@ -250,7 +252,7 @@ i915_gem_evict_something(struct i915_address_space *vm,
 
 		/* If we find any non-objects (!vma), we cannot evict them */
 		if (vma->node.color != I915_COLOR_UNEVICTABLE &&
-		    i915_gem_object_trylock(vma->obj)) {
+		    i915_gem_object_trylock(vma->obj, ww)) {
 			ret = __i915_vma_unbind(vma);
 			i915_gem_object_unlock(vma->obj);
 		} else {
@@ -273,6 +275,7 @@ i915_gem_evict_something(struct i915_address_space *vm,
  * memory in e.g. the shrinker.
  */
 int i915_gem_evict_for_node(struct i915_address_space *vm,
+			    struct i915_gem_ww_ctx *ww,
 			    struct drm_mm_node *target,
 			    unsigned int flags)
 {
@@ -345,7 +348,7 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
 			break;
 		}
 
-		if (!i915_gem_object_trylock(vma->obj)) {
+		if (!i915_gem_object_trylock(vma->obj, ww)) {
 			ret = -ENOSPC;
 			break;
 		}
@@ -386,7 +389,7 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
  * To clarify: This is for freeing up virtual address space, not for freeing
  * memory in e.g. the shrinker.
  */
-int i915_gem_evict_vm(struct i915_address_space *vm)
+int i915_gem_evict_vm(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww)
 {
 	int ret = 0;
 
@@ -412,7 +415,7 @@ int i915_gem_evict_vm(struct i915_address_space *vm)
 			if (i915_vma_is_pinned(vma))
 				continue;
 
-			if (!i915_gem_object_trylock(vma->obj))
+			if (!i915_gem_object_trylock(vma->obj, ww))
 				continue;
 
 			__i915_vma_pin(vma);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index cd5f2348a187..c810da476c2b 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -93,6 +93,7 @@ void i915_gem_gtt_finish_pages(struct drm_i915_gem_object *obj,
  * asked to wait for eviction and interrupted.
  */
 int i915_gem_gtt_reserve(struct i915_address_space *vm,
+			 struct i915_gem_ww_ctx *ww,
 			 struct drm_mm_node *node,
 			 u64 size, u64 offset, unsigned long color,
 			 unsigned int flags)
@@ -117,7 +118,7 @@ int i915_gem_gtt_reserve(struct i915_address_space *vm,
 	if (flags & PIN_NOEVICT)
 		return -ENOSPC;
 
-	err = i915_gem_evict_for_node(vm, node, flags);
+	err = i915_gem_evict_for_node(vm, ww, node, flags);
 	if (err == 0)
 		err = drm_mm_reserve_node(&vm->mm, node);
 
@@ -184,6 +185,7 @@ static u64 random_offset(u64 start, u64 end, u64 len, u64 align)
  * asked to wait for eviction and interrupted.
  */
 int i915_gem_gtt_insert(struct i915_address_space *vm,
+			struct i915_gem_ww_ctx *ww,
 			struct drm_mm_node *node,
 			u64 size, u64 alignment, unsigned long color,
 			u64 start, u64 end, unsigned int flags)
@@ -269,7 +271,7 @@ int i915_gem_gtt_insert(struct i915_address_space *vm,
 	 */
 	offset = random_offset(start, end,
 			       size, alignment ?: I915_GTT_MIN_ALIGNMENT);
-	err = i915_gem_gtt_reserve(vm, node, size, offset, color, flags);
+	err = i915_gem_gtt_reserve(vm, ww, node, size, offset, color, flags);
 	if (err != -ENOSPC)
 		return err;
 
@@ -277,7 +279,7 @@ int i915_gem_gtt_insert(struct i915_address_space *vm,
 		return -ENOSPC;
 
 	/* Randomly selected placement is pinned, do a search */
-	err = i915_gem_evict_something(vm, size, alignment, color,
+	err = i915_gem_evict_something(vm, ww, size, alignment, color,
 				       start, end, flags);
 	if (err)
 		return err;
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index c9b0ee5e1d23..e4938aba3fe9 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -16,6 +16,7 @@
 
 struct drm_i915_gem_object;
 struct i915_address_space;
+struct i915_gem_ww_ctx;
 
 int __must_check i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj,
 					    struct sg_table *pages);
@@ -23,11 +24,13 @@ void i915_gem_gtt_finish_pages(struct drm_i915_gem_object *obj,
 			       struct sg_table *pages);
 
 int i915_gem_gtt_reserve(struct i915_address_space *vm,
+			 struct i915_gem_ww_ctx *ww,
 			 struct drm_mm_node *node,
 			 u64 size, u64 offset, unsigned long color,
 			 unsigned int flags);
 
 int i915_gem_gtt_insert(struct i915_address_space *vm,
+			struct i915_gem_ww_ctx *ww,
 			struct drm_mm_node *node,
 			u64 size, u64 alignment, unsigned long color,
 			u64 start, u64 end, unsigned int flags);
diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c
index 31a105bc1792..c97323973f9b 100644
--- a/drivers/gpu/drm/i915/i915_vgpu.c
+++ b/drivers/gpu/drm/i915/i915_vgpu.c
@@ -197,7 +197,7 @@ static int vgt_balloon_space(struct i915_ggtt *ggtt,
 	drm_info(&dev_priv->drm,
 		 "balloon space: range [ 0x%lx - 0x%lx ] %lu KiB.\n",
 		 start, end, size / 1024);
-	ret = i915_gem_gtt_reserve(&ggtt->vm, node,
+	ret = i915_gem_gtt_reserve(&ggtt->vm, NULL, node,
 				   size, start, I915_COLOR_UNEVICTABLE,
 				   0);
 	if (!ret)
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 2877dcd62acb..3275b2364785 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -623,7 +623,8 @@ bool i915_gem_valid_gtt_space(struct i915_vma *vma, unsigned long color)
  * 0 on success, negative error code otherwise.
  */
 static int
-i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
+i915_vma_insert(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
+		u64 size, u64 alignment, u64 flags)
 {
 	unsigned long color;
 	u64 start, end;
@@ -675,7 +676,7 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
 		    range_overflows(offset, size, end))
 			return -EINVAL;
 
-		ret = i915_gem_gtt_reserve(vma->vm, &vma->node,
+		ret = i915_gem_gtt_reserve(vma->vm, ww, &vma->node,
 					   size, offset, color,
 					   flags);
 		if (ret)
@@ -714,7 +715,7 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
 				size = round_up(size, I915_GTT_PAGE_SIZE_2M);
 		}
 
-		ret = i915_gem_gtt_insert(vma->vm, &vma->node,
+		ret = i915_gem_gtt_insert(vma->vm, ww, &vma->node,
 					  size, alignment, color,
 					  start, end, flags);
 		if (ret)
@@ -1293,7 +1294,7 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 		goto err_unlock;
 
 	if (!(bound & I915_VMA_BIND_MASK)) {
-		err = i915_vma_insert(vma, size, alignment, flags);
+		err = i915_vma_insert(vma, ww, size, alignment, flags);
 		if (err)
 			goto err_active;
 
@@ -1369,7 +1370,9 @@ static int __i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 		/* Unlike i915_vma_pin, we don't take no for an answer! */
 		flush_idle_contexts(vm->gt);
 		if (mutex_lock_interruptible(&vm->mutex) == 0) {
-			i915_gem_evict_vm(vm);
+
+			/* We pass NULL ww here, as we don't want to unbind locked objects */
+			i915_gem_evict_vm(vm, NULL);
 			mutex_unlock(&vm->mutex);
 		}
 	} while (1);
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
index f99bb0113726..4591be1a8803 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
@@ -117,7 +117,7 @@ static int igt_evict_something(void *arg)
 
 	/* Everything is pinned, nothing should happen */
 	mutex_lock(&ggtt->vm.mutex);
-	err = i915_gem_evict_something(&ggtt->vm,
+	err = i915_gem_evict_something(&ggtt->vm, NULL,
 				       I915_GTT_PAGE_SIZE, 0, 0,
 				       0, U64_MAX,
 				       0);
@@ -132,11 +132,12 @@ static int igt_evict_something(void *arg)
 
 	/* Everything is unpinned, we should be able to evict something */
 	mutex_lock(&ggtt->vm.mutex);
-	err = i915_gem_evict_something(&ggtt->vm,
+	err = i915_gem_evict_something(&ggtt->vm, NULL,
 				       I915_GTT_PAGE_SIZE, 0, 0,
 				       0, U64_MAX,
 				       0);
 	mutex_unlock(&ggtt->vm.mutex);
+
 	if (err) {
 		pr_err("i915_gem_evict_something failed on a full GGTT with err=%d\n",
 		       err);
@@ -204,7 +205,7 @@ static int igt_evict_for_vma(void *arg)
 
 	/* Everything is pinned, nothing should happen */
 	mutex_lock(&ggtt->vm.mutex);
-	err = i915_gem_evict_for_node(&ggtt->vm, &target, 0);
+	err = i915_gem_evict_for_node(&ggtt->vm, NULL, &target, 0);
 	mutex_unlock(&ggtt->vm.mutex);
 	if (err != -ENOSPC) {
 		pr_err("i915_gem_evict_for_node on a full GGTT returned err=%d\n",
@@ -216,7 +217,7 @@ static int igt_evict_for_vma(void *arg)
 
 	/* Everything is unpinned, we should be able to evict the node */
 	mutex_lock(&ggtt->vm.mutex);
-	err = i915_gem_evict_for_node(&ggtt->vm, &target, 0);
+	err = i915_gem_evict_for_node(&ggtt->vm, NULL, &target, 0);
 	mutex_unlock(&ggtt->vm.mutex);
 	if (err) {
 		pr_err("i915_gem_evict_for_node returned err=%d\n",
@@ -297,7 +298,7 @@ static int igt_evict_for_cache_color(void *arg)
 
 	/* Remove just the second vma */
 	mutex_lock(&ggtt->vm.mutex);
-	err = i915_gem_evict_for_node(&ggtt->vm, &target, 0);
+	err = i915_gem_evict_for_node(&ggtt->vm, NULL, &target, 0);
 	mutex_unlock(&ggtt->vm.mutex);
 	if (err) {
 		pr_err("[0]i915_gem_evict_for_node returned err=%d\n", err);
@@ -310,7 +311,7 @@ static int igt_evict_for_cache_color(void *arg)
 	target.color = I915_CACHE_L3_LLC;
 
 	mutex_lock(&ggtt->vm.mutex);
-	err = i915_gem_evict_for_node(&ggtt->vm, &target, 0);
+	err = i915_gem_evict_for_node(&ggtt->vm, NULL, &target, 0);
 	mutex_unlock(&ggtt->vm.mutex);
 	if (!err) {
 		pr_err("[1]i915_gem_evict_for_node returned err=%d\n", err);
@@ -331,6 +332,7 @@ static int igt_evict_vm(void *arg)
 {
 	struct intel_gt *gt = arg;
 	struct i915_ggtt *ggtt = gt->ggtt;
+	struct i915_gem_ww_ctx ww;
 	LIST_HEAD(objects);
 	int err;
 
@@ -342,7 +344,7 @@ static int igt_evict_vm(void *arg)
 
 	/* Everything is pinned, nothing should happen */
 	mutex_lock(&ggtt->vm.mutex);
-	err = i915_gem_evict_vm(&ggtt->vm);
+	err = i915_gem_evict_vm(&ggtt->vm, NULL);
 	mutex_unlock(&ggtt->vm.mutex);
 	if (err) {
 		pr_err("i915_gem_evict_vm on a full GGTT returned err=%d]\n",
@@ -352,9 +354,14 @@ static int igt_evict_vm(void *arg)
 
 	unpin_ggtt(ggtt);
 
+	i915_gem_ww_ctx_init(&ww, false);
 	mutex_lock(&ggtt->vm.mutex);
-	err = i915_gem_evict_vm(&ggtt->vm);
+	err = i915_gem_evict_vm(&ggtt->vm, &ww);
 	mutex_unlock(&ggtt->vm.mutex);
+
+	/* no -EDEADLK handling; can't happen with vm.mutex in place */
+	i915_gem_ww_ctx_fini(&ww);
+
 	if (err) {
 		pr_err("i915_gem_evict_vm on a full GGTT returned err=%d]\n",
 		       err);
@@ -402,7 +409,7 @@ static int igt_evict_contexts(void *arg)
 	/* Reserve a block so that we know we have enough to fit a few rq */
 	memset(&hole, 0, sizeof(hole));
 	mutex_lock(&ggtt->vm.mutex);
-	err = i915_gem_gtt_insert(&ggtt->vm, &hole,
+	err = i915_gem_gtt_insert(&ggtt->vm, NULL, &hole,
 				  PRETEND_GGTT_SIZE, 0, I915_COLOR_UNEVICTABLE,
 				  0, ggtt->vm.total,
 				  PIN_NOEVICT);
@@ -422,7 +429,7 @@ static int igt_evict_contexts(void *arg)
 			goto out_locked;
 		}
 
-		if (i915_gem_gtt_insert(&ggtt->vm, &r->node,
+		if (i915_gem_gtt_insert(&ggtt->vm, NULL, &r->node,
 					1ul << 20, 0, I915_COLOR_UNEVICTABLE,
 					0, ggtt->vm.total,
 					PIN_NOEVICT)) {
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 4574fb51b656..6b1db83119b3 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -1378,7 +1378,7 @@ static int igt_gtt_reserve(void *arg)
 		}
 
 		mutex_lock(&ggtt->vm.mutex);
-		err = i915_gem_gtt_reserve(&ggtt->vm, &vma->node,
+		err = i915_gem_gtt_reserve(&ggtt->vm, NULL, &vma->node,
 					   obj->base.size,
 					   total,
 					   obj->cache_level,
@@ -1430,7 +1430,7 @@ static int igt_gtt_reserve(void *arg)
 		}
 
 		mutex_lock(&ggtt->vm.mutex);
-		err = i915_gem_gtt_reserve(&ggtt->vm, &vma->node,
+		err = i915_gem_gtt_reserve(&ggtt->vm, NULL, &vma->node,
 					   obj->base.size,
 					   total,
 					   obj->cache_level,
@@ -1477,7 +1477,7 @@ static int igt_gtt_reserve(void *arg)
 					   I915_GTT_MIN_ALIGNMENT);
 
 		mutex_lock(&ggtt->vm.mutex);
-		err = i915_gem_gtt_reserve(&ggtt->vm, &vma->node,
+		err = i915_gem_gtt_reserve(&ggtt->vm, NULL, &vma->node,
 					   obj->base.size,
 					   offset,
 					   obj->cache_level,
@@ -1552,7 +1552,7 @@ static int igt_gtt_insert(void *arg)
 	/* Check a couple of obviously invalid requests */
 	for (ii = invalid_insert; ii->size; ii++) {
 		mutex_lock(&ggtt->vm.mutex);
-		err = i915_gem_gtt_insert(&ggtt->vm, &tmp,
+		err = i915_gem_gtt_insert(&ggtt->vm, NULL, &tmp,
 					  ii->size, ii->alignment,
 					  I915_COLOR_UNEVICTABLE,
 					  ii->start, ii->end,
@@ -1594,7 +1594,7 @@ static int igt_gtt_insert(void *arg)
 		}
 
 		mutex_lock(&ggtt->vm.mutex);
-		err = i915_gem_gtt_insert(&ggtt->vm, &vma->node,
+		err = i915_gem_gtt_insert(&ggtt->vm, NULL, &vma->node,
 					  obj->base.size, 0, obj->cache_level,
 					  0, ggtt->vm.total,
 					  0);
@@ -1654,7 +1654,7 @@ static int igt_gtt_insert(void *arg)
 		}
 
 		mutex_lock(&ggtt->vm.mutex);
-		err = i915_gem_gtt_insert(&ggtt->vm, &vma->node,
+		err = i915_gem_gtt_insert(&ggtt->vm, NULL, &vma->node,
 					  obj->base.size, 0, obj->cache_level,
 					  0, ggtt->vm.total,
 					  0);
@@ -1703,7 +1703,7 @@ static int igt_gtt_insert(void *arg)
 		}
 
 		mutex_lock(&ggtt->vm.mutex);
-		err = i915_gem_gtt_insert(&ggtt->vm, &vma->node,
+		err = i915_gem_gtt_insert(&ggtt->vm, NULL, &vma->node,
 					  obj->base.size, 0, obj->cache_level,
 					  0, ggtt->vm.total,
 					  0);
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 19/28] drm/i915: Pass trylock context to callers
@ 2021-10-21 10:35   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c    |  2 +-
 drivers/gpu/drm/i915/gem/i915_gem_object.h    |  8 ++++--
 drivers/gpu/drm/i915/gem/i915_gem_shrinker.c  |  4 +--
 drivers/gpu/drm/i915/gem/i915_gem_stolen.c    |  2 +-
 drivers/gpu/drm/i915/gt/intel_engine_pm.c     |  2 +-
 drivers/gpu/drm/i915/gt/intel_ggtt.c          |  2 +-
 drivers/gpu/drm/i915/gt/mock_engine.c         |  2 +-
 drivers/gpu/drm/i915/gt/selftest_hangcheck.c  |  2 +-
 drivers/gpu/drm/i915/gt/selftest_migrate.c    |  2 +-
 drivers/gpu/drm/i915/gvt/aperture_gm.c        |  2 +-
 drivers/gpu/drm/i915/i915_drv.h               |  5 +++-
 drivers/gpu/drm/i915/i915_gem_evict.c         | 15 ++++++-----
 drivers/gpu/drm/i915/i915_gem_gtt.c           |  8 +++---
 drivers/gpu/drm/i915/i915_gem_gtt.h           |  3 +++
 drivers/gpu/drm/i915/i915_vgpu.c              |  2 +-
 drivers/gpu/drm/i915/i915_vma.c               | 13 +++++----
 .../gpu/drm/i915/selftests/i915_gem_evict.c   | 27 ++++++++++++-------
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 14 +++++-----
 18 files changed, 70 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index e614591ca510..bbf2a10738f7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -764,7 +764,7 @@ static int eb_reserve(struct i915_execbuffer *eb)
 		case 1:
 			/* Too fragmented, unbind everything and retry */
 			mutex_lock(&eb->context->vm->mutex);
-			err = i915_gem_evict_vm(eb->context->vm);
+			err = i915_gem_evict_vm(eb->context->vm, &eb->ww);
 			mutex_unlock(&eb->context->vm->mutex);
 			if (err)
 				return err;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index 59201801cec5..accd8fad0ed7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -211,9 +211,13 @@ static inline int i915_gem_object_lock_interruptible(struct drm_i915_gem_object
 	return __i915_gem_object_lock(obj, ww, true);
 }
 
-static inline bool i915_gem_object_trylock(struct drm_i915_gem_object *obj)
+static inline bool i915_gem_object_trylock(struct drm_i915_gem_object *obj,
+					   struct i915_gem_ww_ctx *ww)
 {
-	return dma_resv_trylock(obj->base.resv);
+	if (!ww)
+		return dma_resv_trylock(obj->base.resv);
+	else
+		return ww_mutex_trylock(&obj->base.resv->lock, &ww->ctx);
 }
 
 static inline void i915_gem_object_unlock(struct drm_i915_gem_object *obj)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
index 34c12e5983eb..5375f3f9f016 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
@@ -210,7 +210,7 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww,
 
 			/* May arrive from get_pages on another bo */
 			if (!ww) {
-				if (!i915_gem_object_trylock(obj))
+				if (!i915_gem_object_trylock(obj, NULL))
 					goto skip;
 			} else {
 				err = i915_gem_object_lock(obj, ww);
@@ -408,7 +408,7 @@ i915_gem_shrinker_vmap(struct notifier_block *nb, unsigned long event, void *ptr
 		if (!vma->iomap || i915_vma_is_active(vma))
 			continue;
 
-		if (!i915_gem_object_trylock(obj))
+		if (!i915_gem_object_trylock(obj, NULL))
 			continue;
 
 		if (__i915_vma_unbind(vma) == 0)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
index ddd37ccb1362..d629ef5abf9a 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
@@ -653,7 +653,7 @@ static int __i915_gem_object_create_stolen(struct intel_memory_region *mem,
 	cache_level = HAS_LLC(mem->i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
 	i915_gem_object_set_cache_coherency(obj, cache_level);
 
-	if (WARN_ON(!i915_gem_object_trylock(obj)))
+	if (WARN_ON(!i915_gem_object_trylock(obj, NULL)))
 		return -EBUSY;
 
 	i915_gem_object_init_memory_region(obj, mem);
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.c b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
index 849fbb229bd3..d66c8bd50ae3 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
@@ -26,7 +26,7 @@ static void dbg_poison_ce(struct intel_context *ce)
 		int type = i915_coherent_map_type(ce->engine->i915, obj, true);
 		void *map;
 
-		if (!i915_gem_object_trylock(obj))
+		if (!i915_gem_object_trylock(obj, NULL))
 			return;
 
 		map = i915_gem_object_pin_map(obj, type);
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index 6da57199bb33..df29fd992b45 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -487,7 +487,7 @@ static int ggtt_reserve_guc_top(struct i915_ggtt *ggtt)
 	GEM_BUG_ON(ggtt->vm.total <= GUC_GGTT_TOP);
 	size = ggtt->vm.total - GUC_GGTT_TOP;
 
-	ret = i915_gem_gtt_reserve(&ggtt->vm, &ggtt->uc_fw, size,
+	ret = i915_gem_gtt_reserve(&ggtt->vm, NULL, &ggtt->uc_fw, size,
 				   GUC_GGTT_TOP, I915_COLOR_UNEVICTABLE,
 				   PIN_NOEVICT);
 	if (ret)
diff --git a/drivers/gpu/drm/i915/gt/mock_engine.c b/drivers/gpu/drm/i915/gt/mock_engine.c
index bb99fc03f503..240265354274 100644
--- a/drivers/gpu/drm/i915/gt/mock_engine.c
+++ b/drivers/gpu/drm/i915/gt/mock_engine.c
@@ -17,7 +17,7 @@ static int mock_timeline_pin(struct intel_timeline *tl)
 {
 	int err;
 
-	if (WARN_ON(!i915_gem_object_trylock(tl->hwsp_ggtt->obj)))
+	if (WARN_ON(!i915_gem_object_trylock(tl->hwsp_ggtt->obj, NULL)))
 		return -EBUSY;
 
 	err = intel_timeline_pin_map(tl);
diff --git a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
index 7e2d99dd012d..572f942c3c5d 100644
--- a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
+++ b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
@@ -1378,7 +1378,7 @@ static int evict_vma(void *data)
 	complete(&arg->completion);
 
 	mutex_lock(&vm->mutex);
-	err = i915_gem_evict_for_node(vm, &evict, 0);
+	err = i915_gem_evict_for_node(vm, NULL, &evict, 0);
 	mutex_unlock(&vm->mutex);
 
 	return err;
diff --git a/drivers/gpu/drm/i915/gt/selftest_migrate.c b/drivers/gpu/drm/i915/gt/selftest_migrate.c
index 12ef2837c89b..78993c760f12 100644
--- a/drivers/gpu/drm/i915/gt/selftest_migrate.c
+++ b/drivers/gpu/drm/i915/gt/selftest_migrate.c
@@ -464,7 +464,7 @@ create_init_lmem_internal(struct intel_gt *gt, size_t sz, bool try_lmem)
 			return obj;
 	}
 
-	i915_gem_object_trylock(obj);
+	i915_gem_object_trylock(obj, NULL);
 	err = i915_gem_object_pin_pages(obj);
 	if (err) {
 		i915_gem_object_unlock(obj);
diff --git a/drivers/gpu/drm/i915/gvt/aperture_gm.c b/drivers/gpu/drm/i915/gvt/aperture_gm.c
index 0d6d59871308..c08098a167e9 100644
--- a/drivers/gpu/drm/i915/gvt/aperture_gm.c
+++ b/drivers/gpu/drm/i915/gvt/aperture_gm.c
@@ -63,7 +63,7 @@ static int alloc_gm(struct intel_vgpu *vgpu, bool high_gm)
 
 	mutex_lock(&gt->ggtt->vm.mutex);
 	mmio_hw_access_pre(gt);
-	ret = i915_gem_gtt_insert(&gt->ggtt->vm, node,
+	ret = i915_gem_gtt_insert(&gt->ggtt->vm, NULL, node,
 				  size, I915_GTT_PAGE_SIZE,
 				  I915_COLOR_UNEVICTABLE,
 				  start, end, flags);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a8d733a7e1d9..22c891720c6d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1920,14 +1920,17 @@ i915_gem_vm_lookup(struct drm_i915_file_private *file_priv, u32 id)
 
 /* i915_gem_evict.c */
 int __must_check i915_gem_evict_something(struct i915_address_space *vm,
+					  struct i915_gem_ww_ctx *ww,
 					  u64 min_size, u64 alignment,
 					  unsigned long color,
 					  u64 start, u64 end,
 					  unsigned flags);
 int __must_check i915_gem_evict_for_node(struct i915_address_space *vm,
+					 struct i915_gem_ww_ctx *ww,
 					 struct drm_mm_node *node,
 					 unsigned int flags);
-int i915_gem_evict_vm(struct i915_address_space *vm);
+int i915_gem_evict_vm(struct i915_address_space *vm,
+		      struct i915_gem_ww_ctx *ww);
 
 /* i915_gem_internal.c */
 struct drm_i915_gem_object *
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
index 286efa462eca..24f5e3345e43 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -51,6 +51,7 @@ static int ggtt_flush(struct intel_gt *gt)
 
 static bool
 mark_free(struct drm_mm_scan *scan,
+	  struct i915_gem_ww_ctx *ww,
 	  struct i915_vma *vma,
 	  unsigned int flags,
 	  struct list_head *unwind)
@@ -58,7 +59,7 @@ mark_free(struct drm_mm_scan *scan,
 	if (i915_vma_is_pinned(vma))
 		return false;
 
-	if (!i915_gem_object_trylock(vma->obj))
+	if (!i915_gem_object_trylock(vma->obj, ww))
 		return false;
 
 	list_add(&vma->evict_link, unwind);
@@ -101,6 +102,7 @@ static bool defer_evict(struct i915_vma *vma)
  */
 int
 i915_gem_evict_something(struct i915_address_space *vm,
+			 struct i915_gem_ww_ctx *ww,
 			 u64 min_size, u64 alignment,
 			 unsigned long color,
 			 u64 start, u64 end,
@@ -173,7 +175,7 @@ i915_gem_evict_something(struct i915_address_space *vm,
 			continue;
 		}
 
-		if (mark_free(&scan, vma, flags, &eviction_list))
+		if (mark_free(&scan, ww, vma, flags, &eviction_list))
 			goto found;
 	}
 
@@ -250,7 +252,7 @@ i915_gem_evict_something(struct i915_address_space *vm,
 
 		/* If we find any non-objects (!vma), we cannot evict them */
 		if (vma->node.color != I915_COLOR_UNEVICTABLE &&
-		    i915_gem_object_trylock(vma->obj)) {
+		    i915_gem_object_trylock(vma->obj, ww)) {
 			ret = __i915_vma_unbind(vma);
 			i915_gem_object_unlock(vma->obj);
 		} else {
@@ -273,6 +275,7 @@ i915_gem_evict_something(struct i915_address_space *vm,
  * memory in e.g. the shrinker.
  */
 int i915_gem_evict_for_node(struct i915_address_space *vm,
+			    struct i915_gem_ww_ctx *ww,
 			    struct drm_mm_node *target,
 			    unsigned int flags)
 {
@@ -345,7 +348,7 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
 			break;
 		}
 
-		if (!i915_gem_object_trylock(vma->obj)) {
+		if (!i915_gem_object_trylock(vma->obj, ww)) {
 			ret = -ENOSPC;
 			break;
 		}
@@ -386,7 +389,7 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
  * To clarify: This is for freeing up virtual address space, not for freeing
  * memory in e.g. the shrinker.
  */
-int i915_gem_evict_vm(struct i915_address_space *vm)
+int i915_gem_evict_vm(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww)
 {
 	int ret = 0;
 
@@ -412,7 +415,7 @@ int i915_gem_evict_vm(struct i915_address_space *vm)
 			if (i915_vma_is_pinned(vma))
 				continue;
 
-			if (!i915_gem_object_trylock(vma->obj))
+			if (!i915_gem_object_trylock(vma->obj, ww))
 				continue;
 
 			__i915_vma_pin(vma);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index cd5f2348a187..c810da476c2b 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -93,6 +93,7 @@ void i915_gem_gtt_finish_pages(struct drm_i915_gem_object *obj,
  * asked to wait for eviction and interrupted.
  */
 int i915_gem_gtt_reserve(struct i915_address_space *vm,
+			 struct i915_gem_ww_ctx *ww,
 			 struct drm_mm_node *node,
 			 u64 size, u64 offset, unsigned long color,
 			 unsigned int flags)
@@ -117,7 +118,7 @@ int i915_gem_gtt_reserve(struct i915_address_space *vm,
 	if (flags & PIN_NOEVICT)
 		return -ENOSPC;
 
-	err = i915_gem_evict_for_node(vm, node, flags);
+	err = i915_gem_evict_for_node(vm, ww, node, flags);
 	if (err == 0)
 		err = drm_mm_reserve_node(&vm->mm, node);
 
@@ -184,6 +185,7 @@ static u64 random_offset(u64 start, u64 end, u64 len, u64 align)
  * asked to wait for eviction and interrupted.
  */
 int i915_gem_gtt_insert(struct i915_address_space *vm,
+			struct i915_gem_ww_ctx *ww,
 			struct drm_mm_node *node,
 			u64 size, u64 alignment, unsigned long color,
 			u64 start, u64 end, unsigned int flags)
@@ -269,7 +271,7 @@ int i915_gem_gtt_insert(struct i915_address_space *vm,
 	 */
 	offset = random_offset(start, end,
 			       size, alignment ?: I915_GTT_MIN_ALIGNMENT);
-	err = i915_gem_gtt_reserve(vm, node, size, offset, color, flags);
+	err = i915_gem_gtt_reserve(vm, ww, node, size, offset, color, flags);
 	if (err != -ENOSPC)
 		return err;
 
@@ -277,7 +279,7 @@ int i915_gem_gtt_insert(struct i915_address_space *vm,
 		return -ENOSPC;
 
 	/* Randomly selected placement is pinned, do a search */
-	err = i915_gem_evict_something(vm, size, alignment, color,
+	err = i915_gem_evict_something(vm, ww, size, alignment, color,
 				       start, end, flags);
 	if (err)
 		return err;
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index c9b0ee5e1d23..e4938aba3fe9 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -16,6 +16,7 @@
 
 struct drm_i915_gem_object;
 struct i915_address_space;
+struct i915_gem_ww_ctx;
 
 int __must_check i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj,
 					    struct sg_table *pages);
@@ -23,11 +24,13 @@ void i915_gem_gtt_finish_pages(struct drm_i915_gem_object *obj,
 			       struct sg_table *pages);
 
 int i915_gem_gtt_reserve(struct i915_address_space *vm,
+			 struct i915_gem_ww_ctx *ww,
 			 struct drm_mm_node *node,
 			 u64 size, u64 offset, unsigned long color,
 			 unsigned int flags);
 
 int i915_gem_gtt_insert(struct i915_address_space *vm,
+			struct i915_gem_ww_ctx *ww,
 			struct drm_mm_node *node,
 			u64 size, u64 alignment, unsigned long color,
 			u64 start, u64 end, unsigned int flags);
diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c
index 31a105bc1792..c97323973f9b 100644
--- a/drivers/gpu/drm/i915/i915_vgpu.c
+++ b/drivers/gpu/drm/i915/i915_vgpu.c
@@ -197,7 +197,7 @@ static int vgt_balloon_space(struct i915_ggtt *ggtt,
 	drm_info(&dev_priv->drm,
 		 "balloon space: range [ 0x%lx - 0x%lx ] %lu KiB.\n",
 		 start, end, size / 1024);
-	ret = i915_gem_gtt_reserve(&ggtt->vm, node,
+	ret = i915_gem_gtt_reserve(&ggtt->vm, NULL, node,
 				   size, start, I915_COLOR_UNEVICTABLE,
 				   0);
 	if (!ret)
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 2877dcd62acb..3275b2364785 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -623,7 +623,8 @@ bool i915_gem_valid_gtt_space(struct i915_vma *vma, unsigned long color)
  * 0 on success, negative error code otherwise.
  */
 static int
-i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
+i915_vma_insert(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
+		u64 size, u64 alignment, u64 flags)
 {
 	unsigned long color;
 	u64 start, end;
@@ -675,7 +676,7 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
 		    range_overflows(offset, size, end))
 			return -EINVAL;
 
-		ret = i915_gem_gtt_reserve(vma->vm, &vma->node,
+		ret = i915_gem_gtt_reserve(vma->vm, ww, &vma->node,
 					   size, offset, color,
 					   flags);
 		if (ret)
@@ -714,7 +715,7 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
 				size = round_up(size, I915_GTT_PAGE_SIZE_2M);
 		}
 
-		ret = i915_gem_gtt_insert(vma->vm, &vma->node,
+		ret = i915_gem_gtt_insert(vma->vm, ww, &vma->node,
 					  size, alignment, color,
 					  start, end, flags);
 		if (ret)
@@ -1293,7 +1294,7 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 		goto err_unlock;
 
 	if (!(bound & I915_VMA_BIND_MASK)) {
-		err = i915_vma_insert(vma, size, alignment, flags);
+		err = i915_vma_insert(vma, ww, size, alignment, flags);
 		if (err)
 			goto err_active;
 
@@ -1369,7 +1370,9 @@ static int __i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 		/* Unlike i915_vma_pin, we don't take no for an answer! */
 		flush_idle_contexts(vm->gt);
 		if (mutex_lock_interruptible(&vm->mutex) == 0) {
-			i915_gem_evict_vm(vm);
+
+			/* We pass NULL ww here, as we don't want to unbind locked objects */
+			i915_gem_evict_vm(vm, NULL);
 			mutex_unlock(&vm->mutex);
 		}
 	} while (1);
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
index f99bb0113726..4591be1a8803 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
@@ -117,7 +117,7 @@ static int igt_evict_something(void *arg)
 
 	/* Everything is pinned, nothing should happen */
 	mutex_lock(&ggtt->vm.mutex);
-	err = i915_gem_evict_something(&ggtt->vm,
+	err = i915_gem_evict_something(&ggtt->vm, NULL,
 				       I915_GTT_PAGE_SIZE, 0, 0,
 				       0, U64_MAX,
 				       0);
@@ -132,11 +132,12 @@ static int igt_evict_something(void *arg)
 
 	/* Everything is unpinned, we should be able to evict something */
 	mutex_lock(&ggtt->vm.mutex);
-	err = i915_gem_evict_something(&ggtt->vm,
+	err = i915_gem_evict_something(&ggtt->vm, NULL,
 				       I915_GTT_PAGE_SIZE, 0, 0,
 				       0, U64_MAX,
 				       0);
 	mutex_unlock(&ggtt->vm.mutex);
+
 	if (err) {
 		pr_err("i915_gem_evict_something failed on a full GGTT with err=%d\n",
 		       err);
@@ -204,7 +205,7 @@ static int igt_evict_for_vma(void *arg)
 
 	/* Everything is pinned, nothing should happen */
 	mutex_lock(&ggtt->vm.mutex);
-	err = i915_gem_evict_for_node(&ggtt->vm, &target, 0);
+	err = i915_gem_evict_for_node(&ggtt->vm, NULL, &target, 0);
 	mutex_unlock(&ggtt->vm.mutex);
 	if (err != -ENOSPC) {
 		pr_err("i915_gem_evict_for_node on a full GGTT returned err=%d\n",
@@ -216,7 +217,7 @@ static int igt_evict_for_vma(void *arg)
 
 	/* Everything is unpinned, we should be able to evict the node */
 	mutex_lock(&ggtt->vm.mutex);
-	err = i915_gem_evict_for_node(&ggtt->vm, &target, 0);
+	err = i915_gem_evict_for_node(&ggtt->vm, NULL, &target, 0);
 	mutex_unlock(&ggtt->vm.mutex);
 	if (err) {
 		pr_err("i915_gem_evict_for_node returned err=%d\n",
@@ -297,7 +298,7 @@ static int igt_evict_for_cache_color(void *arg)
 
 	/* Remove just the second vma */
 	mutex_lock(&ggtt->vm.mutex);
-	err = i915_gem_evict_for_node(&ggtt->vm, &target, 0);
+	err = i915_gem_evict_for_node(&ggtt->vm, NULL, &target, 0);
 	mutex_unlock(&ggtt->vm.mutex);
 	if (err) {
 		pr_err("[0]i915_gem_evict_for_node returned err=%d\n", err);
@@ -310,7 +311,7 @@ static int igt_evict_for_cache_color(void *arg)
 	target.color = I915_CACHE_L3_LLC;
 
 	mutex_lock(&ggtt->vm.mutex);
-	err = i915_gem_evict_for_node(&ggtt->vm, &target, 0);
+	err = i915_gem_evict_for_node(&ggtt->vm, NULL, &target, 0);
 	mutex_unlock(&ggtt->vm.mutex);
 	if (!err) {
 		pr_err("[1]i915_gem_evict_for_node returned err=%d\n", err);
@@ -331,6 +332,7 @@ static int igt_evict_vm(void *arg)
 {
 	struct intel_gt *gt = arg;
 	struct i915_ggtt *ggtt = gt->ggtt;
+	struct i915_gem_ww_ctx ww;
 	LIST_HEAD(objects);
 	int err;
 
@@ -342,7 +344,7 @@ static int igt_evict_vm(void *arg)
 
 	/* Everything is pinned, nothing should happen */
 	mutex_lock(&ggtt->vm.mutex);
-	err = i915_gem_evict_vm(&ggtt->vm);
+	err = i915_gem_evict_vm(&ggtt->vm, NULL);
 	mutex_unlock(&ggtt->vm.mutex);
 	if (err) {
 		pr_err("i915_gem_evict_vm on a full GGTT returned err=%d]\n",
@@ -352,9 +354,14 @@ static int igt_evict_vm(void *arg)
 
 	unpin_ggtt(ggtt);
 
+	i915_gem_ww_ctx_init(&ww, false);
 	mutex_lock(&ggtt->vm.mutex);
-	err = i915_gem_evict_vm(&ggtt->vm);
+	err = i915_gem_evict_vm(&ggtt->vm, &ww);
 	mutex_unlock(&ggtt->vm.mutex);
+
+	/* no -EDEADLK handling; can't happen with vm.mutex in place */
+	i915_gem_ww_ctx_fini(&ww);
+
 	if (err) {
 		pr_err("i915_gem_evict_vm on a full GGTT returned err=%d]\n",
 		       err);
@@ -402,7 +409,7 @@ static int igt_evict_contexts(void *arg)
 	/* Reserve a block so that we know we have enough to fit a few rq */
 	memset(&hole, 0, sizeof(hole));
 	mutex_lock(&ggtt->vm.mutex);
-	err = i915_gem_gtt_insert(&ggtt->vm, &hole,
+	err = i915_gem_gtt_insert(&ggtt->vm, NULL, &hole,
 				  PRETEND_GGTT_SIZE, 0, I915_COLOR_UNEVICTABLE,
 				  0, ggtt->vm.total,
 				  PIN_NOEVICT);
@@ -422,7 +429,7 @@ static int igt_evict_contexts(void *arg)
 			goto out_locked;
 		}
 
-		if (i915_gem_gtt_insert(&ggtt->vm, &r->node,
+		if (i915_gem_gtt_insert(&ggtt->vm, NULL, &r->node,
 					1ul << 20, 0, I915_COLOR_UNEVICTABLE,
 					0, ggtt->vm.total,
 					PIN_NOEVICT)) {
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 4574fb51b656..6b1db83119b3 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -1378,7 +1378,7 @@ static int igt_gtt_reserve(void *arg)
 		}
 
 		mutex_lock(&ggtt->vm.mutex);
-		err = i915_gem_gtt_reserve(&ggtt->vm, &vma->node,
+		err = i915_gem_gtt_reserve(&ggtt->vm, NULL, &vma->node,
 					   obj->base.size,
 					   total,
 					   obj->cache_level,
@@ -1430,7 +1430,7 @@ static int igt_gtt_reserve(void *arg)
 		}
 
 		mutex_lock(&ggtt->vm.mutex);
-		err = i915_gem_gtt_reserve(&ggtt->vm, &vma->node,
+		err = i915_gem_gtt_reserve(&ggtt->vm, NULL, &vma->node,
 					   obj->base.size,
 					   total,
 					   obj->cache_level,
@@ -1477,7 +1477,7 @@ static int igt_gtt_reserve(void *arg)
 					   I915_GTT_MIN_ALIGNMENT);
 
 		mutex_lock(&ggtt->vm.mutex);
-		err = i915_gem_gtt_reserve(&ggtt->vm, &vma->node,
+		err = i915_gem_gtt_reserve(&ggtt->vm, NULL, &vma->node,
 					   obj->base.size,
 					   offset,
 					   obj->cache_level,
@@ -1552,7 +1552,7 @@ static int igt_gtt_insert(void *arg)
 	/* Check a couple of obviously invalid requests */
 	for (ii = invalid_insert; ii->size; ii++) {
 		mutex_lock(&ggtt->vm.mutex);
-		err = i915_gem_gtt_insert(&ggtt->vm, &tmp,
+		err = i915_gem_gtt_insert(&ggtt->vm, NULL, &tmp,
 					  ii->size, ii->alignment,
 					  I915_COLOR_UNEVICTABLE,
 					  ii->start, ii->end,
@@ -1594,7 +1594,7 @@ static int igt_gtt_insert(void *arg)
 		}
 
 		mutex_lock(&ggtt->vm.mutex);
-		err = i915_gem_gtt_insert(&ggtt->vm, &vma->node,
+		err = i915_gem_gtt_insert(&ggtt->vm, NULL, &vma->node,
 					  obj->base.size, 0, obj->cache_level,
 					  0, ggtt->vm.total,
 					  0);
@@ -1654,7 +1654,7 @@ static int igt_gtt_insert(void *arg)
 		}
 
 		mutex_lock(&ggtt->vm.mutex);
-		err = i915_gem_gtt_insert(&ggtt->vm, &vma->node,
+		err = i915_gem_gtt_insert(&ggtt->vm, NULL, &vma->node,
 					  obj->base.size, 0, obj->cache_level,
 					  0, ggtt->vm.total,
 					  0);
@@ -1703,7 +1703,7 @@ static int igt_gtt_insert(void *arg)
 		}
 
 		mutex_lock(&ggtt->vm.mutex);
-		err = i915_gem_gtt_insert(&ggtt->vm, &vma->node,
+		err = i915_gem_gtt_insert(&ggtt->vm, NULL, &vma->node,
 					  obj->base.size, 0, obj->cache_level,
 					  0, ggtt->vm.total,
 					  0);
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 20/28] drm/i915: Ensure i915_vma tests do not get -ENOSPC with the locking changes.
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:35   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

Now that we require locking to evict, multiple vmas from the same object
might not be evicted. This is expected and required, because execbuf will
move to short-term pinning by using the lock only. This will cause these
tests to fail, because they create a ton of vma's for the same object.

Unbind manually to prevent spurious -ENOSPC in those mock tests.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/selftests/i915_vma.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c
index 1f10fe36619b..5c5809dfe9b2 100644
--- a/drivers/gpu/drm/i915/selftests/i915_vma.c
+++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
@@ -691,7 +691,11 @@ static int igt_vma_rotate_remap(void *arg)
 					}
 
 					i915_vma_unpin(vma);
-
+					err = i915_vma_unbind(vma);
+					if (err) {
+						pr_err("Unbinding returned %i\n", err);
+						goto out_object;
+					}
 					cond_resched();
 				}
 			}
@@ -848,6 +852,11 @@ static int igt_vma_partial(void *arg)
 
 				i915_vma_unpin(vma);
 				nvma++;
+				err = i915_vma_unbind(vma);
+				if (err) {
+					pr_err("Unbinding returned %i\n", err);
+					goto out_object;
+				}
 
 				cond_resched();
 			}
@@ -882,6 +891,12 @@ static int igt_vma_partial(void *arg)
 
 		i915_vma_unpin(vma);
 
+		err = i915_vma_unbind(vma);
+		if (err) {
+			pr_err("Unbinding returned %i\n", err);
+			goto out_object;
+		}
+
 		count = 0;
 		list_for_each_entry(vma, &obj->vma.list, obj_link)
 			count++;
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 20/28] drm/i915: Ensure i915_vma tests do not get -ENOSPC with the locking changes.
@ 2021-10-21 10:35   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

Now that we require locking to evict, multiple vmas from the same object
might not be evicted. This is expected and required, because execbuf will
move to short-term pinning by using the lock only. This will cause these
tests to fail, because they create a ton of vma's for the same object.

Unbind manually to prevent spurious -ENOSPC in those mock tests.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/selftests/i915_vma.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c
index 1f10fe36619b..5c5809dfe9b2 100644
--- a/drivers/gpu/drm/i915/selftests/i915_vma.c
+++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
@@ -691,7 +691,11 @@ static int igt_vma_rotate_remap(void *arg)
 					}
 
 					i915_vma_unpin(vma);
-
+					err = i915_vma_unbind(vma);
+					if (err) {
+						pr_err("Unbinding returned %i\n", err);
+						goto out_object;
+					}
 					cond_resched();
 				}
 			}
@@ -848,6 +852,11 @@ static int igt_vma_partial(void *arg)
 
 				i915_vma_unpin(vma);
 				nvma++;
+				err = i915_vma_unbind(vma);
+				if (err) {
+					pr_err("Unbinding returned %i\n", err);
+					goto out_object;
+				}
 
 				cond_resched();
 			}
@@ -882,6 +891,12 @@ static int igt_vma_partial(void *arg)
 
 		i915_vma_unpin(vma);
 
+		err = i915_vma_unbind(vma);
+		if (err) {
+			pr_err("Unbinding returned %i\n", err);
+			goto out_object;
+		}
+
 		count = 0;
 		list_for_each_entry(vma, &obj->vma.list, obj_link)
 			count++;
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 21/28] drm/i915: Drain the ttm delayed workqueue too
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:35   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

Be thorough..

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 22c891720c6d..7c5ed5957fe2 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1819,6 +1819,7 @@ static inline void i915_gem_drain_freed_objects(struct drm_i915_private *i915)
 	 */
 	while (atomic_read(&i915->mm.free_count)) {
 		flush_work(&i915->mm.free_work);
+		flush_delayed_work(&i915->bdev.wq);
 		rcu_barrier();
 	}
 }
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 21/28] drm/i915: Drain the ttm delayed workqueue too
@ 2021-10-21 10:35   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

Be thorough..

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 22c891720c6d..7c5ed5957fe2 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1819,6 +1819,7 @@ static inline void i915_gem_drain_freed_objects(struct drm_i915_private *i915)
 	 */
 	while (atomic_read(&i915->mm.free_count)) {
 		flush_work(&i915->mm.free_work);
+		flush_delayed_work(&i915->bdev.wq);
 		rcu_barrier();
 	}
 }
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 22/28] drm/i915: Make i915_gem_evict_vm work correctly for already locked objects
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:35   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

i915_gem_execbuf will call i915_gem_evict_vm() after failing to pin
all objects in the first round. We are about to remove those short-term
pins, but even without those the objects are still locked. Add a special
case to allow i915_gem_evict_vm to evict locked objects as well.

This might also allow multiple objects sharing the same resv to be evicted.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem_evict.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
index 24f5e3345e43..f502a617b35c 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -410,21 +410,42 @@ int i915_gem_evict_vm(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww)
 	do {
 		struct i915_vma *vma, *vn;
 		LIST_HEAD(eviction_list);
+		LIST_HEAD(locked_eviction_list);
 
 		list_for_each_entry(vma, &vm->bound_list, vm_link) {
 			if (i915_vma_is_pinned(vma))
 				continue;
 
+			/*
+			 * If we already own the lock, trylock fails. In case the resv
+			 * is shared among multiple objects, we still need the object ref.
+			 */
+			if (ww && (dma_resv_locking_ctx(vma->obj->base.resv) == &ww->ctx)) {
+				__i915_vma_pin(vma);
+				list_add(&vma->evict_link, &locked_eviction_list);
+				continue;
+			}
+
 			if (!i915_gem_object_trylock(vma->obj, ww))
 				continue;
 
 			__i915_vma_pin(vma);
 			list_add(&vma->evict_link, &eviction_list);
 		}
-		if (list_empty(&eviction_list))
+		if (list_empty(&eviction_list) && list_empty(&locked_eviction_list))
 			break;
 
 		ret = 0;
+		/* Unbind locked objects first, before unlocking the eviction_list */
+		list_for_each_entry_safe(vma, vn, &locked_eviction_list, evict_link) {
+			__i915_vma_unpin(vma);
+
+			if (ret == 0)
+				ret = __i915_vma_unbind(vma);
+			if (ret != -EINTR) /* "Get me out of here!" */
+				ret = 0;
+		}
+
 		list_for_each_entry_safe(vma, vn, &eviction_list, evict_link) {
 			__i915_vma_unpin(vma);
 			if (ret == 0)
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 22/28] drm/i915: Make i915_gem_evict_vm work correctly for already locked objects
@ 2021-10-21 10:35   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:35 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

i915_gem_execbuf will call i915_gem_evict_vm() after failing to pin
all objects in the first round. We are about to remove those short-term
pins, but even without those the objects are still locked. Add a special
case to allow i915_gem_evict_vm to evict locked objects as well.

This might also allow multiple objects sharing the same resv to be evicted.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem_evict.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
index 24f5e3345e43..f502a617b35c 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -410,21 +410,42 @@ int i915_gem_evict_vm(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww)
 	do {
 		struct i915_vma *vma, *vn;
 		LIST_HEAD(eviction_list);
+		LIST_HEAD(locked_eviction_list);
 
 		list_for_each_entry(vma, &vm->bound_list, vm_link) {
 			if (i915_vma_is_pinned(vma))
 				continue;
 
+			/*
+			 * If we already own the lock, trylock fails. In case the resv
+			 * is shared among multiple objects, we still need the object ref.
+			 */
+			if (ww && (dma_resv_locking_ctx(vma->obj->base.resv) == &ww->ctx)) {
+				__i915_vma_pin(vma);
+				list_add(&vma->evict_link, &locked_eviction_list);
+				continue;
+			}
+
 			if (!i915_gem_object_trylock(vma->obj, ww))
 				continue;
 
 			__i915_vma_pin(vma);
 			list_add(&vma->evict_link, &eviction_list);
 		}
-		if (list_empty(&eviction_list))
+		if (list_empty(&eviction_list) && list_empty(&locked_eviction_list))
 			break;
 
 		ret = 0;
+		/* Unbind locked objects first, before unlocking the eviction_list */
+		list_for_each_entry_safe(vma, vn, &locked_eviction_list, evict_link) {
+			__i915_vma_unpin(vma);
+
+			if (ret == 0)
+				ret = __i915_vma_unbind(vma);
+			if (ret != -EINTR) /* "Get me out of here!" */
+				ret = 0;
+		}
+
 		list_for_each_entry_safe(vma, vn, &eviction_list, evict_link) {
 			__i915_vma_unpin(vma);
 			if (ret == 0)
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 23/28] drm/i915: Call i915_gem_evict_vm in vm_fault_gtt to prevent new ENOSPC errors
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:36   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:36 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

Now that we cannot unbind kill the currently locked object directly
because we're removing short term pinning, we may have to unbind the
object from gtt manually, using a i915_gem_evict_vm() call.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 65fc6ff5f59d..6d557bb9926f 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -357,8 +357,22 @@ static vm_fault_t vm_fault_gtt(struct vm_fault *vmf)
 			vma = i915_gem_object_ggtt_pin_ww(obj, &ww, &view, 0, 0, flags);
 		}
 
-		/* The entire mappable GGTT is pinned? Unexpected! */
-		GEM_BUG_ON(vma == ERR_PTR(-ENOSPC));
+		/*
+		 * The entire mappable GGTT is pinned? Unexpected!
+		 * Try to evict the object we locked too, as normally we skip it
+		 * due to lack of short term pinning inside execbuf.
+		 */
+		if (vma == ERR_PTR(-ENOSPC)) {
+			ret = mutex_lock_interruptible(&ggtt->vm.mutex);
+			if (!ret) {
+				ret = i915_gem_evict_vm(&ggtt->vm, &ww);
+				mutex_unlock(&ggtt->vm.mutex);
+			}
+			if (ret)
+				goto err_reset;
+			vma = i915_gem_object_ggtt_pin_ww(obj, &ww, &view, 0, 0, flags);
+		}
+		GEM_WARN_ON(vma == ERR_PTR(-ENOSPC));
 	}
 	if (IS_ERR(vma)) {
 		ret = PTR_ERR(vma);
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 23/28] drm/i915: Call i915_gem_evict_vm in vm_fault_gtt to prevent new ENOSPC errors
@ 2021-10-21 10:36   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:36 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

Now that we cannot unbind kill the currently locked object directly
because we're removing short term pinning, we may have to unbind the
object from gtt manually, using a i915_gem_evict_vm() call.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 65fc6ff5f59d..6d557bb9926f 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -357,8 +357,22 @@ static vm_fault_t vm_fault_gtt(struct vm_fault *vmf)
 			vma = i915_gem_object_ggtt_pin_ww(obj, &ww, &view, 0, 0, flags);
 		}
 
-		/* The entire mappable GGTT is pinned? Unexpected! */
-		GEM_BUG_ON(vma == ERR_PTR(-ENOSPC));
+		/*
+		 * The entire mappable GGTT is pinned? Unexpected!
+		 * Try to evict the object we locked too, as normally we skip it
+		 * due to lack of short term pinning inside execbuf.
+		 */
+		if (vma == ERR_PTR(-ENOSPC)) {
+			ret = mutex_lock_interruptible(&ggtt->vm.mutex);
+			if (!ret) {
+				ret = i915_gem_evict_vm(&ggtt->vm, &ww);
+				mutex_unlock(&ggtt->vm.mutex);
+			}
+			if (ret)
+				goto err_reset;
+			vma = i915_gem_object_ggtt_pin_ww(obj, &ww, &view, 0, 0, flags);
+		}
+		GEM_WARN_ON(vma == ERR_PTR(-ENOSPC));
 	}
 	if (IS_ERR(vma)) {
 		ret = PTR_ERR(vma);
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 24/28] drm/i915: Add i915_vma_unbind_unlocked, and take obj lock for i915_vma_unbind
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:36   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:36 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

We want to remove more members of i915_vma, which requires the locking to be
held more often.

Start requiring gem object lock for i915_vma_unbind, as it's one of the
callers that may unpin pages.

Some special care is needed when evicting, because the last reference to the
object may be held by the VMA, so after __i915_vma_unbind, vma may be garbage,
and we need to cache vma->obj before unlocking.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_fb_pin.c   |  2 +-
 .../gpu/drm/i915/gem/selftests/huge_pages.c   |  2 +-
 .../i915/gem/selftests/i915_gem_client_blt.c  |  2 +-
 .../drm/i915/gem/selftests/i915_gem_mman.c    |  6 +++
 drivers/gpu/drm/i915/gt/intel_ggtt.c          | 45 ++++++++++++++++---
 drivers/gpu/drm/i915/i915_gem.c               |  2 +
 drivers/gpu/drm/i915/i915_vma.c               | 27 ++++++++++-
 drivers/gpu/drm/i915/i915_vma.h               |  1 +
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 22 ++++-----
 drivers/gpu/drm/i915/selftests/i915_vma.c     |  8 ++--
 10 files changed, 91 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c b/drivers/gpu/drm/i915/display/intel_fb_pin.c
index 3f77f3013584..1c0ff2ef3937 100644
--- a/drivers/gpu/drm/i915/display/intel_fb_pin.c
+++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c
@@ -47,7 +47,7 @@ intel_pin_fb_obj_dpt(struct drm_framebuffer *fb,
 		goto err;
 
 	if (i915_vma_misplaced(vma, 0, alignment, 0)) {
-		ret = i915_vma_unbind(vma);
+		ret = i915_vma_unbind_unlocked(vma);
 		if (ret) {
 			vma = ERR_PTR(ret);
 			goto err;
diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index 493509f90b35..97473ac7c7f7 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -646,7 +646,7 @@ static int igt_mock_ppgtt_misaligned_dma(void *arg)
 		 * pages.
 		 */
 		for (offset = 4096; offset < page_size; offset += 4096) {
-			err = i915_vma_unbind(vma);
+			err = i915_vma_unbind_unlocked(vma);
 			if (err)
 				goto out_unpin;
 
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 8402ed925a69..8fb5be799b3c 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
@@ -318,7 +318,7 @@ static int pin_buffer(struct i915_vma *vma, u64 addr)
 	int err;
 
 	if (drm_mm_node_allocated(&vma->node) && vma->node.start != addr) {
-		err = i915_vma_unbind(vma);
+		err = i915_vma_unbind_unlocked(vma);
 		if (err)
 			return err;
 	}
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
index 6d30cdfa80f3..e69e8861352d 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
@@ -165,7 +165,9 @@ static int check_partial_mapping(struct drm_i915_gem_object *obj,
 	kunmap(p);
 
 out:
+	i915_gem_object_lock(obj, NULL);
 	__i915_vma_put(vma);
+	i915_gem_object_unlock(obj);
 	return err;
 }
 
@@ -259,7 +261,9 @@ static int check_partial_mappings(struct drm_i915_gem_object *obj,
 		if (err)
 			return err;
 
+		i915_gem_object_lock(obj, NULL);
 		__i915_vma_put(vma);
+		i915_gem_object_unlock(obj);
 
 		if (igt_timeout(end_time,
 				"%s: timed out after tiling=%d stride=%d\n",
@@ -1349,7 +1353,9 @@ static int __igt_mmap_revoke(struct drm_i915_private *i915,
 	 * for other objects. Ergo we have to revoke the previous mmap PTE
 	 * access as it no longer points to the same object.
 	 */
+	i915_gem_object_lock(obj, NULL);
 	err = i915_gem_object_unbind(obj, I915_GEM_OBJECT_UNBIND_ACTIVE);
+	i915_gem_object_unlock(obj);
 	if (err) {
 		pr_err("Failed to unbind object!\n");
 		goto out_unmap;
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index df29fd992b45..44bc30458cac 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -118,22 +118,45 @@ void i915_ggtt_suspend(struct i915_ggtt *ggtt)
 	struct i915_vma *vma, *vn;
 	int open;
 
+retry:
+	i915_gem_drain_freed_objects(ggtt->vm.i915);
+
 	mutex_lock(&ggtt->vm.mutex);
 
 	/* Skip rewriting PTE on VMA unbind. */
 	open = atomic_xchg(&ggtt->vm.open, 0);
 
 	list_for_each_entry_safe(vma, vn, &ggtt->vm.bound_list, vm_link) {
+		struct drm_i915_gem_object *obj = vma->obj;
+
 		GEM_BUG_ON(!drm_mm_node_allocated(&vma->node));
-		i915_vma_wait_for_bind(vma);
 
-		if (i915_vma_is_pinned(vma))
+		if (i915_vma_is_pinned(vma) || !i915_vma_is_bound(vma, I915_VMA_GLOBAL_BIND))
 			continue;
 
-		if (!i915_vma_is_bound(vma, I915_VMA_GLOBAL_BIND)) {
-			__i915_vma_evict(vma);
-			drm_mm_remove_node(&vma->node);
+		/* unlikely to race when GPU is idle, so no worry about slowpath.. */
+		if (!i915_gem_object_trylock(obj, NULL)) {
+			atomic_set(&ggtt->vm.open, open);
+
+			i915_gem_object_get(obj);
+			mutex_unlock(&ggtt->vm.mutex);
+
+			i915_gem_object_lock(obj, NULL);
+			open = i915_vma_unbind(vma);
+			i915_gem_object_unlock(obj);
+
+			GEM_WARN_ON(open);
+
+			i915_gem_object_put(obj);
+			goto retry;
 		}
+
+		i915_vma_wait_for_bind(vma);
+
+		__i915_vma_evict(vma);
+		drm_mm_remove_node(&vma->node);
+
+		i915_gem_object_unlock(obj);
 	}
 
 	ggtt->vm.clear_range(&ggtt->vm, 0, ggtt->vm.total);
@@ -725,11 +748,21 @@ static void ggtt_cleanup_hw(struct i915_ggtt *ggtt)
 	atomic_set(&ggtt->vm.open, 0);
 
 	flush_workqueue(ggtt->vm.i915->wq);
+	i915_gem_drain_freed_objects(ggtt->vm.i915);
 
 	mutex_lock(&ggtt->vm.mutex);
 
-	list_for_each_entry_safe(vma, vn, &ggtt->vm.bound_list, vm_link)
+	list_for_each_entry_safe(vma, vn, &ggtt->vm.bound_list, vm_link) {
+		struct drm_i915_gem_object *obj = vma->obj;
+		bool trylock;
+
+		trylock = i915_gem_object_trylock(obj, NULL);
+		WARN_ON(!trylock);
+
 		WARN_ON(__i915_vma_unbind(vma));
+		if (trylock)
+			i915_gem_object_unlock(obj);
+	}
 
 	if (drm_mm_node_allocated(&ggtt->error_capture))
 		drm_mm_remove_node(&ggtt->error_capture);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 6aa9e465b48e..d45abf05987d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -118,6 +118,8 @@ int i915_gem_object_unbind(struct drm_i915_gem_object *obj,
 	struct i915_vma *vma;
 	int ret;
 
+	assert_object_held(obj);
+
 	if (list_empty(&obj->vma.list))
 		return 0;
 
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 3275b2364785..982bb8b739d3 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -1508,8 +1508,16 @@ void i915_vma_parked(struct intel_gt *gt)
 		struct drm_i915_gem_object *obj = vma->obj;
 		struct i915_address_space *vm = vma->vm;
 
-		INIT_LIST_HEAD(&vma->closed_link);
-		__i915_vma_put(vma);
+		if (i915_gem_object_trylock(obj, NULL)) {
+			INIT_LIST_HEAD(&vma->closed_link);
+			__i915_vma_put(vma);
+			i915_gem_object_unlock(obj);
+		} else {
+			/* back you go.. */
+			spin_lock_irq(&gt->closed_lock);
+			list_add(&vma->closed_link, &gt->closed_vma);
+			spin_unlock_irq(&gt->closed_lock);
+		}
 
 		i915_gem_object_put(obj);
 		i915_vm_close(vm);
@@ -1625,6 +1633,7 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
 void __i915_vma_evict(struct i915_vma *vma)
 {
 	GEM_BUG_ON(i915_vma_is_pinned(vma));
+	assert_object_held_shared(vma->obj);
 
 	if (i915_vma_is_map_and_fenceable(vma)) {
 		/* Force a pagefault for domain tracking on next user access */
@@ -1670,6 +1679,7 @@ int __i915_vma_unbind(struct i915_vma *vma)
 	int ret;
 
 	lockdep_assert_held(&vma->vm->mutex);
+	assert_object_held_shared(vma->obj);
 
 	if (!drm_mm_node_allocated(&vma->node))
 		return 0;
@@ -1701,6 +1711,8 @@ int i915_vma_unbind(struct i915_vma *vma)
 	intel_wakeref_t wakeref = 0;
 	int err;
 
+	assert_object_held_shared(vma->obj);
+
 	/* Optimistic wait before taking the mutex */
 	err = i915_vma_sync(vma);
 	if (err)
@@ -1731,6 +1743,17 @@ int i915_vma_unbind(struct i915_vma *vma)
 	return err;
 }
 
+int i915_vma_unbind_unlocked(struct i915_vma *vma)
+{
+	int err;
+
+	i915_gem_object_lock(vma->obj, NULL);
+	err = i915_vma_unbind(vma);
+	i915_gem_object_unlock(vma->obj);
+
+	return err;
+}
+
 struct i915_vma *i915_vma_make_unshrinkable(struct i915_vma *vma)
 {
 	i915_gem_object_make_unshrinkable(vma->obj);
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 32719431b3df..da69ecb1b860 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -214,6 +214,7 @@ void i915_vma_revoke_mmap(struct i915_vma *vma);
 void __i915_vma_evict(struct i915_vma *vma);
 int __i915_vma_unbind(struct i915_vma *vma);
 int __must_check i915_vma_unbind(struct i915_vma *vma);
+int __must_check i915_vma_unbind_unlocked(struct i915_vma *vma);
 void i915_vma_unlink_ctx(struct i915_vma *vma);
 void i915_vma_close(struct i915_vma *vma);
 void i915_vma_reopen(struct i915_vma *vma);
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 6b1db83119b3..de16897d3d9a 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -385,7 +385,7 @@ static void close_object_list(struct list_head *objects,
 
 		vma = i915_vma_instance(obj, vm, NULL);
 		if (!IS_ERR(vma))
-			ignored = i915_vma_unbind(vma);
+			ignored = i915_vma_unbind_unlocked(vma);
 
 		list_del(&obj->st_link);
 		i915_gem_object_put(obj);
@@ -496,7 +496,7 @@ static int fill_hole(struct i915_address_space *vm,
 						goto err;
 					}
 
-					err = i915_vma_unbind(vma);
+					err = i915_vma_unbind_unlocked(vma);
 					if (err) {
 						pr_err("%s(%s) (forward) unbind of vma.node=%llx + %llx failed with err=%d\n",
 						       __func__, p->name, vma->node.start, vma->node.size,
@@ -569,7 +569,7 @@ static int fill_hole(struct i915_address_space *vm,
 						goto err;
 					}
 
-					err = i915_vma_unbind(vma);
+					err = i915_vma_unbind_unlocked(vma);
 					if (err) {
 						pr_err("%s(%s) (backward) unbind of vma.node=%llx + %llx failed with err=%d\n",
 						       __func__, p->name, vma->node.start, vma->node.size,
@@ -655,7 +655,7 @@ static int walk_hole(struct i915_address_space *vm,
 				goto err_put;
 			}
 
-			err = i915_vma_unbind(vma);
+			err = i915_vma_unbind_unlocked(vma);
 			if (err) {
 				pr_err("%s unbind failed at %llx + %llx  with err=%d\n",
 				       __func__, addr, vma->size, err);
@@ -732,13 +732,13 @@ static int pot_hole(struct i915_address_space *vm,
 				pr_err("%s incorrect at %llx + %llx\n",
 				       __func__, addr, vma->size);
 				i915_vma_unpin(vma);
-				err = i915_vma_unbind(vma);
+				err = i915_vma_unbind_unlocked(vma);
 				err = -EINVAL;
 				goto err_obj;
 			}
 
 			i915_vma_unpin(vma);
-			err = i915_vma_unbind(vma);
+			err = i915_vma_unbind_unlocked(vma);
 			GEM_BUG_ON(err);
 		}
 
@@ -832,13 +832,13 @@ static int drunk_hole(struct i915_address_space *vm,
 				pr_err("%s incorrect at %llx + %llx\n",
 				       __func__, addr, BIT_ULL(size));
 				i915_vma_unpin(vma);
-				err = i915_vma_unbind(vma);
+				err = i915_vma_unbind_unlocked(vma);
 				err = -EINVAL;
 				goto err_obj;
 			}
 
 			i915_vma_unpin(vma);
-			err = i915_vma_unbind(vma);
+			err = i915_vma_unbind_unlocked(vma);
 			GEM_BUG_ON(err);
 
 			if (igt_timeout(end_time,
@@ -906,7 +906,7 @@ static int __shrink_hole(struct i915_address_space *vm,
 			pr_err("%s incorrect at %llx + %llx\n",
 			       __func__, addr, size);
 			i915_vma_unpin(vma);
-			err = i915_vma_unbind(vma);
+			err = i915_vma_unbind_unlocked(vma);
 			err = -EINVAL;
 			break;
 		}
@@ -1465,7 +1465,7 @@ static int igt_gtt_reserve(void *arg)
 			goto out;
 		}
 
-		err = i915_vma_unbind(vma);
+		err = i915_vma_unbind_unlocked(vma);
 		if (err) {
 			pr_err("i915_vma_unbind failed with err=%d!\n", err);
 			goto out;
@@ -1647,7 +1647,7 @@ static int igt_gtt_insert(void *arg)
 		GEM_BUG_ON(!drm_mm_node_allocated(&vma->node));
 		offset = vma->node.start;
 
-		err = i915_vma_unbind(vma);
+		err = i915_vma_unbind_unlocked(vma);
 		if (err) {
 			pr_err("i915_vma_unbind failed with err=%d!\n", err);
 			goto out;
diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c
index 5c5809dfe9b2..2c73f7448df7 100644
--- a/drivers/gpu/drm/i915/selftests/i915_vma.c
+++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
@@ -340,7 +340,7 @@ static int igt_vma_pin1(void *arg)
 
 		if (!err) {
 			i915_vma_unpin(vma);
-			err = i915_vma_unbind(vma);
+			err = i915_vma_unbind_unlocked(vma);
 			if (err) {
 				pr_err("Failed to unbind single page from GGTT, err=%d\n", err);
 				goto out;
@@ -691,7 +691,7 @@ static int igt_vma_rotate_remap(void *arg)
 					}
 
 					i915_vma_unpin(vma);
-					err = i915_vma_unbind(vma);
+					err = i915_vma_unbind_unlocked(vma);
 					if (err) {
 						pr_err("Unbinding returned %i\n", err);
 						goto out_object;
@@ -852,7 +852,7 @@ static int igt_vma_partial(void *arg)
 
 				i915_vma_unpin(vma);
 				nvma++;
-				err = i915_vma_unbind(vma);
+				err = i915_vma_unbind_unlocked(vma);
 				if (err) {
 					pr_err("Unbinding returned %i\n", err);
 					goto out_object;
@@ -891,7 +891,7 @@ static int igt_vma_partial(void *arg)
 
 		i915_vma_unpin(vma);
 
-		err = i915_vma_unbind(vma);
+		err = i915_vma_unbind_unlocked(vma);
 		if (err) {
 			pr_err("Unbinding returned %i\n", err);
 			goto out_object;
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 24/28] drm/i915: Add i915_vma_unbind_unlocked, and take obj lock for i915_vma_unbind
@ 2021-10-21 10:36   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:36 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

We want to remove more members of i915_vma, which requires the locking to be
held more often.

Start requiring gem object lock for i915_vma_unbind, as it's one of the
callers that may unpin pages.

Some special care is needed when evicting, because the last reference to the
object may be held by the VMA, so after __i915_vma_unbind, vma may be garbage,
and we need to cache vma->obj before unlocking.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_fb_pin.c   |  2 +-
 .../gpu/drm/i915/gem/selftests/huge_pages.c   |  2 +-
 .../i915/gem/selftests/i915_gem_client_blt.c  |  2 +-
 .../drm/i915/gem/selftests/i915_gem_mman.c    |  6 +++
 drivers/gpu/drm/i915/gt/intel_ggtt.c          | 45 ++++++++++++++++---
 drivers/gpu/drm/i915/i915_gem.c               |  2 +
 drivers/gpu/drm/i915/i915_vma.c               | 27 ++++++++++-
 drivers/gpu/drm/i915/i915_vma.h               |  1 +
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 22 ++++-----
 drivers/gpu/drm/i915/selftests/i915_vma.c     |  8 ++--
 10 files changed, 91 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c b/drivers/gpu/drm/i915/display/intel_fb_pin.c
index 3f77f3013584..1c0ff2ef3937 100644
--- a/drivers/gpu/drm/i915/display/intel_fb_pin.c
+++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c
@@ -47,7 +47,7 @@ intel_pin_fb_obj_dpt(struct drm_framebuffer *fb,
 		goto err;
 
 	if (i915_vma_misplaced(vma, 0, alignment, 0)) {
-		ret = i915_vma_unbind(vma);
+		ret = i915_vma_unbind_unlocked(vma);
 		if (ret) {
 			vma = ERR_PTR(ret);
 			goto err;
diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index 493509f90b35..97473ac7c7f7 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -646,7 +646,7 @@ static int igt_mock_ppgtt_misaligned_dma(void *arg)
 		 * pages.
 		 */
 		for (offset = 4096; offset < page_size; offset += 4096) {
-			err = i915_vma_unbind(vma);
+			err = i915_vma_unbind_unlocked(vma);
 			if (err)
 				goto out_unpin;
 
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 8402ed925a69..8fb5be799b3c 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
@@ -318,7 +318,7 @@ static int pin_buffer(struct i915_vma *vma, u64 addr)
 	int err;
 
 	if (drm_mm_node_allocated(&vma->node) && vma->node.start != addr) {
-		err = i915_vma_unbind(vma);
+		err = i915_vma_unbind_unlocked(vma);
 		if (err)
 			return err;
 	}
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
index 6d30cdfa80f3..e69e8861352d 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
@@ -165,7 +165,9 @@ static int check_partial_mapping(struct drm_i915_gem_object *obj,
 	kunmap(p);
 
 out:
+	i915_gem_object_lock(obj, NULL);
 	__i915_vma_put(vma);
+	i915_gem_object_unlock(obj);
 	return err;
 }
 
@@ -259,7 +261,9 @@ static int check_partial_mappings(struct drm_i915_gem_object *obj,
 		if (err)
 			return err;
 
+		i915_gem_object_lock(obj, NULL);
 		__i915_vma_put(vma);
+		i915_gem_object_unlock(obj);
 
 		if (igt_timeout(end_time,
 				"%s: timed out after tiling=%d stride=%d\n",
@@ -1349,7 +1353,9 @@ static int __igt_mmap_revoke(struct drm_i915_private *i915,
 	 * for other objects. Ergo we have to revoke the previous mmap PTE
 	 * access as it no longer points to the same object.
 	 */
+	i915_gem_object_lock(obj, NULL);
 	err = i915_gem_object_unbind(obj, I915_GEM_OBJECT_UNBIND_ACTIVE);
+	i915_gem_object_unlock(obj);
 	if (err) {
 		pr_err("Failed to unbind object!\n");
 		goto out_unmap;
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index df29fd992b45..44bc30458cac 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -118,22 +118,45 @@ void i915_ggtt_suspend(struct i915_ggtt *ggtt)
 	struct i915_vma *vma, *vn;
 	int open;
 
+retry:
+	i915_gem_drain_freed_objects(ggtt->vm.i915);
+
 	mutex_lock(&ggtt->vm.mutex);
 
 	/* Skip rewriting PTE on VMA unbind. */
 	open = atomic_xchg(&ggtt->vm.open, 0);
 
 	list_for_each_entry_safe(vma, vn, &ggtt->vm.bound_list, vm_link) {
+		struct drm_i915_gem_object *obj = vma->obj;
+
 		GEM_BUG_ON(!drm_mm_node_allocated(&vma->node));
-		i915_vma_wait_for_bind(vma);
 
-		if (i915_vma_is_pinned(vma))
+		if (i915_vma_is_pinned(vma) || !i915_vma_is_bound(vma, I915_VMA_GLOBAL_BIND))
 			continue;
 
-		if (!i915_vma_is_bound(vma, I915_VMA_GLOBAL_BIND)) {
-			__i915_vma_evict(vma);
-			drm_mm_remove_node(&vma->node);
+		/* unlikely to race when GPU is idle, so no worry about slowpath.. */
+		if (!i915_gem_object_trylock(obj, NULL)) {
+			atomic_set(&ggtt->vm.open, open);
+
+			i915_gem_object_get(obj);
+			mutex_unlock(&ggtt->vm.mutex);
+
+			i915_gem_object_lock(obj, NULL);
+			open = i915_vma_unbind(vma);
+			i915_gem_object_unlock(obj);
+
+			GEM_WARN_ON(open);
+
+			i915_gem_object_put(obj);
+			goto retry;
 		}
+
+		i915_vma_wait_for_bind(vma);
+
+		__i915_vma_evict(vma);
+		drm_mm_remove_node(&vma->node);
+
+		i915_gem_object_unlock(obj);
 	}
 
 	ggtt->vm.clear_range(&ggtt->vm, 0, ggtt->vm.total);
@@ -725,11 +748,21 @@ static void ggtt_cleanup_hw(struct i915_ggtt *ggtt)
 	atomic_set(&ggtt->vm.open, 0);
 
 	flush_workqueue(ggtt->vm.i915->wq);
+	i915_gem_drain_freed_objects(ggtt->vm.i915);
 
 	mutex_lock(&ggtt->vm.mutex);
 
-	list_for_each_entry_safe(vma, vn, &ggtt->vm.bound_list, vm_link)
+	list_for_each_entry_safe(vma, vn, &ggtt->vm.bound_list, vm_link) {
+		struct drm_i915_gem_object *obj = vma->obj;
+		bool trylock;
+
+		trylock = i915_gem_object_trylock(obj, NULL);
+		WARN_ON(!trylock);
+
 		WARN_ON(__i915_vma_unbind(vma));
+		if (trylock)
+			i915_gem_object_unlock(obj);
+	}
 
 	if (drm_mm_node_allocated(&ggtt->error_capture))
 		drm_mm_remove_node(&ggtt->error_capture);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 6aa9e465b48e..d45abf05987d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -118,6 +118,8 @@ int i915_gem_object_unbind(struct drm_i915_gem_object *obj,
 	struct i915_vma *vma;
 	int ret;
 
+	assert_object_held(obj);
+
 	if (list_empty(&obj->vma.list))
 		return 0;
 
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 3275b2364785..982bb8b739d3 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -1508,8 +1508,16 @@ void i915_vma_parked(struct intel_gt *gt)
 		struct drm_i915_gem_object *obj = vma->obj;
 		struct i915_address_space *vm = vma->vm;
 
-		INIT_LIST_HEAD(&vma->closed_link);
-		__i915_vma_put(vma);
+		if (i915_gem_object_trylock(obj, NULL)) {
+			INIT_LIST_HEAD(&vma->closed_link);
+			__i915_vma_put(vma);
+			i915_gem_object_unlock(obj);
+		} else {
+			/* back you go.. */
+			spin_lock_irq(&gt->closed_lock);
+			list_add(&vma->closed_link, &gt->closed_vma);
+			spin_unlock_irq(&gt->closed_lock);
+		}
 
 		i915_gem_object_put(obj);
 		i915_vm_close(vm);
@@ -1625,6 +1633,7 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
 void __i915_vma_evict(struct i915_vma *vma)
 {
 	GEM_BUG_ON(i915_vma_is_pinned(vma));
+	assert_object_held_shared(vma->obj);
 
 	if (i915_vma_is_map_and_fenceable(vma)) {
 		/* Force a pagefault for domain tracking on next user access */
@@ -1670,6 +1679,7 @@ int __i915_vma_unbind(struct i915_vma *vma)
 	int ret;
 
 	lockdep_assert_held(&vma->vm->mutex);
+	assert_object_held_shared(vma->obj);
 
 	if (!drm_mm_node_allocated(&vma->node))
 		return 0;
@@ -1701,6 +1711,8 @@ int i915_vma_unbind(struct i915_vma *vma)
 	intel_wakeref_t wakeref = 0;
 	int err;
 
+	assert_object_held_shared(vma->obj);
+
 	/* Optimistic wait before taking the mutex */
 	err = i915_vma_sync(vma);
 	if (err)
@@ -1731,6 +1743,17 @@ int i915_vma_unbind(struct i915_vma *vma)
 	return err;
 }
 
+int i915_vma_unbind_unlocked(struct i915_vma *vma)
+{
+	int err;
+
+	i915_gem_object_lock(vma->obj, NULL);
+	err = i915_vma_unbind(vma);
+	i915_gem_object_unlock(vma->obj);
+
+	return err;
+}
+
 struct i915_vma *i915_vma_make_unshrinkable(struct i915_vma *vma)
 {
 	i915_gem_object_make_unshrinkable(vma->obj);
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 32719431b3df..da69ecb1b860 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -214,6 +214,7 @@ void i915_vma_revoke_mmap(struct i915_vma *vma);
 void __i915_vma_evict(struct i915_vma *vma);
 int __i915_vma_unbind(struct i915_vma *vma);
 int __must_check i915_vma_unbind(struct i915_vma *vma);
+int __must_check i915_vma_unbind_unlocked(struct i915_vma *vma);
 void i915_vma_unlink_ctx(struct i915_vma *vma);
 void i915_vma_close(struct i915_vma *vma);
 void i915_vma_reopen(struct i915_vma *vma);
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 6b1db83119b3..de16897d3d9a 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -385,7 +385,7 @@ static void close_object_list(struct list_head *objects,
 
 		vma = i915_vma_instance(obj, vm, NULL);
 		if (!IS_ERR(vma))
-			ignored = i915_vma_unbind(vma);
+			ignored = i915_vma_unbind_unlocked(vma);
 
 		list_del(&obj->st_link);
 		i915_gem_object_put(obj);
@@ -496,7 +496,7 @@ static int fill_hole(struct i915_address_space *vm,
 						goto err;
 					}
 
-					err = i915_vma_unbind(vma);
+					err = i915_vma_unbind_unlocked(vma);
 					if (err) {
 						pr_err("%s(%s) (forward) unbind of vma.node=%llx + %llx failed with err=%d\n",
 						       __func__, p->name, vma->node.start, vma->node.size,
@@ -569,7 +569,7 @@ static int fill_hole(struct i915_address_space *vm,
 						goto err;
 					}
 
-					err = i915_vma_unbind(vma);
+					err = i915_vma_unbind_unlocked(vma);
 					if (err) {
 						pr_err("%s(%s) (backward) unbind of vma.node=%llx + %llx failed with err=%d\n",
 						       __func__, p->name, vma->node.start, vma->node.size,
@@ -655,7 +655,7 @@ static int walk_hole(struct i915_address_space *vm,
 				goto err_put;
 			}
 
-			err = i915_vma_unbind(vma);
+			err = i915_vma_unbind_unlocked(vma);
 			if (err) {
 				pr_err("%s unbind failed at %llx + %llx  with err=%d\n",
 				       __func__, addr, vma->size, err);
@@ -732,13 +732,13 @@ static int pot_hole(struct i915_address_space *vm,
 				pr_err("%s incorrect at %llx + %llx\n",
 				       __func__, addr, vma->size);
 				i915_vma_unpin(vma);
-				err = i915_vma_unbind(vma);
+				err = i915_vma_unbind_unlocked(vma);
 				err = -EINVAL;
 				goto err_obj;
 			}
 
 			i915_vma_unpin(vma);
-			err = i915_vma_unbind(vma);
+			err = i915_vma_unbind_unlocked(vma);
 			GEM_BUG_ON(err);
 		}
 
@@ -832,13 +832,13 @@ static int drunk_hole(struct i915_address_space *vm,
 				pr_err("%s incorrect at %llx + %llx\n",
 				       __func__, addr, BIT_ULL(size));
 				i915_vma_unpin(vma);
-				err = i915_vma_unbind(vma);
+				err = i915_vma_unbind_unlocked(vma);
 				err = -EINVAL;
 				goto err_obj;
 			}
 
 			i915_vma_unpin(vma);
-			err = i915_vma_unbind(vma);
+			err = i915_vma_unbind_unlocked(vma);
 			GEM_BUG_ON(err);
 
 			if (igt_timeout(end_time,
@@ -906,7 +906,7 @@ static int __shrink_hole(struct i915_address_space *vm,
 			pr_err("%s incorrect at %llx + %llx\n",
 			       __func__, addr, size);
 			i915_vma_unpin(vma);
-			err = i915_vma_unbind(vma);
+			err = i915_vma_unbind_unlocked(vma);
 			err = -EINVAL;
 			break;
 		}
@@ -1465,7 +1465,7 @@ static int igt_gtt_reserve(void *arg)
 			goto out;
 		}
 
-		err = i915_vma_unbind(vma);
+		err = i915_vma_unbind_unlocked(vma);
 		if (err) {
 			pr_err("i915_vma_unbind failed with err=%d!\n", err);
 			goto out;
@@ -1647,7 +1647,7 @@ static int igt_gtt_insert(void *arg)
 		GEM_BUG_ON(!drm_mm_node_allocated(&vma->node));
 		offset = vma->node.start;
 
-		err = i915_vma_unbind(vma);
+		err = i915_vma_unbind_unlocked(vma);
 		if (err) {
 			pr_err("i915_vma_unbind failed with err=%d!\n", err);
 			goto out;
diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c b/drivers/gpu/drm/i915/selftests/i915_vma.c
index 5c5809dfe9b2..2c73f7448df7 100644
--- a/drivers/gpu/drm/i915/selftests/i915_vma.c
+++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
@@ -340,7 +340,7 @@ static int igt_vma_pin1(void *arg)
 
 		if (!err) {
 			i915_vma_unpin(vma);
-			err = i915_vma_unbind(vma);
+			err = i915_vma_unbind_unlocked(vma);
 			if (err) {
 				pr_err("Failed to unbind single page from GGTT, err=%d\n", err);
 				goto out;
@@ -691,7 +691,7 @@ static int igt_vma_rotate_remap(void *arg)
 					}
 
 					i915_vma_unpin(vma);
-					err = i915_vma_unbind(vma);
+					err = i915_vma_unbind_unlocked(vma);
 					if (err) {
 						pr_err("Unbinding returned %i\n", err);
 						goto out_object;
@@ -852,7 +852,7 @@ static int igt_vma_partial(void *arg)
 
 				i915_vma_unpin(vma);
 				nvma++;
-				err = i915_vma_unbind(vma);
+				err = i915_vma_unbind_unlocked(vma);
 				if (err) {
 					pr_err("Unbinding returned %i\n", err);
 					goto out_object;
@@ -891,7 +891,7 @@ static int igt_vma_partial(void *arg)
 
 		i915_vma_unpin(vma);
 
-		err = i915_vma_unbind(vma);
+		err = i915_vma_unbind_unlocked(vma);
 		if (err) {
 			pr_err("Unbinding returned %i\n", err);
 			goto out_object;
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 25/28] drm/i915: Require object lock when freeing pages during destruction
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:36   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:36 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

TTM already requires this, and we require it for delayed destroy.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_object.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
index 1e426a42a36c..d549f34829d0 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
@@ -257,6 +257,8 @@ static void __i915_gem_object_free_mmaps(struct drm_i915_gem_object *obj)
  */
 void __i915_gem_object_pages_fini(struct drm_i915_gem_object *obj)
 {
+	assert_object_held(obj);
+
 	if (!list_empty(&obj->vma.list)) {
 		struct i915_vma *vma;
 
@@ -323,7 +325,10 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915,
 			obj->ops->delayed_free(obj);
 			continue;
 		}
+
+		i915_gem_object_lock(obj, NULL);
 		__i915_gem_object_pages_fini(obj);
+		i915_gem_object_unlock(obj);
 		__i915_gem_free_object(obj);
 
 		/* But keep the pointer alive for RCU-protected lookups */
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 25/28] drm/i915: Require object lock when freeing pages during destruction
@ 2021-10-21 10:36   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:36 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

TTM already requires this, and we require it for delayed destroy.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_object.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
index 1e426a42a36c..d549f34829d0 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
@@ -257,6 +257,8 @@ static void __i915_gem_object_free_mmaps(struct drm_i915_gem_object *obj)
  */
 void __i915_gem_object_pages_fini(struct drm_i915_gem_object *obj)
 {
+	assert_object_held(obj);
+
 	if (!list_empty(&obj->vma.list)) {
 		struct i915_vma *vma;
 
@@ -323,7 +325,10 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915,
 			obj->ops->delayed_free(obj);
 			continue;
 		}
+
+		i915_gem_object_lock(obj, NULL);
 		__i915_gem_object_pages_fini(obj);
+		i915_gem_object_unlock(obj);
 		__i915_gem_free_object(obj);
 
 		/* But keep the pointer alive for RCU-protected lookups */
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 26/28] drm/i915: Remove assert_object_held_shared
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:36   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:36 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

This duck tape workaround is no longer required, unbind and destroy are
fixed to take the obj->resv mutex before destroying and obj->mm.lock has
been removed, always requiring obj->resv as well.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_object.c  |  4 ++--
 drivers/gpu/drm/i915/gem/i915_gem_object.h  | 14 --------------
 drivers/gpu/drm/i915/gem/i915_gem_pages.c   | 12 ++++++------
 drivers/gpu/drm/i915/gem/i915_gem_userptr.c |  2 +-
 drivers/gpu/drm/i915/i915_vma.c             |  6 +++---
 5 files changed, 12 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
index d549f34829d0..a4fb76b7841d 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
@@ -548,7 +548,7 @@ bool i915_gem_object_has_struct_page(const struct drm_i915_gem_object *obj)
 #ifdef CONFIG_LOCKDEP
 	if (IS_DGFX(to_i915(obj->base.dev)) &&
 	    i915_gem_object_evictable((void __force *)obj))
-		assert_object_held_shared(obj);
+		assert_object_held(obj);
 #endif
 	return obj->mem_flags & I915_BO_FLAG_STRUCT_PAGE;
 }
@@ -567,7 +567,7 @@ bool i915_gem_object_has_iomem(const struct drm_i915_gem_object *obj)
 #ifdef CONFIG_LOCKDEP
 	if (IS_DGFX(to_i915(obj->base.dev)) &&
 	    i915_gem_object_evictable((void __force *)obj))
-		assert_object_held_shared(obj);
+		assert_object_held(obj);
 #endif
 	return obj->mem_flags & I915_BO_FLAG_IOMEM;
 }
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index accd8fad0ed7..ef4f2568d46a 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -158,20 +158,6 @@ i915_gem_object_put(struct drm_i915_gem_object *obj)
 
 #define assert_object_held(obj) dma_resv_assert_held((obj)->base.resv)
 
-/*
- * If more than one potential simultaneous locker, assert held.
- */
-static inline void assert_object_held_shared(const struct drm_i915_gem_object *obj)
-{
-	/*
-	 * Note mm list lookup is protected by
-	 * kref_get_unless_zero().
-	 */
-	if (IS_ENABLED(CONFIG_LOCKDEP) &&
-	    kref_read(&obj->base.refcount) > 0)
-		assert_object_held(obj);
-}
-
 static inline int __i915_gem_object_lock(struct drm_i915_gem_object *obj,
 					 struct i915_gem_ww_ctx *ww,
 					 bool intr)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
index 8eb1c3a6fc9c..dbd226b0ea49 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
@@ -19,7 +19,7 @@ void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj,
 	bool shrinkable;
 	int i;
 
-	assert_object_held_shared(obj);
+	assert_object_held(obj);
 
 	if (i915_gem_object_is_volatile(obj))
 		obj->mm.madv = I915_MADV_DONTNEED;
@@ -94,7 +94,7 @@ int ____i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
 	struct drm_i915_private *i915 = to_i915(obj->base.dev);
 	int err;
 
-	assert_object_held_shared(obj);
+	assert_object_held(obj);
 
 	if (unlikely(obj->mm.madv != I915_MADV_WILLNEED)) {
 		drm_dbg(&i915->drm,
@@ -121,7 +121,7 @@ int __i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
 
 	assert_object_held(obj);
 
-	assert_object_held_shared(obj);
+	assert_object_held(obj);
 
 	if (unlikely(!i915_gem_object_has_pages(obj))) {
 		GEM_BUG_ON(i915_gem_object_has_pinned_pages(obj));
@@ -168,7 +168,7 @@ void i915_gem_object_truncate(struct drm_i915_gem_object *obj)
 /* Try to discard unwanted pages */
 void i915_gem_object_writeback(struct drm_i915_gem_object *obj)
 {
-	assert_object_held_shared(obj);
+	assert_object_held(obj);
 	GEM_BUG_ON(i915_gem_object_has_pages(obj));
 
 	if (obj->ops->writeback)
@@ -199,7 +199,7 @@ __i915_gem_object_unset_pages(struct drm_i915_gem_object *obj)
 {
 	struct sg_table *pages;
 
-	assert_object_held_shared(obj);
+	assert_object_held(obj);
 
 	pages = fetch_and_zero(&obj->mm.pages);
 	if (IS_ERR_OR_NULL(pages))
@@ -229,7 +229,7 @@ int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj)
 		return -EBUSY;
 
 	/* May be called by shrinker from within get_pages() (on another bo) */
-	assert_object_held_shared(obj);
+	assert_object_held(obj);
 
 	i915_gem_object_release_mmap_offset(obj);
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
index 3173c9f9a040..a315c010f635 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
@@ -109,7 +109,7 @@ static void i915_gem_object_userptr_drop_ref(struct drm_i915_gem_object *obj)
 {
 	struct page **pvec = NULL;
 
-	assert_object_held_shared(obj);
+	assert_object_held(obj);
 
 	if (!--obj->userptr.page_ref) {
 		pvec = obj->userptr.pvec;
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 982bb8b739d3..8131dbf89048 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -1633,7 +1633,7 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
 void __i915_vma_evict(struct i915_vma *vma)
 {
 	GEM_BUG_ON(i915_vma_is_pinned(vma));
-	assert_object_held_shared(vma->obj);
+	assert_object_held(vma->obj);
 
 	if (i915_vma_is_map_and_fenceable(vma)) {
 		/* Force a pagefault for domain tracking on next user access */
@@ -1679,7 +1679,7 @@ int __i915_vma_unbind(struct i915_vma *vma)
 	int ret;
 
 	lockdep_assert_held(&vma->vm->mutex);
-	assert_object_held_shared(vma->obj);
+	assert_object_held(vma->obj);
 
 	if (!drm_mm_node_allocated(&vma->node))
 		return 0;
@@ -1711,7 +1711,7 @@ int i915_vma_unbind(struct i915_vma *vma)
 	intel_wakeref_t wakeref = 0;
 	int err;
 
-	assert_object_held_shared(vma->obj);
+	assert_object_held(vma->obj);
 
 	/* Optimistic wait before taking the mutex */
 	err = i915_vma_sync(vma);
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 26/28] drm/i915: Remove assert_object_held_shared
@ 2021-10-21 10:36   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:36 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

This duck tape workaround is no longer required, unbind and destroy are
fixed to take the obj->resv mutex before destroying and obj->mm.lock has
been removed, always requiring obj->resv as well.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_object.c  |  4 ++--
 drivers/gpu/drm/i915/gem/i915_gem_object.h  | 14 --------------
 drivers/gpu/drm/i915/gem/i915_gem_pages.c   | 12 ++++++------
 drivers/gpu/drm/i915/gem/i915_gem_userptr.c |  2 +-
 drivers/gpu/drm/i915/i915_vma.c             |  6 +++---
 5 files changed, 12 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
index d549f34829d0..a4fb76b7841d 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
@@ -548,7 +548,7 @@ bool i915_gem_object_has_struct_page(const struct drm_i915_gem_object *obj)
 #ifdef CONFIG_LOCKDEP
 	if (IS_DGFX(to_i915(obj->base.dev)) &&
 	    i915_gem_object_evictable((void __force *)obj))
-		assert_object_held_shared(obj);
+		assert_object_held(obj);
 #endif
 	return obj->mem_flags & I915_BO_FLAG_STRUCT_PAGE;
 }
@@ -567,7 +567,7 @@ bool i915_gem_object_has_iomem(const struct drm_i915_gem_object *obj)
 #ifdef CONFIG_LOCKDEP
 	if (IS_DGFX(to_i915(obj->base.dev)) &&
 	    i915_gem_object_evictable((void __force *)obj))
-		assert_object_held_shared(obj);
+		assert_object_held(obj);
 #endif
 	return obj->mem_flags & I915_BO_FLAG_IOMEM;
 }
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index accd8fad0ed7..ef4f2568d46a 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -158,20 +158,6 @@ i915_gem_object_put(struct drm_i915_gem_object *obj)
 
 #define assert_object_held(obj) dma_resv_assert_held((obj)->base.resv)
 
-/*
- * If more than one potential simultaneous locker, assert held.
- */
-static inline void assert_object_held_shared(const struct drm_i915_gem_object *obj)
-{
-	/*
-	 * Note mm list lookup is protected by
-	 * kref_get_unless_zero().
-	 */
-	if (IS_ENABLED(CONFIG_LOCKDEP) &&
-	    kref_read(&obj->base.refcount) > 0)
-		assert_object_held(obj);
-}
-
 static inline int __i915_gem_object_lock(struct drm_i915_gem_object *obj,
 					 struct i915_gem_ww_ctx *ww,
 					 bool intr)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
index 8eb1c3a6fc9c..dbd226b0ea49 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
@@ -19,7 +19,7 @@ void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj,
 	bool shrinkable;
 	int i;
 
-	assert_object_held_shared(obj);
+	assert_object_held(obj);
 
 	if (i915_gem_object_is_volatile(obj))
 		obj->mm.madv = I915_MADV_DONTNEED;
@@ -94,7 +94,7 @@ int ____i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
 	struct drm_i915_private *i915 = to_i915(obj->base.dev);
 	int err;
 
-	assert_object_held_shared(obj);
+	assert_object_held(obj);
 
 	if (unlikely(obj->mm.madv != I915_MADV_WILLNEED)) {
 		drm_dbg(&i915->drm,
@@ -121,7 +121,7 @@ int __i915_gem_object_get_pages(struct drm_i915_gem_object *obj)
 
 	assert_object_held(obj);
 
-	assert_object_held_shared(obj);
+	assert_object_held(obj);
 
 	if (unlikely(!i915_gem_object_has_pages(obj))) {
 		GEM_BUG_ON(i915_gem_object_has_pinned_pages(obj));
@@ -168,7 +168,7 @@ void i915_gem_object_truncate(struct drm_i915_gem_object *obj)
 /* Try to discard unwanted pages */
 void i915_gem_object_writeback(struct drm_i915_gem_object *obj)
 {
-	assert_object_held_shared(obj);
+	assert_object_held(obj);
 	GEM_BUG_ON(i915_gem_object_has_pages(obj));
 
 	if (obj->ops->writeback)
@@ -199,7 +199,7 @@ __i915_gem_object_unset_pages(struct drm_i915_gem_object *obj)
 {
 	struct sg_table *pages;
 
-	assert_object_held_shared(obj);
+	assert_object_held(obj);
 
 	pages = fetch_and_zero(&obj->mm.pages);
 	if (IS_ERR_OR_NULL(pages))
@@ -229,7 +229,7 @@ int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj)
 		return -EBUSY;
 
 	/* May be called by shrinker from within get_pages() (on another bo) */
-	assert_object_held_shared(obj);
+	assert_object_held(obj);
 
 	i915_gem_object_release_mmap_offset(obj);
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
index 3173c9f9a040..a315c010f635 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
@@ -109,7 +109,7 @@ static void i915_gem_object_userptr_drop_ref(struct drm_i915_gem_object *obj)
 {
 	struct page **pvec = NULL;
 
-	assert_object_held_shared(obj);
+	assert_object_held(obj);
 
 	if (!--obj->userptr.page_ref) {
 		pvec = obj->userptr.pvec;
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 982bb8b739d3..8131dbf89048 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -1633,7 +1633,7 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
 void __i915_vma_evict(struct i915_vma *vma)
 {
 	GEM_BUG_ON(i915_vma_is_pinned(vma));
-	assert_object_held_shared(vma->obj);
+	assert_object_held(vma->obj);
 
 	if (i915_vma_is_map_and_fenceable(vma)) {
 		/* Force a pagefault for domain tracking on next user access */
@@ -1679,7 +1679,7 @@ int __i915_vma_unbind(struct i915_vma *vma)
 	int ret;
 
 	lockdep_assert_held(&vma->vm->mutex);
-	assert_object_held_shared(vma->obj);
+	assert_object_held(vma->obj);
 
 	if (!drm_mm_node_allocated(&vma->node))
 		return 0;
@@ -1711,7 +1711,7 @@ int i915_vma_unbind(struct i915_vma *vma)
 	intel_wakeref_t wakeref = 0;
 	int err;
 
-	assert_object_held_shared(vma->obj);
+	assert_object_held(vma->obj);
 
 	/* Optimistic wait before taking the mutex */
 	err = i915_vma_sync(vma);
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 27/28] drm/i915: Remove support for unlocked i915_vma unbind
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:36   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:36 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst, Niranjana Vishwanathapura

Now that we require the object lock for all ops, some code handling
race conditions can be removed.

This is required to not take short-term pins inside execbuf.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Acked-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 drivers/gpu/drm/i915/i915_vma.c | 40 +++++----------------------------
 1 file changed, 5 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 8131dbf89048..65168db534f0 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -749,7 +749,6 @@ i915_vma_detach(struct i915_vma *vma)
 static bool try_qad_pin(struct i915_vma *vma, unsigned int flags)
 {
 	unsigned int bound;
-	bool pinned = true;
 
 	bound = atomic_read(&vma->flags);
 	do {
@@ -759,34 +758,10 @@ static bool try_qad_pin(struct i915_vma *vma, unsigned int flags)
 		if (unlikely(bound & (I915_VMA_OVERFLOW | I915_VMA_ERROR)))
 			return false;
 
-		if (!(bound & I915_VMA_PIN_MASK))
-			goto unpinned;
-
 		GEM_BUG_ON(((bound + 1) & I915_VMA_PIN_MASK) == 0);
 	} while (!atomic_try_cmpxchg(&vma->flags, &bound, bound + 1));
 
 	return true;
-
-unpinned:
-	/*
-	 * If pin_count==0, but we are bound, check under the lock to avoid
-	 * racing with a concurrent i915_vma_unbind().
-	 */
-	mutex_lock(&vma->vm->mutex);
-	do {
-		if (unlikely(bound & (I915_VMA_OVERFLOW | I915_VMA_ERROR))) {
-			pinned = false;
-			break;
-		}
-
-		if (unlikely(flags & ~bound)) {
-			pinned = false;
-			break;
-		}
-	} while (!atomic_try_cmpxchg(&vma->flags, &bound, bound + 1));
-	mutex_unlock(&vma->vm->mutex);
-
-	return pinned;
 }
 
 
@@ -1112,13 +1087,7 @@ __i915_vma_get_pages(struct i915_vma *vma)
 			vma->ggtt_view.type, ret);
 	}
 
-	pages = xchg(&vma->pages, pages);
-
-	/* did we race against a put_pages? */
-	if (pages && pages != vma->obj->mm.pages) {
-		sg_free_table(vma->pages);
-		kfree(vma->pages);
-	}
+	vma->pages = pages;
 
 	return ret;
 }
@@ -1152,13 +1121,14 @@ I915_SELFTEST_EXPORT int i915_vma_get_pages(struct i915_vma *vma)
 static void __vma_put_pages(struct i915_vma *vma, unsigned int count)
 {
 	/* We allocate under vma_get_pages, so beware the shrinker */
-	struct sg_table *pages = READ_ONCE(vma->pages);
+	struct sg_table *pages = vma->pages;
 
 	GEM_BUG_ON(atomic_read(&vma->pages_count) < count);
 
 	if (atomic_sub_return(count, &vma->pages_count) == 0) {
-		if (pages == cmpxchg(&vma->pages, pages, NULL) &&
-		    pages != vma->obj->mm.pages) {
+		vma->pages = NULL;
+
+		if (pages != vma->obj->mm.pages) {
 			sg_free_table(pages);
 			kfree(pages);
 		}
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 27/28] drm/i915: Remove support for unlocked i915_vma unbind
@ 2021-10-21 10:36   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:36 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst, Niranjana Vishwanathapura

Now that we require the object lock for all ops, some code handling
race conditions can be removed.

This is required to not take short-term pins inside execbuf.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Acked-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
---
 drivers/gpu/drm/i915/i915_vma.c | 40 +++++----------------------------
 1 file changed, 5 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 8131dbf89048..65168db534f0 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -749,7 +749,6 @@ i915_vma_detach(struct i915_vma *vma)
 static bool try_qad_pin(struct i915_vma *vma, unsigned int flags)
 {
 	unsigned int bound;
-	bool pinned = true;
 
 	bound = atomic_read(&vma->flags);
 	do {
@@ -759,34 +758,10 @@ static bool try_qad_pin(struct i915_vma *vma, unsigned int flags)
 		if (unlikely(bound & (I915_VMA_OVERFLOW | I915_VMA_ERROR)))
 			return false;
 
-		if (!(bound & I915_VMA_PIN_MASK))
-			goto unpinned;
-
 		GEM_BUG_ON(((bound + 1) & I915_VMA_PIN_MASK) == 0);
 	} while (!atomic_try_cmpxchg(&vma->flags, &bound, bound + 1));
 
 	return true;
-
-unpinned:
-	/*
-	 * If pin_count==0, but we are bound, check under the lock to avoid
-	 * racing with a concurrent i915_vma_unbind().
-	 */
-	mutex_lock(&vma->vm->mutex);
-	do {
-		if (unlikely(bound & (I915_VMA_OVERFLOW | I915_VMA_ERROR))) {
-			pinned = false;
-			break;
-		}
-
-		if (unlikely(flags & ~bound)) {
-			pinned = false;
-			break;
-		}
-	} while (!atomic_try_cmpxchg(&vma->flags, &bound, bound + 1));
-	mutex_unlock(&vma->vm->mutex);
-
-	return pinned;
 }
 
 
@@ -1112,13 +1087,7 @@ __i915_vma_get_pages(struct i915_vma *vma)
 			vma->ggtt_view.type, ret);
 	}
 
-	pages = xchg(&vma->pages, pages);
-
-	/* did we race against a put_pages? */
-	if (pages && pages != vma->obj->mm.pages) {
-		sg_free_table(vma->pages);
-		kfree(vma->pages);
-	}
+	vma->pages = pages;
 
 	return ret;
 }
@@ -1152,13 +1121,14 @@ I915_SELFTEST_EXPORT int i915_vma_get_pages(struct i915_vma *vma)
 static void __vma_put_pages(struct i915_vma *vma, unsigned int count)
 {
 	/* We allocate under vma_get_pages, so beware the shrinker */
-	struct sg_table *pages = READ_ONCE(vma->pages);
+	struct sg_table *pages = vma->pages;
 
 	GEM_BUG_ON(atomic_read(&vma->pages_count) < count);
 
 	if (atomic_sub_return(count, &vma->pages_count) == 0) {
-		if (pages == cmpxchg(&vma->pages, pages, NULL) &&
-		    pages != vma->obj->mm.pages) {
+		vma->pages = NULL;
+
+		if (pages != vma->obj->mm.pages) {
 			sg_free_table(pages);
 			kfree(pages);
 		}
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [PATCH 28/28] drm/i915: Remove short-term pins from execbuf, v4.
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:36   ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:36 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

Add a flag PIN_VALIDATE, to indicate we don't need to pin and only
protected by the object lock.

This removes the need to unpin, which is done by just releasing the
lock.

eb_reserve is slightly reworked for readability, but the same steps
are still done:
- First pass pins with NONBLOCK.
- Second pass unbinds all objects first, then pins.
- Third pass is only called when not all objects are softpinned, and
  unbinds all objects, then calls i915_gem_evict_vm(), then pins.

When evicting the entire vm in eb_reserve() we do temporarily pin objects
that are marked with EXEC_OBJECT_PINNED. This is because they are already
at their destination, and i915_gem_evict_vm() would otherwise unbind them.

However, we reduce the visibility of those pins by limiting the pin
to our call to i915_gem_evict_vm() only, and pin with vm->mutex held,
instead of the entire duration of the execbuf.

Not sure the latter matters, one can hope..
In theory we could kill the pinning by adding an extra flag to the vma
to temporarily prevent unbinding for gtt for i915_gem_evict_vm only, but
I think that might be overkill. We're still holding the object lock, and
we don't have blocking eviction yet. It's likely sufficient to simply
enforce EXEC_OBJECT_PINNED for all objects on >= gen12.

Changes since v1:
- Split out eb_reserve() into separate functions for readability.
Changes since v2:
- Make batch buffer mappable on platforms where only GGTT is available,
  to prevent moving the batch buffer during relocations.
Changes since v3:
- Preserve current behavior for batch buffer, instead be cautious when
  calling i915_gem_object_ggtt_pin_ww, and re-use the current batch vma
  if it's inside ggtt and map-and-fenceable.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 252 ++++++++++--------
 drivers/gpu/drm/i915/i915_gem_gtt.h           |   1 +
 drivers/gpu/drm/i915/i915_vma.c               |  24 +-
 3 files changed, 161 insertions(+), 116 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index bbf2a10738f7..19f91143cfcf 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -439,7 +439,7 @@ eb_pin_vma(struct i915_execbuffer *eb,
 	else
 		pin_flags = entry->offset & PIN_OFFSET_MASK;
 
-	pin_flags |= PIN_USER | PIN_NOEVICT | PIN_OFFSET_FIXED;
+	pin_flags |= PIN_USER | PIN_NOEVICT | PIN_OFFSET_FIXED | PIN_VALIDATE;
 	if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_GTT))
 		pin_flags |= PIN_GLOBAL;
 
@@ -457,17 +457,15 @@ eb_pin_vma(struct i915_execbuffer *eb,
 					     entry->pad_to_size,
 					     entry->alignment,
 					     eb_pin_flags(entry, ev->flags) |
-					     PIN_USER | PIN_NOEVICT);
+					     PIN_USER | PIN_NOEVICT | PIN_VALIDATE);
 		if (unlikely(err))
 			return err;
 	}
 
 	if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_FENCE)) {
 		err = i915_vma_pin_fence(vma);
-		if (unlikely(err)) {
-			i915_vma_unpin(vma);
+		if (unlikely(err))
 			return err;
-		}
 
 		if (vma->fence)
 			ev->flags |= __EXEC_OBJECT_HAS_FENCE;
@@ -483,13 +481,9 @@ eb_pin_vma(struct i915_execbuffer *eb,
 static inline void
 eb_unreserve_vma(struct eb_vma *ev)
 {
-	if (!(ev->flags & __EXEC_OBJECT_HAS_PIN))
-		return;
-
 	if (unlikely(ev->flags & __EXEC_OBJECT_HAS_FENCE))
 		__i915_vma_unpin_fence(ev->vma);
 
-	__i915_vma_unpin(ev->vma);
 	ev->flags &= ~__EXEC_OBJECT_RESERVED;
 }
 
@@ -682,10 +676,8 @@ static int eb_reserve_vma(struct i915_execbuffer *eb,
 
 	if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_FENCE)) {
 		err = i915_vma_pin_fence(vma);
-		if (unlikely(err)) {
-			i915_vma_unpin(vma);
+		if (unlikely(err))
 			return err;
-		}
 
 		if (vma->fence)
 			ev->flags |= __EXEC_OBJECT_HAS_FENCE;
@@ -697,85 +689,129 @@ static int eb_reserve_vma(struct i915_execbuffer *eb,
 	return 0;
 }
 
-static int eb_reserve(struct i915_execbuffer *eb)
+static int eb_evict_vm(struct i915_execbuffer *eb)
+{
+	const unsigned int count = eb->buffer_count;
+	unsigned int i;
+	int err;
+
+	err = mutex_lock_interruptible(&eb->context->vm->mutex);
+	if (err)
+		return err;
+
+	/* pin to protect against i915_gem_evict_vm evicting below */
+	for (i = 0; i < count; i++) {
+		struct eb_vma *ev = &eb->vma[i];
+
+		if (ev->flags & __EXEC_OBJECT_HAS_PIN)
+			__i915_vma_pin(ev->vma);
+	}
+
+	/* Too fragmented, unbind everything and retry */
+	err = i915_gem_evict_vm(eb->context->vm, &eb->ww);
+
+	/* unpin objects.. */
+	for (i = 0; i < count; i++) {
+		struct eb_vma *ev = &eb->vma[i];
+
+		if (ev->flags & __EXEC_OBJECT_HAS_PIN)
+			i915_vma_unpin(ev->vma);
+	}
+
+	mutex_unlock(&eb->context->vm->mutex);
+
+	return err;
+}
+
+static bool eb_unbind(struct i915_execbuffer *eb)
 {
 	const unsigned int count = eb->buffer_count;
-	unsigned int pin_flags = PIN_USER | PIN_NONBLOCK;
+	unsigned int i;
 	struct list_head last;
+	bool unpinned = false;
+
+	/* Resort *all* the objects into priority order */
+	INIT_LIST_HEAD(&eb->unbound);
+	INIT_LIST_HEAD(&last);
+
+	for (i = 0; i < count; i++) {
+		struct eb_vma *ev = &eb->vma[i];
+		unsigned int flags = ev->flags;
+
+		if (flags & EXEC_OBJECT_PINNED &&
+		    flags & __EXEC_OBJECT_HAS_PIN)
+			continue;
+
+		unpinned = true;
+		eb_unreserve_vma(ev);
+
+		if (flags & EXEC_OBJECT_PINNED)
+			/* Pinned must have their slot */
+			list_add(&ev->bind_link, &eb->unbound);
+		else if (flags & __EXEC_OBJECT_NEEDS_MAP)
+			/* Map require the lowest 256MiB (aperture) */
+			list_add_tail(&ev->bind_link, &eb->unbound);
+		else if (!(flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS))
+			/* Prioritise 4GiB region for restricted bo */
+			list_add(&ev->bind_link, &last);
+		else
+			list_add_tail(&ev->bind_link, &last);
+	}
+
+	list_splice_tail(&last, &eb->unbound);
+	return unpinned;
+}
+
+static int eb_reserve(struct i915_execbuffer *eb)
+{
 	struct eb_vma *ev;
-	unsigned int i, pass;
+	unsigned int pass;
 	int err = 0;
+	bool unpinned;
 
 	/*
 	 * Attempt to pin all of the buffers into the GTT.
-	 * This is done in 3 phases:
+	 * This is done in 2 phases:
 	 *
-	 * 1a. Unbind all objects that do not match the GTT constraints for
-	 *     the execbuffer (fenceable, mappable, alignment etc).
-	 * 1b. Increment pin count for already bound objects.
-	 * 2.  Bind new objects.
-	 * 3.  Decrement pin count.
+	 * 1. Unbind all objects that do not match the GTT constraints for
+	 *    the execbuffer (fenceable, mappable, alignment etc).
+	 * 2. Bind new objects.
 	 *
 	 * This avoid unnecessary unbinding of later objects in order to make
 	 * room for the earlier objects *unless* we need to defragment.
+	 *
+	 * Defragmenting is skipped if all objects are pinned at a fixed location.
 	 */
-	pass = 0;
-	do {
-		list_for_each_entry(ev, &eb->unbound, bind_link) {
-			err = eb_reserve_vma(eb, ev, pin_flags);
-			if (err)
-				break;
-		}
-		if (err != -ENOSPC)
-			return err;
+	for (pass = 0; pass <= 2; pass++) {
+		int pin_flags = PIN_USER | PIN_VALIDATE;
 
-		/* Resort *all* the objects into priority order */
-		INIT_LIST_HEAD(&eb->unbound);
-		INIT_LIST_HEAD(&last);
-		for (i = 0; i < count; i++) {
-			unsigned int flags;
+		if (pass == 0)
+			pin_flags |= PIN_NONBLOCK;
 
-			ev = &eb->vma[i];
-			flags = ev->flags;
-			if (flags & EXEC_OBJECT_PINNED &&
-			    flags & __EXEC_OBJECT_HAS_PIN)
-				continue;
+		if (pass >= 1)
+			unpinned = eb_unbind(eb);
 
-			eb_unreserve_vma(ev);
-
-			if (flags & EXEC_OBJECT_PINNED)
-				/* Pinned must have their slot */
-				list_add(&ev->bind_link, &eb->unbound);
-			else if (flags & __EXEC_OBJECT_NEEDS_MAP)
-				/* Map require the lowest 256MiB (aperture) */
-				list_add_tail(&ev->bind_link, &eb->unbound);
-			else if (!(flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS))
-				/* Prioritise 4GiB region for restricted bo */
-				list_add(&ev->bind_link, &last);
-			else
-				list_add_tail(&ev->bind_link, &last);
-		}
-		list_splice_tail(&last, &eb->unbound);
-
-		switch (pass++) {
-		case 0:
-			break;
+		if (pass == 2) {
+			/* No point in defragmenting gtt if all is pinned */
+			if (!unpinned)
+				return -ENOSPC;
 
-		case 1:
-			/* Too fragmented, unbind everything and retry */
-			mutex_lock(&eb->context->vm->mutex);
-			err = i915_gem_evict_vm(eb->context->vm, &eb->ww);
-			mutex_unlock(&eb->context->vm->mutex);
+			err = eb_evict_vm(eb);
 			if (err)
 				return err;
-			break;
+		}
 
-		default:
-			return -ENOSPC;
+		list_for_each_entry(ev, &eb->unbound, bind_link) {
+			err = eb_reserve_vma(eb, ev, pin_flags);
+			if (err)
+				break;
 		}
 
-		pin_flags = PIN_USER;
-	} while (1);
+		if (err != -ENOSPC)
+			break;
+	}
+
+	return err;
 }
 
 static int eb_select_context(struct i915_execbuffer *eb)
@@ -1184,10 +1220,11 @@ static void *reloc_kmap(struct drm_i915_gem_object *obj,
 	return vaddr;
 }
 
-static void *reloc_iomap(struct drm_i915_gem_object *obj,
+static void *reloc_iomap(struct i915_vma *batch,
 			 struct i915_execbuffer *eb,
 			 unsigned long page)
 {
+	struct drm_i915_gem_object *obj = batch->obj;
 	struct reloc_cache *cache = &eb->reloc_cache;
 	struct i915_ggtt *ggtt = cache_to_ggtt(cache);
 	unsigned long offset;
@@ -1197,7 +1234,7 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
 		intel_gt_flush_ggtt_writes(ggtt->vm.gt);
 		io_mapping_unmap_atomic((void __force __iomem *) unmask_page(cache->vaddr));
 	} else {
-		struct i915_vma *vma;
+		struct i915_vma *vma = ERR_PTR(-ENODEV);
 		int err;
 
 		if (i915_gem_object_is_tiled(obj))
@@ -1210,10 +1247,23 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
 		if (err)
 			return ERR_PTR(err);
 
-		vma = i915_gem_object_ggtt_pin_ww(obj, &eb->ww, NULL, 0, 0,
-						  PIN_MAPPABLE |
-						  PIN_NONBLOCK /* NOWARN */ |
-						  PIN_NOEVICT);
+		/*
+		 * i915_gem_object_ggtt_pin_ww may attempt to remove the batch
+		 * VMA from the object list because we no longer pin.
+		 *
+		 * Only attempt to pin the batch buffer to ggtt if the current batch
+		 * is not inside ggtt, or the batch buffer is not misplaced.
+		 */
+		if (!i915_is_ggtt(batch->vm)) {
+			vma = i915_gem_object_ggtt_pin_ww(obj, &eb->ww, NULL, 0, 0,
+							  PIN_MAPPABLE |
+							  PIN_NONBLOCK /* NOWARN */ |
+							  PIN_NOEVICT);
+		} else if (i915_vma_is_map_and_fenceable(batch)) {
+			__i915_vma_pin(batch);
+			vma = batch;
+		}
+
 		if (vma == ERR_PTR(-EDEADLK))
 			return vma;
 
@@ -1251,7 +1301,7 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
 	return vaddr;
 }
 
-static void *reloc_vaddr(struct drm_i915_gem_object *obj,
+static void *reloc_vaddr(struct i915_vma *vma,
 			 struct i915_execbuffer *eb,
 			 unsigned long page)
 {
@@ -1263,9 +1313,9 @@ static void *reloc_vaddr(struct drm_i915_gem_object *obj,
 	} else {
 		vaddr = NULL;
 		if ((cache->vaddr & KMAP) == 0)
-			vaddr = reloc_iomap(obj, eb, page);
+			vaddr = reloc_iomap(vma, eb, page);
 		if (!vaddr)
-			vaddr = reloc_kmap(obj, cache, page);
+			vaddr = reloc_kmap(vma->obj, cache, page);
 	}
 
 	return vaddr;
@@ -1306,7 +1356,7 @@ relocate_entry(struct i915_vma *vma,
 	void *vaddr;
 
 repeat:
-	vaddr = reloc_vaddr(vma->obj, eb,
+	vaddr = reloc_vaddr(vma, eb,
 			    offset >> PAGE_SHIFT);
 	if (IS_ERR(vaddr))
 		return PTR_ERR(vaddr);
@@ -2074,7 +2124,7 @@ shadow_batch_pin(struct i915_execbuffer *eb,
 	if (IS_ERR(vma))
 		return vma;
 
-	err = i915_vma_pin_ww(vma, &eb->ww, 0, 0, flags);
+	err = i915_vma_pin_ww(vma, &eb->ww, 0, 0, flags | PIN_VALIDATE);
 	if (err)
 		return ERR_PTR(err);
 
@@ -2088,7 +2138,7 @@ static struct i915_vma *eb_dispatch_secure(struct i915_execbuffer *eb, struct i9
 	 * batch" bit. Hence we need to pin secure batches into the global gtt.
 	 * hsw should have this fixed, but bdw mucks it up again. */
 	if (eb->batch_flags & I915_DISPATCH_SECURE)
-		return i915_gem_object_ggtt_pin_ww(vma->obj, &eb->ww, NULL, 0, 0, 0);
+		return i915_gem_object_ggtt_pin_ww(vma->obj, &eb->ww, NULL, 0, 0, PIN_VALIDATE);
 
 	return NULL;
 }
@@ -2139,13 +2189,12 @@ static int eb_parse(struct i915_execbuffer *eb)
 
 	err = i915_gem_object_lock(pool->obj, &eb->ww);
 	if (err)
-		goto err;
+		return err;
 
 	shadow = shadow_batch_pin(eb, pool->obj, eb->context->vm, PIN_USER);
-	if (IS_ERR(shadow)) {
-		err = PTR_ERR(shadow);
-		goto err;
-	}
+	if (IS_ERR(shadow))
+		return PTR_ERR(shadow);
+
 	intel_gt_buffer_pool_mark_used(pool);
 	i915_gem_object_set_readonly(shadow->obj);
 	shadow->private = pool;
@@ -2157,25 +2206,21 @@ static int eb_parse(struct i915_execbuffer *eb)
 		shadow = shadow_batch_pin(eb, pool->obj,
 					  &eb->gt->ggtt->vm,
 					  PIN_GLOBAL);
-		if (IS_ERR(shadow)) {
-			err = PTR_ERR(shadow);
-			shadow = trampoline;
-			goto err_shadow;
-		}
+		if (IS_ERR(shadow))
+			return PTR_ERR(shadow);
+
 		shadow->private = pool;
 
 		eb->batch_flags |= I915_DISPATCH_SECURE;
 	}
 
 	batch = eb_dispatch_secure(eb, shadow);
-	if (IS_ERR(batch)) {
-		err = PTR_ERR(batch);
-		goto err_trampoline;
-	}
+	if (IS_ERR(batch))
+		return PTR_ERR(batch);
 
 	err = dma_resv_reserve_shared(shadow->obj->base.resv, 1);
 	if (err)
-		goto err_trampoline;
+		return err;
 
 	err = intel_engine_cmd_parser(eb->context->engine,
 				      eb->batches[0]->vma,
@@ -2183,7 +2228,7 @@ static int eb_parse(struct i915_execbuffer *eb)
 				      eb->batch_len[0],
 				      shadow, trampoline);
 	if (err)
-		goto err_unpin_batch;
+		return err;
 
 	eb->batches[0] = &eb->vma[eb->buffer_count++];
 	eb->batches[0]->vma = i915_vma_get(shadow);
@@ -2202,17 +2247,6 @@ static int eb_parse(struct i915_execbuffer *eb)
 		eb->batches[0]->vma = i915_vma_get(batch);
 	}
 	return 0;
-
-err_unpin_batch:
-	if (batch)
-		i915_vma_unpin(batch);
-err_trampoline:
-	if (trampoline)
-		i915_vma_unpin(trampoline);
-err_shadow:
-	i915_vma_unpin(shadow);
-err:
-	return err;
 }
 
 static int eb_request_submit(struct i915_execbuffer *eb,
@@ -3337,8 +3371,6 @@ i915_gem_do_execbuffer(struct drm_device *dev,
 
 err_vma:
 	eb_release_vmas(&eb, true);
-	if (eb.trampoline)
-		i915_vma_unpin(eb.trampoline);
 	WARN_ON(err == -EDEADLK);
 	i915_gem_ww_ctx_fini(&eb.ww);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index e4938aba3fe9..8c2f57eb5dda 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -44,6 +44,7 @@ int i915_gem_gtt_insert(struct i915_address_space *vm,
 #define PIN_HIGH		BIT_ULL(5)
 #define PIN_OFFSET_BIAS		BIT_ULL(6)
 #define PIN_OFFSET_FIXED	BIT_ULL(7)
+#define PIN_VALIDATE		BIT_ULL(8) /* validate placement only, no need to call unpin() */
 
 #define PIN_GLOBAL		BIT_ULL(10) /* I915_VMA_GLOBAL_BIND */
 #define PIN_USER		BIT_ULL(11) /* I915_VMA_LOCAL_BIND */
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 65168db534f0..0706731b211d 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -751,6 +751,15 @@ static bool try_qad_pin(struct i915_vma *vma, unsigned int flags)
 	unsigned int bound;
 
 	bound = atomic_read(&vma->flags);
+
+	if (flags & PIN_VALIDATE) {
+		flags &= I915_VMA_BIND_MASK;
+
+		return (flags & bound) == flags;
+	}
+
+	/* with the lock mandatory for unbind, we don't race here */
+	flags &= I915_VMA_BIND_MASK;
 	do {
 		if (unlikely(flags & ~bound))
 			return false;
@@ -1176,7 +1185,7 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 	GEM_BUG_ON(!(flags & (PIN_USER | PIN_GLOBAL)));
 
 	/* First try and grab the pin without rebinding the vma */
-	if (try_qad_pin(vma, flags & I915_VMA_BIND_MASK))
+	if (try_qad_pin(vma, flags))
 		return 0;
 
 	err = i915_vma_get_pages(vma);
@@ -1255,7 +1264,8 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 	}
 
 	if (unlikely(!(flags & ~bound & I915_VMA_BIND_MASK))) {
-		__i915_vma_pin(vma);
+		if (!(flags & PIN_VALIDATE))
+			__i915_vma_pin(vma);
 		goto err_unlock;
 	}
 
@@ -1284,8 +1294,10 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 	atomic_add(I915_VMA_PAGES_ACTIVE, &vma->pages_count);
 	list_move_tail(&vma->vm_link, &vma->vm->bound_list);
 
-	__i915_vma_pin(vma);
-	GEM_BUG_ON(!i915_vma_is_pinned(vma));
+	if (!(flags & PIN_VALIDATE)) {
+		__i915_vma_pin(vma);
+		GEM_BUG_ON(!i915_vma_is_pinned(vma));
+	}
 	GEM_BUG_ON(!i915_vma_is_bound(vma, flags));
 	GEM_BUG_ON(i915_vma_misplaced(vma, size, alignment, flags));
 
@@ -1538,8 +1550,6 @@ static int __i915_vma_move_to_active(struct i915_vma *vma, struct i915_request *
 {
 	int err;
 
-	GEM_BUG_ON(!i915_vma_is_pinned(vma));
-
 	/* Wait for the vma to be bound before we start! */
 	err = __i915_request_await_bind(rq, vma);
 	if (err)
@@ -1558,6 +1568,8 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
 
 	assert_object_held(obj);
 
+	GEM_BUG_ON(!vma->pages);
+
 	err = __i915_vma_move_to_active(vma, rq);
 	if (unlikely(err))
 		return err;
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* [Intel-gfx] [PATCH 28/28] drm/i915: Remove short-term pins from execbuf, v4.
@ 2021-10-21 10:36   ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 10:36 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Maarten Lankhorst

Add a flag PIN_VALIDATE, to indicate we don't need to pin and only
protected by the object lock.

This removes the need to unpin, which is done by just releasing the
lock.

eb_reserve is slightly reworked for readability, but the same steps
are still done:
- First pass pins with NONBLOCK.
- Second pass unbinds all objects first, then pins.
- Third pass is only called when not all objects are softpinned, and
  unbinds all objects, then calls i915_gem_evict_vm(), then pins.

When evicting the entire vm in eb_reserve() we do temporarily pin objects
that are marked with EXEC_OBJECT_PINNED. This is because they are already
at their destination, and i915_gem_evict_vm() would otherwise unbind them.

However, we reduce the visibility of those pins by limiting the pin
to our call to i915_gem_evict_vm() only, and pin with vm->mutex held,
instead of the entire duration of the execbuf.

Not sure the latter matters, one can hope..
In theory we could kill the pinning by adding an extra flag to the vma
to temporarily prevent unbinding for gtt for i915_gem_evict_vm only, but
I think that might be overkill. We're still holding the object lock, and
we don't have blocking eviction yet. It's likely sufficient to simply
enforce EXEC_OBJECT_PINNED for all objects on >= gen12.

Changes since v1:
- Split out eb_reserve() into separate functions for readability.
Changes since v2:
- Make batch buffer mappable on platforms where only GGTT is available,
  to prevent moving the batch buffer during relocations.
Changes since v3:
- Preserve current behavior for batch buffer, instead be cautious when
  calling i915_gem_object_ggtt_pin_ww, and re-use the current batch vma
  if it's inside ggtt and map-and-fenceable.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 252 ++++++++++--------
 drivers/gpu/drm/i915/i915_gem_gtt.h           |   1 +
 drivers/gpu/drm/i915/i915_vma.c               |  24 +-
 3 files changed, 161 insertions(+), 116 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index bbf2a10738f7..19f91143cfcf 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -439,7 +439,7 @@ eb_pin_vma(struct i915_execbuffer *eb,
 	else
 		pin_flags = entry->offset & PIN_OFFSET_MASK;
 
-	pin_flags |= PIN_USER | PIN_NOEVICT | PIN_OFFSET_FIXED;
+	pin_flags |= PIN_USER | PIN_NOEVICT | PIN_OFFSET_FIXED | PIN_VALIDATE;
 	if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_GTT))
 		pin_flags |= PIN_GLOBAL;
 
@@ -457,17 +457,15 @@ eb_pin_vma(struct i915_execbuffer *eb,
 					     entry->pad_to_size,
 					     entry->alignment,
 					     eb_pin_flags(entry, ev->flags) |
-					     PIN_USER | PIN_NOEVICT);
+					     PIN_USER | PIN_NOEVICT | PIN_VALIDATE);
 		if (unlikely(err))
 			return err;
 	}
 
 	if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_FENCE)) {
 		err = i915_vma_pin_fence(vma);
-		if (unlikely(err)) {
-			i915_vma_unpin(vma);
+		if (unlikely(err))
 			return err;
-		}
 
 		if (vma->fence)
 			ev->flags |= __EXEC_OBJECT_HAS_FENCE;
@@ -483,13 +481,9 @@ eb_pin_vma(struct i915_execbuffer *eb,
 static inline void
 eb_unreserve_vma(struct eb_vma *ev)
 {
-	if (!(ev->flags & __EXEC_OBJECT_HAS_PIN))
-		return;
-
 	if (unlikely(ev->flags & __EXEC_OBJECT_HAS_FENCE))
 		__i915_vma_unpin_fence(ev->vma);
 
-	__i915_vma_unpin(ev->vma);
 	ev->flags &= ~__EXEC_OBJECT_RESERVED;
 }
 
@@ -682,10 +676,8 @@ static int eb_reserve_vma(struct i915_execbuffer *eb,
 
 	if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_FENCE)) {
 		err = i915_vma_pin_fence(vma);
-		if (unlikely(err)) {
-			i915_vma_unpin(vma);
+		if (unlikely(err))
 			return err;
-		}
 
 		if (vma->fence)
 			ev->flags |= __EXEC_OBJECT_HAS_FENCE;
@@ -697,85 +689,129 @@ static int eb_reserve_vma(struct i915_execbuffer *eb,
 	return 0;
 }
 
-static int eb_reserve(struct i915_execbuffer *eb)
+static int eb_evict_vm(struct i915_execbuffer *eb)
+{
+	const unsigned int count = eb->buffer_count;
+	unsigned int i;
+	int err;
+
+	err = mutex_lock_interruptible(&eb->context->vm->mutex);
+	if (err)
+		return err;
+
+	/* pin to protect against i915_gem_evict_vm evicting below */
+	for (i = 0; i < count; i++) {
+		struct eb_vma *ev = &eb->vma[i];
+
+		if (ev->flags & __EXEC_OBJECT_HAS_PIN)
+			__i915_vma_pin(ev->vma);
+	}
+
+	/* Too fragmented, unbind everything and retry */
+	err = i915_gem_evict_vm(eb->context->vm, &eb->ww);
+
+	/* unpin objects.. */
+	for (i = 0; i < count; i++) {
+		struct eb_vma *ev = &eb->vma[i];
+
+		if (ev->flags & __EXEC_OBJECT_HAS_PIN)
+			i915_vma_unpin(ev->vma);
+	}
+
+	mutex_unlock(&eb->context->vm->mutex);
+
+	return err;
+}
+
+static bool eb_unbind(struct i915_execbuffer *eb)
 {
 	const unsigned int count = eb->buffer_count;
-	unsigned int pin_flags = PIN_USER | PIN_NONBLOCK;
+	unsigned int i;
 	struct list_head last;
+	bool unpinned = false;
+
+	/* Resort *all* the objects into priority order */
+	INIT_LIST_HEAD(&eb->unbound);
+	INIT_LIST_HEAD(&last);
+
+	for (i = 0; i < count; i++) {
+		struct eb_vma *ev = &eb->vma[i];
+		unsigned int flags = ev->flags;
+
+		if (flags & EXEC_OBJECT_PINNED &&
+		    flags & __EXEC_OBJECT_HAS_PIN)
+			continue;
+
+		unpinned = true;
+		eb_unreserve_vma(ev);
+
+		if (flags & EXEC_OBJECT_PINNED)
+			/* Pinned must have their slot */
+			list_add(&ev->bind_link, &eb->unbound);
+		else if (flags & __EXEC_OBJECT_NEEDS_MAP)
+			/* Map require the lowest 256MiB (aperture) */
+			list_add_tail(&ev->bind_link, &eb->unbound);
+		else if (!(flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS))
+			/* Prioritise 4GiB region for restricted bo */
+			list_add(&ev->bind_link, &last);
+		else
+			list_add_tail(&ev->bind_link, &last);
+	}
+
+	list_splice_tail(&last, &eb->unbound);
+	return unpinned;
+}
+
+static int eb_reserve(struct i915_execbuffer *eb)
+{
 	struct eb_vma *ev;
-	unsigned int i, pass;
+	unsigned int pass;
 	int err = 0;
+	bool unpinned;
 
 	/*
 	 * Attempt to pin all of the buffers into the GTT.
-	 * This is done in 3 phases:
+	 * This is done in 2 phases:
 	 *
-	 * 1a. Unbind all objects that do not match the GTT constraints for
-	 *     the execbuffer (fenceable, mappable, alignment etc).
-	 * 1b. Increment pin count for already bound objects.
-	 * 2.  Bind new objects.
-	 * 3.  Decrement pin count.
+	 * 1. Unbind all objects that do not match the GTT constraints for
+	 *    the execbuffer (fenceable, mappable, alignment etc).
+	 * 2. Bind new objects.
 	 *
 	 * This avoid unnecessary unbinding of later objects in order to make
 	 * room for the earlier objects *unless* we need to defragment.
+	 *
+	 * Defragmenting is skipped if all objects are pinned at a fixed location.
 	 */
-	pass = 0;
-	do {
-		list_for_each_entry(ev, &eb->unbound, bind_link) {
-			err = eb_reserve_vma(eb, ev, pin_flags);
-			if (err)
-				break;
-		}
-		if (err != -ENOSPC)
-			return err;
+	for (pass = 0; pass <= 2; pass++) {
+		int pin_flags = PIN_USER | PIN_VALIDATE;
 
-		/* Resort *all* the objects into priority order */
-		INIT_LIST_HEAD(&eb->unbound);
-		INIT_LIST_HEAD(&last);
-		for (i = 0; i < count; i++) {
-			unsigned int flags;
+		if (pass == 0)
+			pin_flags |= PIN_NONBLOCK;
 
-			ev = &eb->vma[i];
-			flags = ev->flags;
-			if (flags & EXEC_OBJECT_PINNED &&
-			    flags & __EXEC_OBJECT_HAS_PIN)
-				continue;
+		if (pass >= 1)
+			unpinned = eb_unbind(eb);
 
-			eb_unreserve_vma(ev);
-
-			if (flags & EXEC_OBJECT_PINNED)
-				/* Pinned must have their slot */
-				list_add(&ev->bind_link, &eb->unbound);
-			else if (flags & __EXEC_OBJECT_NEEDS_MAP)
-				/* Map require the lowest 256MiB (aperture) */
-				list_add_tail(&ev->bind_link, &eb->unbound);
-			else if (!(flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS))
-				/* Prioritise 4GiB region for restricted bo */
-				list_add(&ev->bind_link, &last);
-			else
-				list_add_tail(&ev->bind_link, &last);
-		}
-		list_splice_tail(&last, &eb->unbound);
-
-		switch (pass++) {
-		case 0:
-			break;
+		if (pass == 2) {
+			/* No point in defragmenting gtt if all is pinned */
+			if (!unpinned)
+				return -ENOSPC;
 
-		case 1:
-			/* Too fragmented, unbind everything and retry */
-			mutex_lock(&eb->context->vm->mutex);
-			err = i915_gem_evict_vm(eb->context->vm, &eb->ww);
-			mutex_unlock(&eb->context->vm->mutex);
+			err = eb_evict_vm(eb);
 			if (err)
 				return err;
-			break;
+		}
 
-		default:
-			return -ENOSPC;
+		list_for_each_entry(ev, &eb->unbound, bind_link) {
+			err = eb_reserve_vma(eb, ev, pin_flags);
+			if (err)
+				break;
 		}
 
-		pin_flags = PIN_USER;
-	} while (1);
+		if (err != -ENOSPC)
+			break;
+	}
+
+	return err;
 }
 
 static int eb_select_context(struct i915_execbuffer *eb)
@@ -1184,10 +1220,11 @@ static void *reloc_kmap(struct drm_i915_gem_object *obj,
 	return vaddr;
 }
 
-static void *reloc_iomap(struct drm_i915_gem_object *obj,
+static void *reloc_iomap(struct i915_vma *batch,
 			 struct i915_execbuffer *eb,
 			 unsigned long page)
 {
+	struct drm_i915_gem_object *obj = batch->obj;
 	struct reloc_cache *cache = &eb->reloc_cache;
 	struct i915_ggtt *ggtt = cache_to_ggtt(cache);
 	unsigned long offset;
@@ -1197,7 +1234,7 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
 		intel_gt_flush_ggtt_writes(ggtt->vm.gt);
 		io_mapping_unmap_atomic((void __force __iomem *) unmask_page(cache->vaddr));
 	} else {
-		struct i915_vma *vma;
+		struct i915_vma *vma = ERR_PTR(-ENODEV);
 		int err;
 
 		if (i915_gem_object_is_tiled(obj))
@@ -1210,10 +1247,23 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
 		if (err)
 			return ERR_PTR(err);
 
-		vma = i915_gem_object_ggtt_pin_ww(obj, &eb->ww, NULL, 0, 0,
-						  PIN_MAPPABLE |
-						  PIN_NONBLOCK /* NOWARN */ |
-						  PIN_NOEVICT);
+		/*
+		 * i915_gem_object_ggtt_pin_ww may attempt to remove the batch
+		 * VMA from the object list because we no longer pin.
+		 *
+		 * Only attempt to pin the batch buffer to ggtt if the current batch
+		 * is not inside ggtt, or the batch buffer is not misplaced.
+		 */
+		if (!i915_is_ggtt(batch->vm)) {
+			vma = i915_gem_object_ggtt_pin_ww(obj, &eb->ww, NULL, 0, 0,
+							  PIN_MAPPABLE |
+							  PIN_NONBLOCK /* NOWARN */ |
+							  PIN_NOEVICT);
+		} else if (i915_vma_is_map_and_fenceable(batch)) {
+			__i915_vma_pin(batch);
+			vma = batch;
+		}
+
 		if (vma == ERR_PTR(-EDEADLK))
 			return vma;
 
@@ -1251,7 +1301,7 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
 	return vaddr;
 }
 
-static void *reloc_vaddr(struct drm_i915_gem_object *obj,
+static void *reloc_vaddr(struct i915_vma *vma,
 			 struct i915_execbuffer *eb,
 			 unsigned long page)
 {
@@ -1263,9 +1313,9 @@ static void *reloc_vaddr(struct drm_i915_gem_object *obj,
 	} else {
 		vaddr = NULL;
 		if ((cache->vaddr & KMAP) == 0)
-			vaddr = reloc_iomap(obj, eb, page);
+			vaddr = reloc_iomap(vma, eb, page);
 		if (!vaddr)
-			vaddr = reloc_kmap(obj, cache, page);
+			vaddr = reloc_kmap(vma->obj, cache, page);
 	}
 
 	return vaddr;
@@ -1306,7 +1356,7 @@ relocate_entry(struct i915_vma *vma,
 	void *vaddr;
 
 repeat:
-	vaddr = reloc_vaddr(vma->obj, eb,
+	vaddr = reloc_vaddr(vma, eb,
 			    offset >> PAGE_SHIFT);
 	if (IS_ERR(vaddr))
 		return PTR_ERR(vaddr);
@@ -2074,7 +2124,7 @@ shadow_batch_pin(struct i915_execbuffer *eb,
 	if (IS_ERR(vma))
 		return vma;
 
-	err = i915_vma_pin_ww(vma, &eb->ww, 0, 0, flags);
+	err = i915_vma_pin_ww(vma, &eb->ww, 0, 0, flags | PIN_VALIDATE);
 	if (err)
 		return ERR_PTR(err);
 
@@ -2088,7 +2138,7 @@ static struct i915_vma *eb_dispatch_secure(struct i915_execbuffer *eb, struct i9
 	 * batch" bit. Hence we need to pin secure batches into the global gtt.
 	 * hsw should have this fixed, but bdw mucks it up again. */
 	if (eb->batch_flags & I915_DISPATCH_SECURE)
-		return i915_gem_object_ggtt_pin_ww(vma->obj, &eb->ww, NULL, 0, 0, 0);
+		return i915_gem_object_ggtt_pin_ww(vma->obj, &eb->ww, NULL, 0, 0, PIN_VALIDATE);
 
 	return NULL;
 }
@@ -2139,13 +2189,12 @@ static int eb_parse(struct i915_execbuffer *eb)
 
 	err = i915_gem_object_lock(pool->obj, &eb->ww);
 	if (err)
-		goto err;
+		return err;
 
 	shadow = shadow_batch_pin(eb, pool->obj, eb->context->vm, PIN_USER);
-	if (IS_ERR(shadow)) {
-		err = PTR_ERR(shadow);
-		goto err;
-	}
+	if (IS_ERR(shadow))
+		return PTR_ERR(shadow);
+
 	intel_gt_buffer_pool_mark_used(pool);
 	i915_gem_object_set_readonly(shadow->obj);
 	shadow->private = pool;
@@ -2157,25 +2206,21 @@ static int eb_parse(struct i915_execbuffer *eb)
 		shadow = shadow_batch_pin(eb, pool->obj,
 					  &eb->gt->ggtt->vm,
 					  PIN_GLOBAL);
-		if (IS_ERR(shadow)) {
-			err = PTR_ERR(shadow);
-			shadow = trampoline;
-			goto err_shadow;
-		}
+		if (IS_ERR(shadow))
+			return PTR_ERR(shadow);
+
 		shadow->private = pool;
 
 		eb->batch_flags |= I915_DISPATCH_SECURE;
 	}
 
 	batch = eb_dispatch_secure(eb, shadow);
-	if (IS_ERR(batch)) {
-		err = PTR_ERR(batch);
-		goto err_trampoline;
-	}
+	if (IS_ERR(batch))
+		return PTR_ERR(batch);
 
 	err = dma_resv_reserve_shared(shadow->obj->base.resv, 1);
 	if (err)
-		goto err_trampoline;
+		return err;
 
 	err = intel_engine_cmd_parser(eb->context->engine,
 				      eb->batches[0]->vma,
@@ -2183,7 +2228,7 @@ static int eb_parse(struct i915_execbuffer *eb)
 				      eb->batch_len[0],
 				      shadow, trampoline);
 	if (err)
-		goto err_unpin_batch;
+		return err;
 
 	eb->batches[0] = &eb->vma[eb->buffer_count++];
 	eb->batches[0]->vma = i915_vma_get(shadow);
@@ -2202,17 +2247,6 @@ static int eb_parse(struct i915_execbuffer *eb)
 		eb->batches[0]->vma = i915_vma_get(batch);
 	}
 	return 0;
-
-err_unpin_batch:
-	if (batch)
-		i915_vma_unpin(batch);
-err_trampoline:
-	if (trampoline)
-		i915_vma_unpin(trampoline);
-err_shadow:
-	i915_vma_unpin(shadow);
-err:
-	return err;
 }
 
 static int eb_request_submit(struct i915_execbuffer *eb,
@@ -3337,8 +3371,6 @@ i915_gem_do_execbuffer(struct drm_device *dev,
 
 err_vma:
 	eb_release_vmas(&eb, true);
-	if (eb.trampoline)
-		i915_vma_unpin(eb.trampoline);
 	WARN_ON(err == -EDEADLK);
 	i915_gem_ww_ctx_fini(&eb.ww);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index e4938aba3fe9..8c2f57eb5dda 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -44,6 +44,7 @@ int i915_gem_gtt_insert(struct i915_address_space *vm,
 #define PIN_HIGH		BIT_ULL(5)
 #define PIN_OFFSET_BIAS		BIT_ULL(6)
 #define PIN_OFFSET_FIXED	BIT_ULL(7)
+#define PIN_VALIDATE		BIT_ULL(8) /* validate placement only, no need to call unpin() */
 
 #define PIN_GLOBAL		BIT_ULL(10) /* I915_VMA_GLOBAL_BIND */
 #define PIN_USER		BIT_ULL(11) /* I915_VMA_LOCAL_BIND */
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 65168db534f0..0706731b211d 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -751,6 +751,15 @@ static bool try_qad_pin(struct i915_vma *vma, unsigned int flags)
 	unsigned int bound;
 
 	bound = atomic_read(&vma->flags);
+
+	if (flags & PIN_VALIDATE) {
+		flags &= I915_VMA_BIND_MASK;
+
+		return (flags & bound) == flags;
+	}
+
+	/* with the lock mandatory for unbind, we don't race here */
+	flags &= I915_VMA_BIND_MASK;
 	do {
 		if (unlikely(flags & ~bound))
 			return false;
@@ -1176,7 +1185,7 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 	GEM_BUG_ON(!(flags & (PIN_USER | PIN_GLOBAL)));
 
 	/* First try and grab the pin without rebinding the vma */
-	if (try_qad_pin(vma, flags & I915_VMA_BIND_MASK))
+	if (try_qad_pin(vma, flags))
 		return 0;
 
 	err = i915_vma_get_pages(vma);
@@ -1255,7 +1264,8 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 	}
 
 	if (unlikely(!(flags & ~bound & I915_VMA_BIND_MASK))) {
-		__i915_vma_pin(vma);
+		if (!(flags & PIN_VALIDATE))
+			__i915_vma_pin(vma);
 		goto err_unlock;
 	}
 
@@ -1284,8 +1294,10 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 	atomic_add(I915_VMA_PAGES_ACTIVE, &vma->pages_count);
 	list_move_tail(&vma->vm_link, &vma->vm->bound_list);
 
-	__i915_vma_pin(vma);
-	GEM_BUG_ON(!i915_vma_is_pinned(vma));
+	if (!(flags & PIN_VALIDATE)) {
+		__i915_vma_pin(vma);
+		GEM_BUG_ON(!i915_vma_is_pinned(vma));
+	}
 	GEM_BUG_ON(!i915_vma_is_bound(vma, flags));
 	GEM_BUG_ON(i915_vma_misplaced(vma, size, alignment, flags));
 
@@ -1538,8 +1550,6 @@ static int __i915_vma_move_to_active(struct i915_vma *vma, struct i915_request *
 {
 	int err;
 
-	GEM_BUG_ON(!i915_vma_is_pinned(vma));
-
 	/* Wait for the vma to be bound before we start! */
 	err = __i915_request_await_bind(rq, vma);
 	if (err)
@@ -1558,6 +1568,8 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
 
 	assert_object_held(obj);
 
+	GEM_BUG_ON(!vma->pages);
+
 	err = __i915_vma_move_to_active(vma, rq);
 	if (unlikely(err))
 		return err;
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 114+ messages in thread

* Re: [PATCH 02/28] drm/i915: use new iterator in i915_gem_object_wait_reservation
  2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 10:38     ` Christian König
  -1 siblings, 0 replies; 114+ messages in thread
From: Christian König @ 2021-10-21 10:38 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx; +Cc: dri-devel

Am 21.10.21 um 12:35 schrieb Maarten Lankhorst:
> From: Christian König <christian.koenig@amd.com>
>
> Simplifying the code a bit.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>
> [mlankhorst: Handle timeout = 0 correctly, use new i915_request_wait_timeout.]
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

LGTM, do you want to push it or should I pick it up into drm-misc-next?

Christian.

> ---
>   drivers/gpu/drm/i915/gem/i915_gem_wait.c | 65 ++++++++----------------
>   1 file changed, 20 insertions(+), 45 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_wait.c b/drivers/gpu/drm/i915/gem/i915_gem_wait.c
> index f909aaa09d9c..840c13706999 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_wait.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_wait.c
> @@ -25,7 +25,7 @@ i915_gem_object_wait_fence(struct dma_fence *fence,
>   		return timeout;
>   
>   	if (dma_fence_is_i915(fence))
> -		return i915_request_wait(to_request(fence), flags, timeout);
> +		return i915_request_wait_timeout(to_request(fence), flags, timeout);
>   
>   	return dma_fence_wait_timeout(fence,
>   				      flags & I915_WAIT_INTERRUPTIBLE,
> @@ -37,58 +37,29 @@ i915_gem_object_wait_reservation(struct dma_resv *resv,
>   				 unsigned int flags,
>   				 long timeout)
>   {
> -	struct dma_fence *excl;
> -	bool prune_fences = false;
> -
> -	if (flags & I915_WAIT_ALL) {
> -		struct dma_fence **shared;
> -		unsigned int count, i;
> -		int ret;
> -
> -		ret = dma_resv_get_fences(resv, &excl, &count, &shared);
> -		if (ret)
> -			return ret;
> -
> -		for (i = 0; i < count; i++) {
> -			timeout = i915_gem_object_wait_fence(shared[i],
> -							     flags, timeout);
> -			if (timeout < 0)
> -				break;
> -
> -			dma_fence_put(shared[i]);
> -		}
> -
> -		for (; i < count; i++)
> -			dma_fence_put(shared[i]);
> -		kfree(shared);
> +	struct dma_resv_iter cursor;
> +	struct dma_fence *fence;
> +	long ret = timeout ?: 1;
> +
> +	dma_resv_iter_begin(&cursor, resv, flags & I915_WAIT_ALL);
> +	dma_resv_for_each_fence_unlocked(&cursor, fence) {
> +		ret = i915_gem_object_wait_fence(fence, flags, timeout);
> +		if (ret <= 0)
> +			break;
>   
> -		/*
> -		 * If both shared fences and an exclusive fence exist,
> -		 * then by construction the shared fences must be later
> -		 * than the exclusive fence. If we successfully wait for
> -		 * all the shared fences, we know that the exclusive fence
> -		 * must all be signaled. If all the shared fences are
> -		 * signaled, we can prune the array and recover the
> -		 * floating references on the fences/requests.
> -		 */
> -		prune_fences = count && timeout >= 0;
> -	} else {
> -		excl = dma_resv_get_excl_unlocked(resv);
> +		if (timeout)
> +			timeout = ret;
>   	}
> -
> -	if (excl && timeout >= 0)
> -		timeout = i915_gem_object_wait_fence(excl, flags, timeout);
> -
> -	dma_fence_put(excl);
> +	dma_resv_iter_end(&cursor);
>   
>   	/*
>   	 * Opportunistically prune the fences iff we know they have *all* been
>   	 * signaled.
>   	 */
> -	if (prune_fences)
> +	if (timeout > 0)
>   		dma_resv_prune(resv);
>   
> -	return timeout;
> +	return ret;
>   }
>   
>   static void fence_set_priority(struct dma_fence *fence,
> @@ -196,7 +167,11 @@ i915_gem_object_wait(struct drm_i915_gem_object *obj,
>   
>   	timeout = i915_gem_object_wait_reservation(obj->base.resv,
>   						   flags, timeout);
> -	return timeout < 0 ? timeout : 0;
> +
> +	if (timeout < 0)
> +		return timeout;
> +
> +	return !timeout ? -ETIME : 0;
>   }
>   
>   static inline unsigned long nsecs_to_jiffies_timeout(const u64 n)


^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 02/28] drm/i915: use new iterator in i915_gem_object_wait_reservation
@ 2021-10-21 10:38     ` Christian König
  0 siblings, 0 replies; 114+ messages in thread
From: Christian König @ 2021-10-21 10:38 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx; +Cc: dri-devel

Am 21.10.21 um 12:35 schrieb Maarten Lankhorst:
> From: Christian König <christian.koenig@amd.com>
>
> Simplifying the code a bit.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>
> [mlankhorst: Handle timeout = 0 correctly, use new i915_request_wait_timeout.]
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

LGTM, do you want to push it or should I pick it up into drm-misc-next?

Christian.

> ---
>   drivers/gpu/drm/i915/gem/i915_gem_wait.c | 65 ++++++++----------------
>   1 file changed, 20 insertions(+), 45 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_wait.c b/drivers/gpu/drm/i915/gem/i915_gem_wait.c
> index f909aaa09d9c..840c13706999 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_wait.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_wait.c
> @@ -25,7 +25,7 @@ i915_gem_object_wait_fence(struct dma_fence *fence,
>   		return timeout;
>   
>   	if (dma_fence_is_i915(fence))
> -		return i915_request_wait(to_request(fence), flags, timeout);
> +		return i915_request_wait_timeout(to_request(fence), flags, timeout);
>   
>   	return dma_fence_wait_timeout(fence,
>   				      flags & I915_WAIT_INTERRUPTIBLE,
> @@ -37,58 +37,29 @@ i915_gem_object_wait_reservation(struct dma_resv *resv,
>   				 unsigned int flags,
>   				 long timeout)
>   {
> -	struct dma_fence *excl;
> -	bool prune_fences = false;
> -
> -	if (flags & I915_WAIT_ALL) {
> -		struct dma_fence **shared;
> -		unsigned int count, i;
> -		int ret;
> -
> -		ret = dma_resv_get_fences(resv, &excl, &count, &shared);
> -		if (ret)
> -			return ret;
> -
> -		for (i = 0; i < count; i++) {
> -			timeout = i915_gem_object_wait_fence(shared[i],
> -							     flags, timeout);
> -			if (timeout < 0)
> -				break;
> -
> -			dma_fence_put(shared[i]);
> -		}
> -
> -		for (; i < count; i++)
> -			dma_fence_put(shared[i]);
> -		kfree(shared);
> +	struct dma_resv_iter cursor;
> +	struct dma_fence *fence;
> +	long ret = timeout ?: 1;
> +
> +	dma_resv_iter_begin(&cursor, resv, flags & I915_WAIT_ALL);
> +	dma_resv_for_each_fence_unlocked(&cursor, fence) {
> +		ret = i915_gem_object_wait_fence(fence, flags, timeout);
> +		if (ret <= 0)
> +			break;
>   
> -		/*
> -		 * If both shared fences and an exclusive fence exist,
> -		 * then by construction the shared fences must be later
> -		 * than the exclusive fence. If we successfully wait for
> -		 * all the shared fences, we know that the exclusive fence
> -		 * must all be signaled. If all the shared fences are
> -		 * signaled, we can prune the array and recover the
> -		 * floating references on the fences/requests.
> -		 */
> -		prune_fences = count && timeout >= 0;
> -	} else {
> -		excl = dma_resv_get_excl_unlocked(resv);
> +		if (timeout)
> +			timeout = ret;
>   	}
> -
> -	if (excl && timeout >= 0)
> -		timeout = i915_gem_object_wait_fence(excl, flags, timeout);
> -
> -	dma_fence_put(excl);
> +	dma_resv_iter_end(&cursor);
>   
>   	/*
>   	 * Opportunistically prune the fences iff we know they have *all* been
>   	 * signaled.
>   	 */
> -	if (prune_fences)
> +	if (timeout > 0)
>   		dma_resv_prune(resv);
>   
> -	return timeout;
> +	return ret;
>   }
>   
>   static void fence_set_priority(struct dma_fence *fence,
> @@ -196,7 +167,11 @@ i915_gem_object_wait(struct drm_i915_gem_object *obj,
>   
>   	timeout = i915_gem_object_wait_reservation(obj->base.resv,
>   						   flags, timeout);
> -	return timeout < 0 ? timeout : 0;
> +
> +	if (timeout < 0)
> +		return timeout;
> +
> +	return !timeout ? -ETIME : 0;
>   }
>   
>   static inline unsigned long nsecs_to_jiffies_timeout(const u64 n)


^ permalink raw reply	[flat|nested] 114+ messages in thread

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/28] drm/i915: Fix i915_request fence wait semantics
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
                   ` (27 preceding siblings ...)
  (?)
@ 2021-10-21 10:56 ` Patchwork
  -1 siblings, 0 replies; 114+ messages in thread
From: Patchwork @ 2021-10-21 10:56 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: series starting with [01/28] drm/i915: Fix i915_request fence wait semantics
URL   : https://patchwork.freedesktop.org/series/96115/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
ddb763fd10e7 drm/i915: Fix i915_request fence wait semantics
0c036c1715f3 drm/i915: use new iterator in i915_gem_object_wait_reservation
6df3a2f9c58a drm/i915: Remove dma_resv_prune
-:23: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#23: 
deleted file mode 100644

total: 0 errors, 1 warnings, 0 checks, 42 lines checked
1740df189181 drm/i915: Remove unused bits of i915_vma/active api
ec8de168f667 drm/i915: Slightly rework EXEC_OBJECT_CAPTURE handling, v2.
-:73: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#73: FILE: drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c:3134:
+				kvcalloc(eb->capture_count + 1,
+					sizeof(*eb->requests[i]->capture_list),

-:77: CHECK:LINE_SPACING: Please don't use multiple blank lines
#77: FILE: drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c:3138:
+
+

total: 0 errors, 0 warnings, 2 checks, 119 lines checked
ce8a62bcaae3 drm/i915: Remove gen6_ppgtt_unpin_all
e22208d09f16 drm/i915: Create a dummy object for gen6 ppgtt
-:178: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#178: FILE: drivers/gpu/drm/i915/gt/gen6_ppgtt.c:376:
+static void pd_dummy_obj_put_pages(struct drm_i915_gem_object *obj,
+				     struct sg_table *pages)

-:200: WARNING:LONG_LINE: line length of 119 exceeds 100 columns
#200: FILE: drivers/gpu/drm/i915/gt/gen6_ppgtt.c:398:
+	pd->pt.base = __i915_gem_object_create_internal(ppgtt->base.vm.gt->i915, &pd_dummy_obj_ops, I915_PDES * SZ_4K);

total: 0 errors, 1 warnings, 1 checks, 256 lines checked
5fa1e4d967c0 drm/i915: Create a full object for mock_ring, v2.
-:6: WARNING:COMMIT_LOG_LONG_LINE: Possible unwrapped commit description (prefer a maximum 75 chars per line)
#6: 
This allows us to finally get rid of all the assumptions that vma->obj is NULL.

total: 0 errors, 1 warnings, 0 checks, 73 lines checked
c56256b7900b drm/i915: vma is always backed by an object.
3324301339ce drm/i915: Change shrink ordering to use locking around unbinding.
-:28: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#28: FILE: drivers/gpu/drm/i915/gem/i915_gem_shrinker.c:40:
+static int drop_pages(struct drm_i915_gem_object *obj,
+		       unsigned long shrink, bool trylock_vm)

total: 0 errors, 0 warnings, 1 checks, 56 lines checked
5b0d3b29f3ce drm/i915/pm: Move CONTEXT_VALID_BIT check
-:6: WARNING:COMMIT_LOG_LONG_LINE: Possible unwrapped commit description (prefer a maximum 75 chars per line)
#6: 
Resetting will clear the CONTEXT_VALID_BIT, so wait until after that to test.

total: 0 errors, 1 warnings, 0 checks, 17 lines checked
494b7f7d1d07 drm/i915: Remove resv from i915_vma
971bfcf716db drm/i915: Remove pages_mutex and intel_gtt->vma_ops.set/clear_pages members
-:545: CHECK:LINE_SPACING: Please don't use multiple blank lines
#545: FILE: drivers/gpu/drm/i915/i915_vma.c:791:
 
+

total: 0 errors, 0 warnings, 1 checks, 659 lines checked
9ca977d4ea2d drm/i915: Take object lock in i915_ggtt_pin if ww is not set
6af62101e38d drm/i915: Add lock for unbinding to i915_gem_object_ggtt_pin_ww
-:8: WARNING:COMMIT_MESSAGE: Missing commit description - Add an appropriate one

total: 0 errors, 1 warnings, 0 checks, 15 lines checked
1893beb58bd2 drm/i915: Rework context handling in hugepages selftests
12aa1adab3a1 drm/i915: Ensure gem_contexts selftests work with unbind changes.
b30510e7c7a5 drm/i915: Take trylock during eviction, v2.
-:92: CHECK:LINE_SPACING: Please don't use multiple blank lines
#92: FILE: drivers/gpu/drm/i915/i915_gem_evict.c:250:
 
+

total: 0 errors, 0 warnings, 1 checks, 109 lines checked
65bb798433f5 drm/i915: Pass trylock context to callers
-:7: WARNING:COMMIT_MESSAGE: Missing commit description - Add an appropriate one

-:391: CHECK:BRACES: Blank lines aren't necessary after an open brace '{'
#391: FILE: drivers/gpu/drm/i915/i915_vma.c:1373:
 		if (mutex_lock_interruptible(&vm->mutex) == 0) {
+

total: 0 errors, 1 warnings, 1 checks, 446 lines checked
83936045aeae drm/i915: Ensure i915_vma tests do not get -ENOSPC with the locking changes.
9ffbca093c70 drm/i915: Drain the ttm delayed workqueue too
1752c3fdca53 drm/i915: Make i915_gem_evict_vm work correctly for already locked objects
d80031a5a1fa drm/i915: Call i915_gem_evict_vm in vm_fault_gtt to prevent new ENOSPC errors
5845081d8530 drm/i915: Add i915_vma_unbind_unlocked, and take obj lock for i915_vma_unbind
-:7: WARNING:COMMIT_LOG_LONG_LINE: Possible unwrapped commit description (prefer a maximum 75 chars per line)
#7: 
We want to remove more members of i915_vma, which requires the locking to be

total: 0 errors, 1 warnings, 0 checks, 313 lines checked
2608631d4a65 drm/i915: Require object lock when freeing pages during destruction
40aa9c364286 drm/i915: Remove assert_object_held_shared
deb3047c26f8 drm/i915: Remove support for unlocked i915_vma unbind
cb7d236df1b3 drm/i915: Remove short-term pins from execbuf, v4.



^ permalink raw reply	[flat|nested] 114+ messages in thread

* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for series starting with [01/28] drm/i915: Fix i915_request fence wait semantics
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
                   ` (28 preceding siblings ...)
  (?)
@ 2021-10-21 10:57 ` Patchwork
  -1 siblings, 0 replies; 114+ messages in thread
From: Patchwork @ 2021-10-21 10:57 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: series starting with [01/28] drm/i915: Fix i915_request fence wait semantics
URL   : https://patchwork.freedesktop.org/series/96115/
State : warning

== Summary ==

$ dim sparse --fast origin/drm-tip
Sparse version: v0.6.2
Fast mode used, each commit won't be checked separately.
+drivers/gpu/drm/i915/gem/selftests/huge_pages.c:25:25: warning: symbol 'hugepage_ctx' was not declared. Should it be static?



^ permalink raw reply	[flat|nested] 114+ messages in thread

* [Intel-gfx] ✗ Fi.CI.DOCS: warning for series starting with [01/28] drm/i915: Fix i915_request fence wait semantics
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
                   ` (29 preceding siblings ...)
  (?)
@ 2021-10-21 11:01 ` Patchwork
  -1 siblings, 0 replies; 114+ messages in thread
From: Patchwork @ 2021-10-21 11:01 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: series starting with [01/28] drm/i915: Fix i915_request fence wait semantics
URL   : https://patchwork.freedesktop.org/series/96115/
State : warning

== Summary ==

$ make htmldocs 2>&1 > /dev/null | grep i915
./drivers/gpu/drm/i915/i915_gem_evict.c:110: warning: Function parameter or member 'ww' not described in 'i915_gem_evict_something'
./drivers/gpu/drm/i915/i915_gem_evict.c:281: warning: Function parameter or member 'ww' not described in 'i915_gem_evict_for_node'
./drivers/gpu/drm/i915/i915_gem_evict.c:393: warning: Function parameter or member 'ww' not described in 'i915_gem_evict_vm'
./drivers/gpu/drm/i915/i915_gem_gtt.c:100: warning: Function parameter or member 'ww' not described in 'i915_gem_gtt_reserve'
./drivers/gpu/drm/i915/i915_gem_gtt.c:192: warning: Function parameter or member 'ww' not described in 'i915_gem_gtt_insert'



^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [PATCH 02/28] drm/i915: use new iterator in i915_gem_object_wait_reservation
  2021-10-21 10:38     ` [Intel-gfx] " Christian König
@ 2021-10-21 11:06       ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 11:06 UTC (permalink / raw)
  To: Christian König, intel-gfx; +Cc: dri-devel

Op 21-10-2021 om 12:38 schreef Christian König:
> Am 21.10.21 um 12:35 schrieb Maarten Lankhorst:
>> From: Christian König <christian.koenig@amd.com>
>>
>> Simplifying the code a bit.
>>
>> Signed-off-by: Christian König <christian.koenig@amd.com>
>> [mlankhorst: Handle timeout = 0 correctly, use new i915_request_wait_timeout.]
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>
> LGTM, do you want to push it or should I pick it up into drm-misc-next? 

I think it can be applied to drm-intel-gt-next, after a backmerge. It needs patch 1 too, which fixes

i915_request_wait semantics when used in dma-fence. It exports a dma-fence compatible i915_request_wait_timeout function, used in this patch.


^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 02/28] drm/i915: use new iterator in i915_gem_object_wait_reservation
@ 2021-10-21 11:06       ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-21 11:06 UTC (permalink / raw)
  To: Christian König, intel-gfx; +Cc: dri-devel

Op 21-10-2021 om 12:38 schreef Christian König:
> Am 21.10.21 um 12:35 schrieb Maarten Lankhorst:
>> From: Christian König <christian.koenig@amd.com>
>>
>> Simplifying the code a bit.
>>
>> Signed-off-by: Christian König <christian.koenig@amd.com>
>> [mlankhorst: Handle timeout = 0 correctly, use new i915_request_wait_timeout.]
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>
> LGTM, do you want to push it or should I pick it up into drm-misc-next? 

I think it can be applied to drm-intel-gt-next, after a backmerge. It needs patch 1 too, which fixes

i915_request_wait semantics when used in dma-fence. It exports a dma-fence compatible i915_request_wait_timeout function, used in this patch.


^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 02/28] drm/i915: use new iterator in i915_gem_object_wait_reservation
  2021-10-21 11:06       ` [Intel-gfx] " Maarten Lankhorst
  (?)
@ 2021-10-21 11:13       ` Tvrtko Ursulin
  2021-10-28  8:41         ` Christian König
  -1 siblings, 1 reply; 114+ messages in thread
From: Tvrtko Ursulin @ 2021-10-21 11:13 UTC (permalink / raw)
  To: Maarten Lankhorst, Christian König, intel-gfx
  Cc: dri-devel, Daniel Vetter


On 21/10/2021 12:06, Maarten Lankhorst wrote:
> Op 21-10-2021 om 12:38 schreef Christian König:
>> Am 21.10.21 um 12:35 schrieb Maarten Lankhorst:
>>> From: Christian König <christian.koenig@amd.com>
>>>
>>> Simplifying the code a bit.
>>>
>>> Signed-off-by: Christian König <christian.koenig@amd.com>
>>> [mlankhorst: Handle timeout = 0 correctly, use new i915_request_wait_timeout.]
>>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>>
>> LGTM, do you want to push it or should I pick it up into drm-misc-next?
> 
> I think it can be applied to drm-intel-gt-next, after a backmerge. It needs patch 1 too, which fixes
> 
> i915_request_wait semantics when used in dma-fence. It exports a dma-fence compatible i915_request_wait_timeout function, used in this patch.

I don't think my open has been resolved, at least I haven't seen a reply 
from Daniel on the topic of potential for infinite waits with untrusted 
clients after this change. +Daniel

Regards,

Tvrtko

^ permalink raw reply	[flat|nested] 114+ messages in thread

* [Intel-gfx] ✓ Fi.CI.BAT: success for series starting with [01/28] drm/i915: Fix i915_request fence wait semantics
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
                   ` (30 preceding siblings ...)
  (?)
@ 2021-10-21 11:27 ` Patchwork
  -1 siblings, 0 replies; 114+ messages in thread
From: Patchwork @ 2021-10-21 11:27 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

[-- Attachment #1: Type: text/plain, Size: 7713 bytes --]

== Series Details ==

Series: series starting with [01/28] drm/i915: Fix i915_request fence wait semantics
URL   : https://patchwork.freedesktop.org/series/96115/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_10768 -> Patchwork_21402
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/index.html

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_21402:

### IGT changes ###

#### Suppressed ####

  The following results come from untrusted machines, tests, or statuses.
  They do not affect the overall result.

  * igt@kms_frontbuffer_tracking@basic:
    - {fi-hsw-gt1}:       [PASS][1] -> [DMESG-WARN][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/fi-hsw-gt1/igt@kms_frontbuffer_tracking@basic.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/fi-hsw-gt1/igt@kms_frontbuffer_tracking@basic.html

  
Known issues
------------

  Here are the changes found in Patchwork_21402 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_huc_copy@huc-copy:
    - fi-glk-dsi:         NOTRUN -> [SKIP][3] ([fdo#109271] / [i915#2190])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/fi-glk-dsi/igt@gem_huc_copy@huc-copy.html

  * igt@gem_tiled_blits@basic:
    - fi-pnv-d510:        [PASS][4] -> [INCOMPLETE][5] ([i915#299])
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/fi-pnv-d510/igt@gem_tiled_blits@basic.html
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/fi-pnv-d510/igt@gem_tiled_blits@basic.html

  * igt@kms_chamelium@dp-crc-fast:
    - fi-bsw-nick:        NOTRUN -> [SKIP][6] ([fdo#109271] / [fdo#111827]) +8 similar issues
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/fi-bsw-nick/igt@kms_chamelium@dp-crc-fast.html

  * igt@kms_chamelium@hdmi-hpd-fast:
    - fi-glk-dsi:         NOTRUN -> [SKIP][7] ([fdo#109271] / [fdo#111827]) +8 similar issues
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/fi-glk-dsi/igt@kms_chamelium@hdmi-hpd-fast.html

  * igt@kms_frontbuffer_tracking@basic:
    - fi-cfl-8109u:       [PASS][8] -> [FAIL][9] ([i915#2546])
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/fi-cfl-8109u/igt@kms_frontbuffer_tracking@basic.html
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/fi-cfl-8109u/igt@kms_frontbuffer_tracking@basic.html

  * igt@kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-d:
    - fi-glk-dsi:         NOTRUN -> [SKIP][10] ([fdo#109271] / [i915#533])
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/fi-glk-dsi/igt@kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-d.html

  * igt@kms_psr@primary_page_flip:
    - fi-glk-dsi:         NOTRUN -> [SKIP][11] ([fdo#109271]) +30 similar issues
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/fi-glk-dsi/igt@kms_psr@primary_page_flip.html

  * igt@prime_vgem@basic-fence-flip:
    - fi-bsw-nick:        NOTRUN -> [SKIP][12] ([fdo#109271]) +63 similar issues
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/fi-bsw-nick/igt@prime_vgem@basic-fence-flip.html

  * igt@runner@aborted:
    - fi-pnv-d510:        NOTRUN -> [FAIL][13] ([i915#2403] / [i915#4312])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/fi-pnv-d510/igt@runner@aborted.html

  
#### Possible fixes ####

  * igt@i915_selftest@live@hangcheck:
    - {fi-hsw-gt1}:       [DMESG-WARN][14] ([i915#3303]) -> [PASS][15]
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/fi-hsw-gt1/igt@i915_selftest@live@hangcheck.html
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/fi-hsw-gt1/igt@i915_selftest@live@hangcheck.html

  * igt@kms_frontbuffer_tracking@basic:
    - fi-cml-u2:          [DMESG-WARN][16] ([i915#4269]) -> [PASS][17]
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/fi-cml-u2/igt@kms_frontbuffer_tracking@basic.html
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/fi-cml-u2/igt@kms_frontbuffer_tracking@basic.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [i915#2190]: https://gitlab.freedesktop.org/drm/intel/issues/2190
  [i915#2403]: https://gitlab.freedesktop.org/drm/intel/issues/2403
  [i915#2546]: https://gitlab.freedesktop.org/drm/intel/issues/2546
  [i915#299]: https://gitlab.freedesktop.org/drm/intel/issues/299
  [i915#3303]: https://gitlab.freedesktop.org/drm/intel/issues/3303
  [i915#4269]: https://gitlab.freedesktop.org/drm/intel/issues/4269
  [i915#4312]: https://gitlab.freedesktop.org/drm/intel/issues/4312
  [i915#533]: https://gitlab.freedesktop.org/drm/intel/issues/533


Participating hosts (41 -> 35)
------------------------------

  Additional (2): fi-glk-dsi fi-bsw-nick 
  Missing    (8): fi-bdw-5557u bat-dg1-6 bat-dg1-5 fi-hsw-4200u fi-bsw-cyan bat-adlp-4 fi-ctg-p8600 fi-snb-2600 


Build changes
-------------

  * Linux: CI_DRM_10768 -> Patchwork_21402

  CI-20190529: 20190529
  CI_DRM_10768: 0e1c99720e0793390c9758dc1b4eedd7395b1382 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_6258: 4c80c71d7dec29b6376846ae96bd04dc0b6e34d9 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  Patchwork_21402: cb7d236df1b36083cc90723c0699ac14c252adaa @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

cb7d236df1b3 drm/i915: Remove short-term pins from execbuf, v4.
deb3047c26f8 drm/i915: Remove support for unlocked i915_vma unbind
40aa9c364286 drm/i915: Remove assert_object_held_shared
2608631d4a65 drm/i915: Require object lock when freeing pages during destruction
5845081d8530 drm/i915: Add i915_vma_unbind_unlocked, and take obj lock for i915_vma_unbind
d80031a5a1fa drm/i915: Call i915_gem_evict_vm in vm_fault_gtt to prevent new ENOSPC errors
1752c3fdca53 drm/i915: Make i915_gem_evict_vm work correctly for already locked objects
9ffbca093c70 drm/i915: Drain the ttm delayed workqueue too
83936045aeae drm/i915: Ensure i915_vma tests do not get -ENOSPC with the locking changes.
65bb798433f5 drm/i915: Pass trylock context to callers
b30510e7c7a5 drm/i915: Take trylock during eviction, v2.
12aa1adab3a1 drm/i915: Ensure gem_contexts selftests work with unbind changes.
1893beb58bd2 drm/i915: Rework context handling in hugepages selftests
6af62101e38d drm/i915: Add lock for unbinding to i915_gem_object_ggtt_pin_ww
9ca977d4ea2d drm/i915: Take object lock in i915_ggtt_pin if ww is not set
971bfcf716db drm/i915: Remove pages_mutex and intel_gtt->vma_ops.set/clear_pages members
494b7f7d1d07 drm/i915: Remove resv from i915_vma
5b0d3b29f3ce drm/i915/pm: Move CONTEXT_VALID_BIT check
3324301339ce drm/i915: Change shrink ordering to use locking around unbinding.
c56256b7900b drm/i915: vma is always backed by an object.
5fa1e4d967c0 drm/i915: Create a full object for mock_ring, v2.
e22208d09f16 drm/i915: Create a dummy object for gen6 ppgtt
ce8a62bcaae3 drm/i915: Remove gen6_ppgtt_unpin_all
ec8de168f667 drm/i915: Slightly rework EXEC_OBJECT_CAPTURE handling, v2.
1740df189181 drm/i915: Remove unused bits of i915_vma/active api
6df3a2f9c58a drm/i915: Remove dma_resv_prune
0c036c1715f3 drm/i915: use new iterator in i915_gem_object_wait_reservation
ddb763fd10e7 drm/i915: Fix i915_request fence wait semantics

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/index.html

[-- Attachment #2: Type: text/html, Size: 9186 bytes --]

^ permalink raw reply	[flat|nested] 114+ messages in thread

* [Intel-gfx] ✗ Fi.CI.IGT: failure for series starting with [01/28] drm/i915: Fix i915_request fence wait semantics
  2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
                   ` (31 preceding siblings ...)
  (?)
@ 2021-10-21 12:57 ` Patchwork
  2021-10-22 11:24   ` Matthew Auld
  -1 siblings, 1 reply; 114+ messages in thread
From: Patchwork @ 2021-10-21 12:57 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

[-- Attachment #1: Type: text/plain, Size: 30299 bytes --]

== Series Details ==

Series: series starting with [01/28] drm/i915: Fix i915_request fence wait semantics
URL   : https://patchwork.freedesktop.org/series/96115/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_10768_full -> Patchwork_21402_full
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with Patchwork_21402_full absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_21402_full, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_21402_full:

### IGT changes ###

#### Possible regressions ####

  * igt@gem_linear_blits@normal:
    - shard-glk:          [PASS][1] -> [FAIL][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-glk4/igt@gem_linear_blits@normal.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-glk4/igt@gem_linear_blits@normal.html

  * igt@gem_mmap_gtt@cpuset-big-copy-xy:
    - shard-iclb:         NOTRUN -> [INCOMPLETE][3]
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb3/igt@gem_mmap_gtt@cpuset-big-copy-xy.html

  * igt@gem_ppgtt@blt-vs-render-ctxn:
    - shard-tglb:         [PASS][4] -> [FAIL][5] +1 similar issue
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-tglb5/igt@gem_ppgtt@blt-vs-render-ctxn.html
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb8/igt@gem_ppgtt@blt-vs-render-ctxn.html

  
Known issues
------------

  Here are the changes found in Patchwork_21402_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@feature_discovery@display-2x:
    - shard-tglb:         NOTRUN -> [SKIP][6] ([i915#1839])
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb1/igt@feature_discovery@display-2x.html

  * igt@gem_create@create-massive:
    - shard-snb:          NOTRUN -> [DMESG-WARN][7] ([i915#3002])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-snb2/igt@gem_create@create-massive.html

  * igt@gem_ctx_isolation@preservation-s3@rcs0:
    - shard-tglb:         [PASS][8] -> [INCOMPLETE][9] ([i915#1373])
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-tglb8/igt@gem_ctx_isolation@preservation-s3@rcs0.html
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb7/igt@gem_ctx_isolation@preservation-s3@rcs0.html

  * igt@gem_ctx_isolation@preservation-s3@vcs0:
    - shard-kbl:          [PASS][10] -> [DMESG-WARN][11] ([i915#180]) +3 similar issues
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-kbl7/igt@gem_ctx_isolation@preservation-s3@vcs0.html
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@gem_ctx_isolation@preservation-s3@vcs0.html

  * igt@gem_ctx_isolation@preservation-s3@vecs0:
    - shard-skl:          [PASS][12] -> [INCOMPLETE][13] ([i915#198])
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl3/igt@gem_ctx_isolation@preservation-s3@vecs0.html
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl1/igt@gem_ctx_isolation@preservation-s3@vecs0.html

  * igt@gem_ctx_persistence@idempotent:
    - shard-snb:          NOTRUN -> [SKIP][14] ([fdo#109271] / [i915#1099]) +4 similar issues
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-snb2/igt@gem_ctx_persistence@idempotent.html

  * igt@gem_exec_fair@basic-none-solo@rcs0:
    - shard-glk:          [PASS][15] -> [FAIL][16] ([i915#2842])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-glk5/igt@gem_exec_fair@basic-none-solo@rcs0.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-glk7/igt@gem_exec_fair@basic-none-solo@rcs0.html

  * igt@gem_exec_fair@basic-pace@bcs0:
    - shard-tglb:         [PASS][17] -> [FAIL][18] ([i915#2842]) +2 similar issues
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-tglb1/igt@gem_exec_fair@basic-pace@bcs0.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb2/igt@gem_exec_fair@basic-pace@bcs0.html

  * igt@gem_exec_fair@basic-pace@vecs0:
    - shard-kbl:          [PASS][19] -> [FAIL][20] ([i915#2842]) +2 similar issues
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-kbl2/igt@gem_exec_fair@basic-pace@vecs0.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl2/igt@gem_exec_fair@basic-pace@vecs0.html

  * igt@gem_exec_params@no-vebox:
    - shard-tglb:         NOTRUN -> [SKIP][21] ([fdo#109283])
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@gem_exec_params@no-vebox.html

  * igt@gem_pwrite@basic-exhaustion:
    - shard-kbl:          NOTRUN -> [WARN][22] ([i915#2658])
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@gem_pwrite@basic-exhaustion.html

  * igt@gem_pxp@dmabuf-shared-protected-dst-is-context-refcounted:
    - shard-tglb:         NOTRUN -> [SKIP][23] ([i915#4270])
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@gem_pxp@dmabuf-shared-protected-dst-is-context-refcounted.html

  * igt@gem_userptr_blits@readonly-unsync:
    - shard-tglb:         NOTRUN -> [SKIP][24] ([i915#3297])
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@gem_userptr_blits@readonly-unsync.html

  * igt@gen7_exec_parse@basic-rejected:
    - shard-tglb:         NOTRUN -> [SKIP][25] ([fdo#109289]) +2 similar issues
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@gen7_exec_parse@basic-rejected.html

  * igt@gen9_exec_parse@cmd-crossing-page:
    - shard-tglb:         NOTRUN -> [SKIP][26] ([i915#2856]) +2 similar issues
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@gen9_exec_parse@cmd-crossing-page.html

  * igt@i915_pm_dc@dc6-psr:
    - shard-iclb:         [PASS][27] -> [FAIL][28] ([i915#454])
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb1/igt@i915_pm_dc@dc6-psr.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb3/igt@i915_pm_dc@dc6-psr.html

  * igt@i915_pm_lpsp@kms-lpsp@kms-lpsp-dp:
    - shard-kbl:          NOTRUN -> [SKIP][29] ([fdo#109271] / [i915#1937])
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@i915_pm_lpsp@kms-lpsp@kms-lpsp-dp.html

  * igt@i915_pm_rpm@dpms-non-lpsp:
    - shard-tglb:         NOTRUN -> [SKIP][30] ([fdo#111644] / [i915#1397] / [i915#2411])
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@i915_pm_rpm@dpms-non-lpsp.html

  * igt@i915_pm_rpm@gem-execbuf-stress-pc8:
    - shard-tglb:         NOTRUN -> [SKIP][31] ([fdo#109506] / [i915#2411])
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@i915_pm_rpm@gem-execbuf-stress-pc8.html

  * igt@i915_suspend@fence-restore-untiled:
    - shard-apl:          [PASS][32] -> [DMESG-WARN][33] ([i915#180]) +1 similar issue
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-apl8/igt@i915_suspend@fence-restore-untiled.html
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl1/igt@i915_suspend@fence-restore-untiled.html

  * igt@kms_big_fb@linear-16bpp-rotate-90:
    - shard-tglb:         NOTRUN -> [SKIP][34] ([fdo#111614]) +1 similar issue
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@kms_big_fb@linear-16bpp-rotate-90.html

  * igt@kms_big_fb@linear-32bpp-rotate-0:
    - shard-glk:          [PASS][35] -> [DMESG-WARN][36] ([i915#118])
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-glk7/igt@kms_big_fb@linear-32bpp-rotate-0.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-glk5/igt@kms_big_fb@linear-32bpp-rotate-0.html

  * igt@kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-0-hflip:
    - shard-kbl:          NOTRUN -> [SKIP][37] ([fdo#109271] / [i915#3777])
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-0-hflip.html

  * igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-180-hflip:
    - shard-apl:          NOTRUN -> [SKIP][38] ([fdo#109271] / [i915#3777])
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl3/igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-180-hflip.html

  * igt@kms_big_fb@yf-tiled-16bpp-rotate-90:
    - shard-tglb:         NOTRUN -> [SKIP][39] ([fdo#111615]) +2 similar issues
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_big_fb@yf-tiled-16bpp-rotate-90.html

  * igt@kms_big_joiner@invalid-modeset:
    - shard-skl:          NOTRUN -> [SKIP][40] ([fdo#109271]) +19 similar issues
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl7/igt@kms_big_joiner@invalid-modeset.html

  * igt@kms_ccs@pipe-a-bad-rotation-90-y_tiled_gen12_rc_ccs_cc:
    - shard-kbl:          NOTRUN -> [SKIP][41] ([fdo#109271] / [i915#3886]) +1 similar issue
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_ccs@pipe-a-bad-rotation-90-y_tiled_gen12_rc_ccs_cc.html

  * igt@kms_ccs@pipe-a-ccs-on-another-bo-y_tiled_gen12_rc_ccs_cc:
    - shard-apl:          NOTRUN -> [SKIP][42] ([fdo#109271] / [i915#3886]) +4 similar issues
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl7/igt@kms_ccs@pipe-a-ccs-on-another-bo-y_tiled_gen12_rc_ccs_cc.html

  * igt@kms_ccs@pipe-a-missing-ccs-buffer-y_tiled_gen12_rc_ccs_cc:
    - shard-skl:          NOTRUN -> [SKIP][43] ([fdo#109271] / [i915#3886])
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl7/igt@kms_ccs@pipe-a-missing-ccs-buffer-y_tiled_gen12_rc_ccs_cc.html

  * igt@kms_ccs@pipe-b-bad-rotation-90-y_tiled_ccs:
    - shard-tglb:         NOTRUN -> [SKIP][44] ([i915#3689]) +6 similar issues
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_ccs@pipe-b-bad-rotation-90-y_tiled_ccs.html

  * igt@kms_ccs@pipe-c-bad-rotation-90-y_tiled_gen12_mc_ccs:
    - shard-tglb:         NOTRUN -> [SKIP][45] ([i915#3689] / [i915#3886]) +1 similar issue
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_ccs@pipe-c-bad-rotation-90-y_tiled_gen12_mc_ccs.html

  * igt@kms_ccs@pipe-d-missing-ccs-buffer-y_tiled_gen12_rc_ccs:
    - shard-kbl:          NOTRUN -> [SKIP][46] ([fdo#109271]) +33 similar issues
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_ccs@pipe-d-missing-ccs-buffer-y_tiled_gen12_rc_ccs.html

  * igt@kms_chamelium@hdmi-mode-timings:
    - shard-snb:          NOTRUN -> [SKIP][47] ([fdo#109271] / [fdo#111827]) +13 similar issues
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-snb2/igt@kms_chamelium@hdmi-mode-timings.html

  * igt@kms_color@pipe-a-ctm-0-75:
    - shard-skl:          [PASS][48] -> [DMESG-WARN][49] ([i915#1982]) +2 similar issues
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl7/igt@kms_color@pipe-a-ctm-0-75.html
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl10/igt@kms_color@pipe-a-ctm-0-75.html

  * igt@kms_color_chamelium@pipe-a-ctm-green-to-red:
    - shard-skl:          NOTRUN -> [SKIP][50] ([fdo#109271] / [fdo#111827])
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl7/igt@kms_color_chamelium@pipe-a-ctm-green-to-red.html

  * igt@kms_color_chamelium@pipe-b-ctm-limited-range:
    - shard-tglb:         NOTRUN -> [SKIP][51] ([fdo#109284] / [fdo#111827]) +5 similar issues
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_color_chamelium@pipe-b-ctm-limited-range.html

  * igt@kms_color_chamelium@pipe-b-ctm-red-to-blue:
    - shard-apl:          NOTRUN -> [SKIP][52] ([fdo#109271] / [fdo#111827]) +10 similar issues
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl3/igt@kms_color_chamelium@pipe-b-ctm-red-to-blue.html

  * igt@kms_color_chamelium@pipe-c-ctm-red-to-blue:
    - shard-kbl:          NOTRUN -> [SKIP][53] ([fdo#109271] / [fdo#111827]) +1 similar issue
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_color_chamelium@pipe-c-ctm-red-to-blue.html

  * igt@kms_content_protection@atomic:
    - shard-apl:          NOTRUN -> [TIMEOUT][54] ([i915#1319])
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl7/igt@kms_content_protection@atomic.html

  * igt@kms_content_protection@atomic-dpms:
    - shard-kbl:          NOTRUN -> [TIMEOUT][55] ([i915#1319])
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_content_protection@atomic-dpms.html

  * igt@kms_content_protection@dp-mst-type-0:
    - shard-tglb:         NOTRUN -> [SKIP][56] ([i915#3116])
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_content_protection@dp-mst-type-0.html

  * igt@kms_cursor_crc@pipe-b-cursor-max-size-onscreen:
    - shard-tglb:         NOTRUN -> [SKIP][57] ([i915#3359]) +3 similar issues
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@kms_cursor_crc@pipe-b-cursor-max-size-onscreen.html

  * igt@kms_cursor_crc@pipe-d-cursor-512x170-random:
    - shard-tglb:         NOTRUN -> [SKIP][58] ([fdo#109279] / [i915#3359]) +7 similar issues
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_cursor_crc@pipe-d-cursor-512x170-random.html

  * igt@kms_cursor_edge_walk@pipe-d-128x128-right-edge:
    - shard-snb:          NOTRUN -> [SKIP][59] ([fdo#109271]) +281 similar issues
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-snb7/igt@kms_cursor_edge_walk@pipe-d-128x128-right-edge.html

  * igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy:
    - shard-iclb:         NOTRUN -> [SKIP][60] ([fdo#109274] / [fdo#109278])
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb3/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy.html

  * igt@kms_cursor_legacy@pipe-d-torture-bo:
    - shard-apl:          NOTRUN -> [SKIP][61] ([fdo#109271] / [i915#533])
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl7/igt@kms_cursor_legacy@pipe-d-torture-bo.html

  * igt@kms_cursor_legacy@short-busy-flip-before-cursor-atomic-transitions-varying-size:
    - shard-tglb:         NOTRUN -> [SKIP][62] ([i915#4103])
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_cursor_legacy@short-busy-flip-before-cursor-atomic-transitions-varying-size.html

  * igt@kms_dp_tiled_display@basic-test-pattern-with-chamelium:
    - shard-tglb:         NOTRUN -> [SKIP][63] ([i915#3528])
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb1/igt@kms_dp_tiled_display@basic-test-pattern-with-chamelium.html

  * igt@kms_flip@2x-flip-vs-expired-vblank-interruptible@bc-hdmi-a1-hdmi-a2:
    - shard-glk:          [PASS][64] -> [FAIL][65] ([i915#79]) +1 similar issue
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-glk5/igt@kms_flip@2x-flip-vs-expired-vblank-interruptible@bc-hdmi-a1-hdmi-a2.html
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-glk7/igt@kms_flip@2x-flip-vs-expired-vblank-interruptible@bc-hdmi-a1-hdmi-a2.html

  * igt@kms_flip@flip-vs-suspend-interruptible@c-dp1:
    - shard-kbl:          NOTRUN -> [DMESG-WARN][66] ([i915#180]) +1 similar issue
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_flip@flip-vs-suspend-interruptible@c-dp1.html

  * igt@kms_flip@flip-vs-suspend@a-dp1:
    - shard-apl:          NOTRUN -> [DMESG-WARN][67] ([i915#180])
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl3/igt@kms_flip@flip-vs-suspend@a-dp1.html

  * igt@kms_flip@plain-flip-ts-check-interruptible@b-edp1:
    - shard-skl:          [PASS][68] -> [FAIL][69] ([i915#2122])
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl9/igt@kms_flip@plain-flip-ts-check-interruptible@b-edp1.html
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl5/igt@kms_flip@plain-flip-ts-check-interruptible@b-edp1.html

  * igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-spr-indfb-draw-mmap-gtt:
    - shard-tglb:         NOTRUN -> [SKIP][70] ([fdo#111825]) +26 similar issues
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-spr-indfb-draw-mmap-gtt.html

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-c:
    - shard-tglb:         [PASS][71] -> [INCOMPLETE][72] ([i915#2828] / [i915#456])
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-tglb3/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-c.html
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb7/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-c.html

  * igt@kms_plane_alpha_blend@pipe-a-alpha-7efc:
    - shard-skl:          NOTRUN -> [FAIL][73] ([fdo#108145] / [i915#265])
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl7/igt@kms_plane_alpha_blend@pipe-a-alpha-7efc.html

  * igt@kms_plane_alpha_blend@pipe-a-alpha-transparent-fb:
    - shard-apl:          NOTRUN -> [FAIL][74] ([i915#265])
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl7/igt@kms_plane_alpha_blend@pipe-a-alpha-transparent-fb.html

  * igt@kms_plane_alpha_blend@pipe-c-alpha-basic:
    - shard-kbl:          NOTRUN -> [FAIL][75] ([fdo#108145] / [i915#265]) +1 similar issue
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_plane_alpha_blend@pipe-c-alpha-basic.html

  * igt@kms_plane_alpha_blend@pipe-c-coverage-7efc:
    - shard-skl:          [PASS][76] -> [FAIL][77] ([fdo#108145] / [i915#265]) +1 similar issue
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl10/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl3/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html

  * igt@kms_plane_lowres@pipe-b-tiling-y:
    - shard-tglb:         NOTRUN -> [SKIP][78] ([i915#3536])
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_plane_lowres@pipe-b-tiling-y.html

  * igt@kms_plane_lowres@pipe-d-tiling-yf:
    - shard-tglb:         NOTRUN -> [SKIP][79] ([fdo#112054]) +1 similar issue
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_plane_lowres@pipe-d-tiling-yf.html

  * igt@kms_psr2_sf@plane-move-sf-dmg-area-1:
    - shard-kbl:          NOTRUN -> [SKIP][80] ([fdo#109271] / [i915#658]) +1 similar issue
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_psr2_sf@plane-move-sf-dmg-area-1.html

  * igt@kms_psr2_sf@plane-move-sf-dmg-area-2:
    - shard-apl:          NOTRUN -> [SKIP][81] ([fdo#109271] / [i915#658]) +3 similar issues
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl3/igt@kms_psr2_sf@plane-move-sf-dmg-area-2.html

  * igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-1:
    - shard-tglb:         NOTRUN -> [SKIP][82] ([i915#2920]) +2 similar issues
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-1.html

  * igt@kms_psr2_su@page_flip:
    - shard-tglb:         NOTRUN -> [SKIP][83] ([i915#1911])
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb1/igt@kms_psr2_su@page_flip.html

  * igt@kms_psr@psr2_suspend:
    - shard-iclb:         [PASS][84] -> [SKIP][85] ([fdo#109441])
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb2/igt@kms_psr@psr2_suspend.html
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb7/igt@kms_psr@psr2_suspend.html
    - shard-tglb:         NOTRUN -> [FAIL][86] ([i915#132] / [i915#3467])
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@kms_psr@psr2_suspend.html

  * igt@kms_vblank@pipe-b-ts-continuation-dpms-suspend:
    - shard-skl:          [PASS][87] -> [INCOMPLETE][88] ([i915#198] / [i915#2828])
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl5/igt@kms_vblank@pipe-b-ts-continuation-dpms-suspend.html
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl5/igt@kms_vblank@pipe-b-ts-continuation-dpms-suspend.html

  * igt@kms_vblank@pipe-d-ts-continuation-idle:
    - shard-apl:          NOTRUN -> [SKIP][89] ([fdo#109271]) +93 similar issues
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl3/igt@kms_vblank@pipe-d-ts-continuation-idle.html

  * igt@nouveau_crc@pipe-a-ctx-flip-detection:
    - shard-tglb:         NOTRUN -> [SKIP][90] ([i915#2530]) +2 similar issues
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@nouveau_crc@pipe-a-ctx-flip-detection.html

  * igt@perf_pmu@event-wait@rcs0:
    - shard-tglb:         NOTRUN -> [SKIP][91] ([fdo#112283])
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@perf_pmu@event-wait@rcs0.html

  * igt@prime_nv_pcopy@test3_5:
    - shard-tglb:         NOTRUN -> [SKIP][92] ([fdo#109291])
   [92]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@prime_nv_pcopy@test3_5.html

  * igt@prime_vgem@fence-write-hang:
    - shard-tglb:         NOTRUN -> [SKIP][93] ([fdo#109295])
   [93]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@prime_vgem@fence-write-hang.html

  * igt@sysfs_clients@create:
    - shard-apl:          NOTRUN -> [SKIP][94] ([fdo#109271] / [i915#2994]) +1 similar issue
   [94]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl7/igt@sysfs_clients@create.html

  * igt@sysfs_clients@fair-0:
    - shard-tglb:         NOTRUN -> [SKIP][95] ([i915#2994])
   [95]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb1/igt@sysfs_clients@fair-0.html

  * igt@sysfs_clients@sema-10:
    - shard-skl:          NOTRUN -> [SKIP][96] ([fdo#109271] / [i915#2994])
   [96]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl7/igt@sysfs_clients@sema-10.html

  
#### Possible fixes ####

  * igt@drm_mm@all@evict:
    - shard-skl:          [INCOMPLETE][97] ([i915#198]) -> [PASS][98]
   [97]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl2/igt@drm_mm@all@evict.html
   [98]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl4/igt@drm_mm@all@evict.html

  * igt@gem_exec_fair@basic-none@vecs0:
    - shard-kbl:          [FAIL][99] ([i915#2842]) -> [PASS][100]
   [99]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-kbl4/igt@gem_exec_fair@basic-none@vecs0.html
   [100]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl1/igt@gem_exec_fair@basic-none@vecs0.html

  * igt@gem_exec_fair@basic-pace@bcs0:
    - shard-iclb:         [FAIL][101] ([i915#2842]) -> [PASS][102]
   [101]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb3/igt@gem_exec_fair@basic-pace@bcs0.html
   [102]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb8/igt@gem_exec_fair@basic-pace@bcs0.html

  * igt@gem_exec_fair@basic-pace@vcs1:
    - shard-tglb:         [FAIL][103] ([i915#2842]) -> [PASS][104]
   [103]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-tglb1/igt@gem_exec_fair@basic-pace@vcs1.html
   [104]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb2/igt@gem_exec_fair@basic-pace@vcs1.html

  * igt@gem_softpin@noreloc-s3:
    - shard-apl:          [DMESG-WARN][105] ([i915#180]) -> [PASS][106]
   [105]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-apl8/igt@gem_softpin@noreloc-s3.html
   [106]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl3/igt@gem_softpin@noreloc-s3.html

  * igt@i915_pm_dc@dc6-dpms:
    - shard-iclb:         [FAIL][107] ([i915#454]) -> [PASS][108]
   [107]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb3/igt@i915_pm_dc@dc6-dpms.html
   [108]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb1/igt@i915_pm_dc@dc6-dpms.html

  * igt@i915_suspend@forcewake:
    - shard-skl:          [INCOMPLETE][109] ([i915#636]) -> [PASS][110]
   [109]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl2/igt@i915_suspend@forcewake.html
   [110]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl7/igt@i915_suspend@forcewake.html

  * igt@kms_color@pipe-b-ctm-0-75:
    - shard-skl:          [DMESG-WARN][111] ([i915#1982]) -> [PASS][112]
   [111]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl7/igt@kms_color@pipe-b-ctm-0-75.html
   [112]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl10/igt@kms_color@pipe-b-ctm-0-75.html

  * igt@kms_cursor_crc@pipe-a-cursor-suspend:
    - shard-tglb:         [INCOMPLETE][113] ([i915#2828] / [i915#456]) -> [PASS][114]
   [113]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-tglb7/igt@kms_cursor_crc@pipe-a-cursor-suspend.html
   [114]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@kms_cursor_crc@pipe-a-cursor-suspend.html

  * igt@kms_flip@flip-vs-expired-vblank-interruptible@b-dp1:
    - shard-kbl:          [FAIL][115] ([i915#79]) -> [PASS][116]
   [115]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-kbl7/igt@kms_flip@flip-vs-expired-vblank-interruptible@b-dp1.html
   [116]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_flip@flip-vs-expired-vblank-interruptible@b-dp1.html

  * igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs:
    - shard-iclb:         [SKIP][117] ([i915#3701]) -> [PASS][118]
   [117]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb2/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs.html
   [118]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb1/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs.html

  * igt@kms_plane_alpha_blend@pipe-a-coverage-7efc:
    - shard-skl:          [FAIL][119] ([fdo#108145] / [i915#265]) -> [PASS][120]
   [119]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl10/igt@kms_plane_alpha_blend@pipe-a-coverage-7efc.html
   [120]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl3/igt@kms_plane_alpha_blend@pipe-a-coverage-7efc.html

  * igt@kms_psr@psr2_cursor_plane_move:
    - shard-iclb:         [SKIP][121] ([fdo#109441]) -> [PASS][122]
   [121]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb4/igt@kms_psr@psr2_cursor_plane_move.html
   [122]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb2/igt@kms_psr@psr2_cursor_plane_move.html

  * igt@kms_vblank@pipe-a-ts-continuation-suspend:
    - shard-tglb:         [INCOMPLETE][123] ([i915#456]) -> [PASS][124] +1 similar issue
   [123]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-tglb7/igt@kms_vblank@pipe-a-ts-continuation-suspend.html
   [124]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_vblank@pipe-a-ts-continuation-suspend.html

  
#### Warnings ####

  * igt@i915_pm_rc6_residency@rc6-fence:
    - shard-iclb:         [WARN][125] ([i915#2684]) -> [WARN][126] ([i915#1804] / [i915#2684])
   [125]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb1/igt@i915_pm_rc6_residency@rc6-fence.html
   [126]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb3/igt@i915_pm_rc6_residency@rc6-fence.html

  * igt@kms_psr2_sf@plane-move-sf-dmg-area-0:
    - shard-iclb:         [SKIP][127] ([i915#658]) -> [SKIP][128] ([i915#2920])
   [127]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb5/igt@kms_psr2_sf@plane-move-sf-dmg-area-0.html
   [128]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb2/igt@kms_psr2_sf@plane-move-sf-dmg-area-0.html

  * igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-1:
    - shard-iclb:         [SKIP][129] ([i915#2920]) -> [SKIP][130] ([i915#658]) +2 similar issues
   [129]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb2/igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-1.html
   [130]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb7/igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-1.html

  * igt@kms_psr2_su@page_flip:
    - shard-iclb:         [FAIL][131] ([i915#4148]) -> [SKIP][132] ([fdo#109642] / [fdo#111068] / [i915#658])
   [131]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb2/igt@kms_psr2_su@page_flip.html
   [132]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb7/igt@kms_psr2_su@page_flip.html

  * igt@runner@aborted:
    - shard-kbl:          ([FAIL][133], [FAIL][134]) ([i915#3002] / [i915#3363] / [i915#4312]) -> ([FAIL][135], [FAIL][136], [FAIL][137]) ([i915#1436] / [i915#180] / [i915#3002] / [i915#3363] / [i915#4312])
   [133]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-kbl7/igt@runner@aborted.html
   [134]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-kbl1/igt@runner@aborted.html
   [135]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl3/igt@runner@aborted.html
   [136]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@runner@aborted.html
   [137]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@runner@aborted.html
    - shard-apl:          ([FAIL][138], [FAIL][139], [FAIL][140]) ([i915#180] / [i915#1814] / [i915#3002] / [i915#3363] / [i915#4312]) -> ([FAIL][141], [FAIL][142], [FAIL][143], [FAIL][144]) ([i915#180] / [i915#3002] / [i915#3363] / [i915#4312])
   [138]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-apl6/igt@runner@aborted.html
   [139]: ht

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/index.html

[-- Attachment #2: Type: text/html, Size: 33597 bytes --]

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [PATCH 03/28] drm/i915: Remove dma_resv_prune
  2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 14:43     ` Matthew Auld
  -1 siblings, 0 replies; 114+ messages in thread
From: Matthew Auld @ 2021-10-21 14:43 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Intel Graphics Development, ML dri-devel

On Thu, 21 Oct 2021 at 11:36, Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
>
> The signaled bit is already used for quick testing if a fence is signaled.

Why do we need this change? Can you add some more details to the commit please?

>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/Makefile                |  1 -
>  drivers/gpu/drm/i915/dma_resv_utils.c        | 17 -----------------
>  drivers/gpu/drm/i915/dma_resv_utils.h        | 13 -------------
>  drivers/gpu/drm/i915/gem/i915_gem_shrinker.c |  3 ---
>  drivers/gpu/drm/i915/gem/i915_gem_wait.c     |  8 --------
>  5 files changed, 42 deletions(-)
>  delete mode 100644 drivers/gpu/drm/i915/dma_resv_utils.c
>  delete mode 100644 drivers/gpu/drm/i915/dma_resv_utils.h
>
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 467872cca027..b87e3ed10d86 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -60,7 +60,6 @@ i915-y += i915_drv.o \
>
>  # core library code
>  i915-y += \
> -       dma_resv_utils.o \
>         i915_memcpy.o \
>         i915_mm.o \
>         i915_sw_fence.o \
> diff --git a/drivers/gpu/drm/i915/dma_resv_utils.c b/drivers/gpu/drm/i915/dma_resv_utils.c
> deleted file mode 100644
> index 7df91b7e4ca8..000000000000
> --- a/drivers/gpu/drm/i915/dma_resv_utils.c
> +++ /dev/null
> @@ -1,17 +0,0 @@
> -// SPDX-License-Identifier: MIT
> -/*
> - * Copyright © 2020 Intel Corporation
> - */
> -
> -#include <linux/dma-resv.h>
> -
> -#include "dma_resv_utils.h"
> -
> -void dma_resv_prune(struct dma_resv *resv)
> -{
> -       if (dma_resv_trylock(resv)) {
> -               if (dma_resv_test_signaled(resv, true))
> -                       dma_resv_add_excl_fence(resv, NULL);
> -               dma_resv_unlock(resv);
> -       }
> -}
> diff --git a/drivers/gpu/drm/i915/dma_resv_utils.h b/drivers/gpu/drm/i915/dma_resv_utils.h
> deleted file mode 100644
> index b9d8fb5f8367..000000000000
> --- a/drivers/gpu/drm/i915/dma_resv_utils.h
> +++ /dev/null
> @@ -1,13 +0,0 @@
> -/* SPDX-License-Identifier: MIT */
> -/*
> - * Copyright © 2020 Intel Corporation
> - */
> -
> -#ifndef DMA_RESV_UTILS_H
> -#define DMA_RESV_UTILS_H
> -
> -struct dma_resv;
> -
> -void dma_resv_prune(struct dma_resv *resv);
> -
> -#endif /* DMA_RESV_UTILS_H */
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
> index 5ab136ffdeb2..af3eb7fd951d 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
> @@ -15,7 +15,6 @@
>
>  #include "gt/intel_gt_requests.h"
>
> -#include "dma_resv_utils.h"
>  #include "i915_trace.h"
>
>  static bool swap_available(void)
> @@ -229,8 +228,6 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww,
>                                         i915_gem_object_unlock(obj);
>                         }
>
> -                       dma_resv_prune(obj->base.resv);

Like here, why do we want to drop this? Later in the series it looks
like it gets added back, just in a slightly different form.

> -
>                         scanned += obj->base.size >> PAGE_SHIFT;
>  skip:
>                         i915_gem_object_put(obj);
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_wait.c b/drivers/gpu/drm/i915/gem/i915_gem_wait.c
> index 840c13706999..1592d95c3ead 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_wait.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_wait.c
> @@ -10,7 +10,6 @@
>
>  #include "gt/intel_engine.h"
>
> -#include "dma_resv_utils.h"
>  #include "i915_gem_ioctls.h"
>  #include "i915_gem_object.h"
>
> @@ -52,13 +51,6 @@ i915_gem_object_wait_reservation(struct dma_resv *resv,
>         }
>         dma_resv_iter_end(&cursor);
>
> -       /*
> -        * Opportunistically prune the fences iff we know they have *all* been
> -        * signaled.
> -        */
> -       if (timeout > 0)
> -               dma_resv_prune(resv);
> -
>         return ret;
>  }
>
> --
> 2.33.0
>

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 03/28] drm/i915: Remove dma_resv_prune
@ 2021-10-21 14:43     ` Matthew Auld
  0 siblings, 0 replies; 114+ messages in thread
From: Matthew Auld @ 2021-10-21 14:43 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Intel Graphics Development, ML dri-devel

On Thu, 21 Oct 2021 at 11:36, Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
>
> The signaled bit is already used for quick testing if a fence is signaled.

Why do we need this change? Can you add some more details to the commit please?

>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/Makefile                |  1 -
>  drivers/gpu/drm/i915/dma_resv_utils.c        | 17 -----------------
>  drivers/gpu/drm/i915/dma_resv_utils.h        | 13 -------------
>  drivers/gpu/drm/i915/gem/i915_gem_shrinker.c |  3 ---
>  drivers/gpu/drm/i915/gem/i915_gem_wait.c     |  8 --------
>  5 files changed, 42 deletions(-)
>  delete mode 100644 drivers/gpu/drm/i915/dma_resv_utils.c
>  delete mode 100644 drivers/gpu/drm/i915/dma_resv_utils.h
>
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 467872cca027..b87e3ed10d86 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -60,7 +60,6 @@ i915-y += i915_drv.o \
>
>  # core library code
>  i915-y += \
> -       dma_resv_utils.o \
>         i915_memcpy.o \
>         i915_mm.o \
>         i915_sw_fence.o \
> diff --git a/drivers/gpu/drm/i915/dma_resv_utils.c b/drivers/gpu/drm/i915/dma_resv_utils.c
> deleted file mode 100644
> index 7df91b7e4ca8..000000000000
> --- a/drivers/gpu/drm/i915/dma_resv_utils.c
> +++ /dev/null
> @@ -1,17 +0,0 @@
> -// SPDX-License-Identifier: MIT
> -/*
> - * Copyright © 2020 Intel Corporation
> - */
> -
> -#include <linux/dma-resv.h>
> -
> -#include "dma_resv_utils.h"
> -
> -void dma_resv_prune(struct dma_resv *resv)
> -{
> -       if (dma_resv_trylock(resv)) {
> -               if (dma_resv_test_signaled(resv, true))
> -                       dma_resv_add_excl_fence(resv, NULL);
> -               dma_resv_unlock(resv);
> -       }
> -}
> diff --git a/drivers/gpu/drm/i915/dma_resv_utils.h b/drivers/gpu/drm/i915/dma_resv_utils.h
> deleted file mode 100644
> index b9d8fb5f8367..000000000000
> --- a/drivers/gpu/drm/i915/dma_resv_utils.h
> +++ /dev/null
> @@ -1,13 +0,0 @@
> -/* SPDX-License-Identifier: MIT */
> -/*
> - * Copyright © 2020 Intel Corporation
> - */
> -
> -#ifndef DMA_RESV_UTILS_H
> -#define DMA_RESV_UTILS_H
> -
> -struct dma_resv;
> -
> -void dma_resv_prune(struct dma_resv *resv);
> -
> -#endif /* DMA_RESV_UTILS_H */
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
> index 5ab136ffdeb2..af3eb7fd951d 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
> @@ -15,7 +15,6 @@
>
>  #include "gt/intel_gt_requests.h"
>
> -#include "dma_resv_utils.h"
>  #include "i915_trace.h"
>
>  static bool swap_available(void)
> @@ -229,8 +228,6 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww,
>                                         i915_gem_object_unlock(obj);
>                         }
>
> -                       dma_resv_prune(obj->base.resv);

Like here, why do we want to drop this? Later in the series it looks
like it gets added back, just in a slightly different form.

> -
>                         scanned += obj->base.size >> PAGE_SHIFT;
>  skip:
>                         i915_gem_object_put(obj);
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_wait.c b/drivers/gpu/drm/i915/gem/i915_gem_wait.c
> index 840c13706999..1592d95c3ead 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_wait.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_wait.c
> @@ -10,7 +10,6 @@
>
>  #include "gt/intel_engine.h"
>
> -#include "dma_resv_utils.h"
>  #include "i915_gem_ioctls.h"
>  #include "i915_gem_object.h"
>
> @@ -52,13 +51,6 @@ i915_gem_object_wait_reservation(struct dma_resv *resv,
>         }
>         dma_resv_iter_end(&cursor);
>
> -       /*
> -        * Opportunistically prune the fences iff we know they have *all* been
> -        * signaled.
> -        */
> -       if (timeout > 0)
> -               dma_resv_prune(resv);
> -
>         return ret;
>  }
>
> --
> 2.33.0
>

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 07/28] drm/i915: Create a dummy object for gen6 ppgtt
  2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
  (?)
@ 2021-10-21 15:42   ` Matthew Auld
  -1 siblings, 0 replies; 114+ messages in thread
From: Matthew Auld @ 2021-10-21 15:42 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Intel Graphics Development, ML dri-devel

On Thu, 21 Oct 2021 at 11:36, Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
>
> We currently have to special case vma->obj being NULL because
> of gen6 ppgtt and mock_engine. Fix gen6 ppgtt, so we may soon
> be able to remove a few checks. As the object only exists as
> a fake object pointing to ggtt, we have no backing storage,
> so no real object is created. It just has to look real enough.
>
> Also kill pin_mutex, it's not compatible with ww locking,
> and we can use the vm lock instead.
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_internal.c |  44 ++++---
>  drivers/gpu/drm/i915/gt/gen6_ppgtt.c         | 122 +++++++++++--------
>  drivers/gpu/drm/i915/gt/gen6_ppgtt.h         |   1 -
>  drivers/gpu/drm/i915/i915_drv.h              |   4 +
>  4 files changed, 99 insertions(+), 72 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
> index a57a6b7013c2..c5150a1ee3d2 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
> @@ -145,24 +145,10 @@ static const struct drm_i915_gem_object_ops i915_gem_object_internal_ops = {
>         .put_pages = i915_gem_object_put_pages_internal,
>  };
>
> -/**
> - * i915_gem_object_create_internal: create an object with volatile pages
> - * @i915: the i915 device
> - * @size: the size in bytes of backing storage to allocate for the object
> - *
> - * Creates a new object that wraps some internal memory for private use.
> - * This object is not backed by swappable storage, and as such its contents
> - * are volatile and only valid whilst pinned. If the object is reaped by the
> - * shrinker, its pages and data will be discarded. Equally, it is not a full
> - * GEM object and so not valid for access from userspace. This makes it useful
> - * for hardware interfaces like ringbuffers (which are pinned from the time
> - * the request is written to the time the hardware stops accessing it), but
> - * not for contexts (which need to be preserved when not active for later
> - * reuse). Note that it is not cleared upon allocation.
> - */
>  struct drm_i915_gem_object *
> -i915_gem_object_create_internal(struct drm_i915_private *i915,
> -                               phys_addr_t size)
> +__i915_gem_object_create_internal(struct drm_i915_private *i915,
> +                                 const struct drm_i915_gem_object_ops *ops,
> +                                 phys_addr_t size)
>  {
>         static struct lock_class_key lock_class;
>         struct drm_i915_gem_object *obj;
> @@ -179,7 +165,7 @@ i915_gem_object_create_internal(struct drm_i915_private *i915,
>                 return ERR_PTR(-ENOMEM);
>
>         drm_gem_private_object_init(&i915->drm, &obj->base, size);
> -       i915_gem_object_init(obj, &i915_gem_object_internal_ops, &lock_class, 0);
> +       i915_gem_object_init(obj, ops, &lock_class, 0);
>         obj->mem_flags |= I915_BO_FLAG_STRUCT_PAGE;
>
>         /*
> @@ -199,3 +185,25 @@ i915_gem_object_create_internal(struct drm_i915_private *i915,
>
>         return obj;
>  }
> +
> +/**
> + * i915_gem_object_create_internal: create an object with volatile pages
> + * @i915: the i915 device
> + * @size: the size in bytes of backing storage to allocate for the object
> + *
> + * Creates a new object that wraps some internal memory for private use.
> + * This object is not backed by swappable storage, and as such its contents
> + * are volatile and only valid whilst pinned. If the object is reaped by the
> + * shrinker, its pages and data will be discarded. Equally, it is not a full
> + * GEM object and so not valid for access from userspace. This makes it useful
> + * for hardware interfaces like ringbuffers (which are pinned from the time
> + * the request is written to the time the hardware stops accessing it), but
> + * not for contexts (which need to be preserved when not active for later
> + * reuse). Note that it is not cleared upon allocation.
> + */
> +struct drm_i915_gem_object *
> +i915_gem_object_create_internal(struct drm_i915_private *i915,
> +                               phys_addr_t size)
> +{
> +       return __i915_gem_object_create_internal(i915, &i915_gem_object_internal_ops, size);
> +}
> diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
> index 9fdbd9d3372b..5caa1703716e 100644
> --- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
> +++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
> @@ -262,13 +262,10 @@ static void gen6_ppgtt_cleanup(struct i915_address_space *vm)
>  {
>         struct gen6_ppgtt *ppgtt = to_gen6_ppgtt(i915_vm_to_ppgtt(vm));
>
> -       __i915_vma_put(ppgtt->vma);
> -
>         gen6_ppgtt_free_pd(ppgtt);
>         free_scratch(vm);
>
>         mutex_destroy(&ppgtt->flush);
> -       mutex_destroy(&ppgtt->pin_mutex);
>
>         free_pd(&ppgtt->base.vm, ppgtt->base.pd);
>  }
> @@ -331,37 +328,6 @@ static const struct i915_vma_ops pd_vma_ops = {
>         .unbind_vma = pd_vma_unbind,
>  };
>
> -static struct i915_vma *pd_vma_create(struct gen6_ppgtt *ppgtt, int size)
> -{
> -       struct i915_ggtt *ggtt = ppgtt->base.vm.gt->ggtt;
> -       struct i915_vma *vma;
> -
> -       GEM_BUG_ON(!IS_ALIGNED(size, I915_GTT_PAGE_SIZE));
> -       GEM_BUG_ON(size > ggtt->vm.total);
> -
> -       vma = i915_vma_alloc();
> -       if (!vma)
> -               return ERR_PTR(-ENOMEM);
> -
> -       i915_active_init(&vma->active, NULL, NULL, 0);
> -
> -       kref_init(&vma->ref);
> -       mutex_init(&vma->pages_mutex);
> -       vma->vm = i915_vm_get(&ggtt->vm);
> -       vma->ops = &pd_vma_ops;
> -       vma->private = ppgtt;
> -
> -       vma->size = size;
> -       vma->fence_size = size;
> -       atomic_set(&vma->flags, I915_VMA_GGTT);
> -       vma->ggtt_view.type = I915_GGTT_VIEW_ROTATED; /* prevent fencing */
> -
> -       INIT_LIST_HEAD(&vma->obj_link);
> -       INIT_LIST_HEAD(&vma->closed_link);
> -
> -       return vma;
> -}
> -
>  int gen6_ppgtt_pin(struct i915_ppgtt *base, struct i915_gem_ww_ctx *ww)
>  {
>         struct gen6_ppgtt *ppgtt = to_gen6_ppgtt(base);
> @@ -378,24 +344,84 @@ int gen6_ppgtt_pin(struct i915_ppgtt *base, struct i915_gem_ww_ctx *ww)
>         if (atomic_add_unless(&ppgtt->pin_count, 1, 0))
>                 return 0;
>
> -       if (mutex_lock_interruptible(&ppgtt->pin_mutex))
> -               return -EINTR;
> +       /* grab the ppgtt resv to pin the object */
> +       err = i915_vm_lock_objects(&ppgtt->base.vm, ww);
> +       if (err)
> +               return err;
>
>         /*
>          * PPGTT PDEs reside in the GGTT and consists of 512 entries. The
>          * allocator works in address space sizes, so it's multiplied by page
>          * size. We allocate at the top of the GTT to avoid fragmentation.
>          */
> -       err = 0;
> -       if (!atomic_read(&ppgtt->pin_count))
> +       if (!atomic_read(&ppgtt->pin_count)) {
>                 err = i915_ggtt_pin(ppgtt->vma, ww, GEN6_PD_ALIGN, PIN_HIGH);
> +
> +               GEM_BUG_ON(ppgtt->vma->fence);
> +               clear_bit(I915_VMA_CAN_FENCE_BIT, __i915_vma_flags(ppgtt->vma));
> +       }
>         if (!err)
>                 atomic_inc(&ppgtt->pin_count);
> -       mutex_unlock(&ppgtt->pin_mutex);
>
>         return err;
>  }
>
> +static int pd_dummy_obj_get_pages(struct drm_i915_gem_object *obj)
> +{
> +       obj->mm.pages = ZERO_SIZE_PTR;
> +       return 0;
> +}
> +
> +static void pd_dummy_obj_put_pages(struct drm_i915_gem_object *obj,
> +                                    struct sg_table *pages)
> +{
> +}
> +
> +static const struct drm_i915_gem_object_ops pd_dummy_obj_ops = {
> +       .name = "pd_dummy_obj",
> +       .flags = I915_GEM_OBJECT_IS_SHRINKABLE,

I would assume we don't want this dummy object to be considered for shrinking?

> +       .get_pages = pd_dummy_obj_get_pages,
> +       .put_pages = pd_dummy_obj_put_pages,
> +};
> +
> +static struct i915_page_directory *
> +gen6_alloc_top_pd(struct gen6_ppgtt *ppgtt)
> +{
> +       struct i915_ggtt * const ggtt = ppgtt->base.vm.gt->ggtt;
> +       struct i915_page_directory *pd;
> +       int err;
> +
> +       pd = __alloc_pd(I915_PDES);
> +       if (unlikely(!pd))
> +               return ERR_PTR(-ENOMEM);
> +
> +       pd->pt.base = __i915_gem_object_create_internal(ppgtt->base.vm.gt->i915, &pd_dummy_obj_ops, I915_PDES * SZ_4K);

Overly long line?

Otherwise,
Reviewed-by: Matthew Auld <matthew.auld@intel.com>

> +       if (IS_ERR(pd->pt.base)) {
> +               err = PTR_ERR(pd->pt.base);
> +               pd->pt.base = NULL;
> +               goto err_pd;
> +       }
> +
> +       pd->pt.base->base.resv = i915_vm_resv_get(&ppgtt->base.vm);
> +       pd->pt.base->shares_resv_from = &ppgtt->base.vm;
> +
> +       ppgtt->vma = i915_vma_instance(pd->pt.base, &ggtt->vm, NULL);
> +       if (IS_ERR(ppgtt->vma)) {
> +               err = PTR_ERR(ppgtt->vma);
> +               ppgtt->vma = NULL;
> +               goto err_pd;
> +       }
> +
> +       /* The dummy object we create is special, override ops.. */
> +       ppgtt->vma->ops = &pd_vma_ops;
> +       ppgtt->vma->private = ppgtt;
> +       return pd;
> +
> +err_pd:
> +       free_pd(&ppgtt->base.vm, pd);
> +       return ERR_PTR(err);
> +}
> +
>  void gen6_ppgtt_unpin(struct i915_ppgtt *base)
>  {
>         struct gen6_ppgtt *ppgtt = to_gen6_ppgtt(base);
> @@ -416,7 +442,6 @@ struct i915_ppgtt *gen6_ppgtt_create(struct intel_gt *gt)
>                 return ERR_PTR(-ENOMEM);
>
>         mutex_init(&ppgtt->flush);
> -       mutex_init(&ppgtt->pin_mutex);
>
>         ppgtt_init(&ppgtt->base, gt, 0);
>         ppgtt->base.vm.pd_shift = ilog2(SZ_4K * SZ_4K / sizeof(gen6_pte_t));
> @@ -431,19 +456,13 @@ struct i915_ppgtt *gen6_ppgtt_create(struct intel_gt *gt)
>         ppgtt->base.vm.alloc_pt_dma = alloc_pt_dma;
>         ppgtt->base.vm.pte_encode = ggtt->vm.pte_encode;
>
> -       ppgtt->base.pd = __alloc_pd(I915_PDES);
> -       if (!ppgtt->base.pd) {
> -               err = -ENOMEM;
> -               goto err_free;
> -       }
> -
>         err = gen6_ppgtt_init_scratch(ppgtt);
>         if (err)
> -               goto err_pd;
> +               goto err_free;
>
> -       ppgtt->vma = pd_vma_create(ppgtt, GEN6_PD_SIZE);
> -       if (IS_ERR(ppgtt->vma)) {
> -               err = PTR_ERR(ppgtt->vma);
> +       ppgtt->base.pd = gen6_alloc_top_pd(ppgtt);
> +       if (IS_ERR(ppgtt->base.pd)) {
> +               err = PTR_ERR(ppgtt->base.pd);
>                 goto err_scratch;
>         }
>
> @@ -451,10 +470,7 @@ struct i915_ppgtt *gen6_ppgtt_create(struct intel_gt *gt)
>
>  err_scratch:
>         free_scratch(&ppgtt->base.vm);
> -err_pd:
> -       free_pd(&ppgtt->base.vm, ppgtt->base.pd);
>  err_free:
> -       mutex_destroy(&ppgtt->pin_mutex);
>         kfree(ppgtt);
>         return ERR_PTR(err);
>  }
> diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.h b/drivers/gpu/drm/i915/gt/gen6_ppgtt.h
> index ab0eecb086dd..5e5cf2ec3309 100644
> --- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.h
> +++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.h
> @@ -19,7 +19,6 @@ struct gen6_ppgtt {
>         u32 pp_dir;
>
>         atomic_t pin_count;
> -       struct mutex pin_mutex;
>
>         bool scan_for_unused_pt;
>  };
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 12256218634f..a8d733a7e1d9 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1933,6 +1933,10 @@ int i915_gem_evict_vm(struct i915_address_space *vm);
>  struct drm_i915_gem_object *
>  i915_gem_object_create_internal(struct drm_i915_private *dev_priv,
>                                 phys_addr_t size);
> +struct drm_i915_gem_object *
> +__i915_gem_object_create_internal(struct drm_i915_private *dev_priv,
> +                                 const struct drm_i915_gem_object_ops *ops,
> +                                 phys_addr_t size);
>
>  /* i915_gem_tiling.c */
>  static inline bool i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj)
> --
> 2.33.0
>

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [PATCH 08/28] drm/i915: Create a full object for mock_ring, v2.
  2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-21 15:57     ` Matthew Auld
  -1 siblings, 0 replies; 114+ messages in thread
From: Matthew Auld @ 2021-10-21 15:57 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Intel Graphics Development, ML dri-devel

On Thu, 21 Oct 2021 at 11:36, Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
>
> This allows us to finally get rid of all the assumptions that vma->obj is NULL.
>
> Changes since v1:
> - Ensure the mock_ring vma is pinned to prevent a fault.
> - Pin it high to avoid failure in evict_for_vma selftest.
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/gt/mock_engine.c | 38 ++++++++++++++++++++-------
>  1 file changed, 28 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gt/mock_engine.c b/drivers/gpu/drm/i915/gt/mock_engine.c
> index 8b89215afe46..bb99fc03f503 100644
> --- a/drivers/gpu/drm/i915/gt/mock_engine.c
> +++ b/drivers/gpu/drm/i915/gt/mock_engine.c
> @@ -35,9 +35,31 @@ static void mock_timeline_unpin(struct intel_timeline *tl)
>         atomic_dec(&tl->pin_count);
>  }
>
> +static struct i915_vma *create_ring_vma(struct i915_ggtt *ggtt, int size)
> +{
> +       struct i915_address_space *vm = &ggtt->vm;
> +       struct drm_i915_private *i915 = vm->i915;
> +       struct drm_i915_gem_object *obj;
> +       struct i915_vma *vma;
> +
> +       obj = i915_gem_object_create_internal(i915, size);
> +       if (IS_ERR(obj))
> +               return ERR_CAST(obj);

We didn't want to use the dummy object here also? I guess meh?

> +
> +       vma = i915_vma_instance(obj, vm, NULL);
> +       if (IS_ERR(vma))
> +               goto err;
> +
> +       return vma;
> +
> +err:
> +       i915_gem_object_put(obj);
> +       return vma;
> +}
> +
>  static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
>  {
> -       const unsigned long sz = PAGE_SIZE / 2;
> +       const unsigned long sz = PAGE_SIZE;

Is that significant?

Reviewed-by: Matthew Auld <matthew.auld@intel.com>


>         struct intel_ring *ring;
>
>         ring = kzalloc(sizeof(*ring) + sz, GFP_KERNEL);
> @@ -50,15 +72,11 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
>         ring->vaddr = (void *)(ring + 1);
>         atomic_set(&ring->pin_count, 1);
>
> -       ring->vma = i915_vma_alloc();
> -       if (!ring->vma) {
> +       ring->vma = create_ring_vma(engine->gt->ggtt, PAGE_SIZE);
> +       if (IS_ERR(ring->vma)) {
>                 kfree(ring);
>                 return NULL;
>         }
> -       i915_active_init(&ring->vma->active, NULL, NULL, 0);
> -       __set_bit(I915_VMA_GGTT_BIT, __i915_vma_flags(ring->vma));
> -       __set_bit(DRM_MM_NODE_ALLOCATED_BIT, &ring->vma->node.flags);
> -       ring->vma->node.size = sz;
>
>         intel_ring_update_space(ring);
>
> @@ -67,8 +85,7 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
>
>  static void mock_ring_free(struct intel_ring *ring)
>  {
> -       i915_active_fini(&ring->vma->active);
> -       i915_vma_free(ring->vma);
> +       i915_vma_put(ring->vma);
>
>         kfree(ring);
>  }
> @@ -125,6 +142,7 @@ static void mock_context_unpin(struct intel_context *ce)
>
>  static void mock_context_post_unpin(struct intel_context *ce)
>  {
> +       i915_vma_unpin(ce->ring->vma);
>  }
>
>  static void mock_context_destroy(struct kref *ref)
> @@ -169,7 +187,7 @@ static int mock_context_alloc(struct intel_context *ce)
>  static int mock_context_pre_pin(struct intel_context *ce,
>                                 struct i915_gem_ww_ctx *ww, void **unused)
>  {
> -       return 0;
> +       return i915_vma_pin_ww(ce->ring->vma, ww, 0, 0, PIN_GLOBAL | PIN_HIGH);
>  }
>
>  static int mock_context_pin(struct intel_context *ce, void *unused)
> --
> 2.33.0
>

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 08/28] drm/i915: Create a full object for mock_ring, v2.
@ 2021-10-21 15:57     ` Matthew Auld
  0 siblings, 0 replies; 114+ messages in thread
From: Matthew Auld @ 2021-10-21 15:57 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Intel Graphics Development, ML dri-devel

On Thu, 21 Oct 2021 at 11:36, Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
>
> This allows us to finally get rid of all the assumptions that vma->obj is NULL.
>
> Changes since v1:
> - Ensure the mock_ring vma is pinned to prevent a fault.
> - Pin it high to avoid failure in evict_for_vma selftest.
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/gt/mock_engine.c | 38 ++++++++++++++++++++-------
>  1 file changed, 28 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gt/mock_engine.c b/drivers/gpu/drm/i915/gt/mock_engine.c
> index 8b89215afe46..bb99fc03f503 100644
> --- a/drivers/gpu/drm/i915/gt/mock_engine.c
> +++ b/drivers/gpu/drm/i915/gt/mock_engine.c
> @@ -35,9 +35,31 @@ static void mock_timeline_unpin(struct intel_timeline *tl)
>         atomic_dec(&tl->pin_count);
>  }
>
> +static struct i915_vma *create_ring_vma(struct i915_ggtt *ggtt, int size)
> +{
> +       struct i915_address_space *vm = &ggtt->vm;
> +       struct drm_i915_private *i915 = vm->i915;
> +       struct drm_i915_gem_object *obj;
> +       struct i915_vma *vma;
> +
> +       obj = i915_gem_object_create_internal(i915, size);
> +       if (IS_ERR(obj))
> +               return ERR_CAST(obj);

We didn't want to use the dummy object here also? I guess meh?

> +
> +       vma = i915_vma_instance(obj, vm, NULL);
> +       if (IS_ERR(vma))
> +               goto err;
> +
> +       return vma;
> +
> +err:
> +       i915_gem_object_put(obj);
> +       return vma;
> +}
> +
>  static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
>  {
> -       const unsigned long sz = PAGE_SIZE / 2;
> +       const unsigned long sz = PAGE_SIZE;

Is that significant?

Reviewed-by: Matthew Auld <matthew.auld@intel.com>


>         struct intel_ring *ring;
>
>         ring = kzalloc(sizeof(*ring) + sz, GFP_KERNEL);
> @@ -50,15 +72,11 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
>         ring->vaddr = (void *)(ring + 1);
>         atomic_set(&ring->pin_count, 1);
>
> -       ring->vma = i915_vma_alloc();
> -       if (!ring->vma) {
> +       ring->vma = create_ring_vma(engine->gt->ggtt, PAGE_SIZE);
> +       if (IS_ERR(ring->vma)) {
>                 kfree(ring);
>                 return NULL;
>         }
> -       i915_active_init(&ring->vma->active, NULL, NULL, 0);
> -       __set_bit(I915_VMA_GGTT_BIT, __i915_vma_flags(ring->vma));
> -       __set_bit(DRM_MM_NODE_ALLOCATED_BIT, &ring->vma->node.flags);
> -       ring->vma->node.size = sz;
>
>         intel_ring_update_space(ring);
>
> @@ -67,8 +85,7 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
>
>  static void mock_ring_free(struct intel_ring *ring)
>  {
> -       i915_active_fini(&ring->vma->active);
> -       i915_vma_free(ring->vma);
> +       i915_vma_put(ring->vma);
>
>         kfree(ring);
>  }
> @@ -125,6 +142,7 @@ static void mock_context_unpin(struct intel_context *ce)
>
>  static void mock_context_post_unpin(struct intel_context *ce)
>  {
> +       i915_vma_unpin(ce->ring->vma);
>  }
>
>  static void mock_context_destroy(struct kref *ref)
> @@ -169,7 +187,7 @@ static int mock_context_alloc(struct intel_context *ce)
>  static int mock_context_pre_pin(struct intel_context *ce,
>                                 struct i915_gem_ww_ctx *ww, void **unused)
>  {
> -       return 0;
> +       return i915_vma_pin_ww(ce->ring->vma, ww, 0, 0, PIN_GLOBAL | PIN_HIGH);
>  }
>
>  static int mock_context_pin(struct intel_context *ce, void *unused)
> --
> 2.33.0
>

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 09/28] drm/i915: vma is always backed by an object.
  2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
  (?)
@ 2021-10-21 16:09   ` Matthew Auld
  -1 siblings, 0 replies; 114+ messages in thread
From: Matthew Auld @ 2021-10-21 16:09 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Intel Graphics Development, ML dri-devel

On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
>
> vma->obj and vma->resv are now never NULL, and some checks can be removed.
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/gt/intel_context.c       |  2 +-
>  .../gpu/drm/i915/gt/intel_ring_submission.c   |  2 +-
>  drivers/gpu/drm/i915/i915_vma.c               | 48 ++++++++-----------
>  drivers/gpu/drm/i915/i915_vma.h               |  3 --
>  4 files changed, 22 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c
> index 5634d14052bc..e0220ac0e9b6 100644
> --- a/drivers/gpu/drm/i915/gt/intel_context.c
> +++ b/drivers/gpu/drm/i915/gt/intel_context.c
> @@ -219,7 +219,7 @@ int __intel_context_do_pin_ww(struct intel_context *ce,
>          */
>
>         err = i915_gem_object_lock(ce->timeline->hwsp_ggtt->obj, ww);
> -       if (!err && ce->ring->vma->obj)
> +       if (!err)
>                 err = i915_gem_object_lock(ce->ring->vma->obj, ww);
>         if (!err && ce->state)
>                 err = i915_gem_object_lock(ce->state->obj, ww);
> diff --git a/drivers/gpu/drm/i915/gt/intel_ring_submission.c b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
> index 586dca1731ce..3e6fac0340ef 100644
> --- a/drivers/gpu/drm/i915/gt/intel_ring_submission.c
> +++ b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
> @@ -1357,7 +1357,7 @@ int intel_ring_submission_setup(struct intel_engine_cs *engine)
>         err = i915_gem_object_lock(timeline->hwsp_ggtt->obj, &ww);
>         if (!err && gen7_wa_vma)
>                 err = i915_gem_object_lock(gen7_wa_vma->obj, &ww);
> -       if (!err && engine->legacy.ring->vma->obj)
> +       if (!err)
>                 err = i915_gem_object_lock(engine->legacy.ring->vma->obj, &ww);
>         if (!err)
>                 err = intel_timeline_pin(timeline, &ww);
> diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
> index 1187f1956c20..aebfc232b58b 100644
> --- a/drivers/gpu/drm/i915/i915_vma.c
> +++ b/drivers/gpu/drm/i915/i915_vma.c
> @@ -40,12 +40,12 @@
>
>  static struct kmem_cache *slab_vmas;
>
> -struct i915_vma *i915_vma_alloc(void)
> +static struct i915_vma *i915_vma_alloc(void)
>  {
>         return kmem_cache_zalloc(slab_vmas, GFP_KERNEL);
>  }
>
> -void i915_vma_free(struct i915_vma *vma)
> +static void i915_vma_free(struct i915_vma *vma)
>  {

I assume this belongs in the previous patch?

Otherwise,
Reviewed-by: Matthew Auld <matthew.auld@intel.com>


>         return kmem_cache_free(slab_vmas, vma);
>  }
> @@ -426,10 +426,8 @@ int i915_vma_bind(struct i915_vma *vma,
>
>                 work->base.dma.error = 0; /* enable the queue_work() */
>
> -               if (vma->obj) {
> -                       __i915_gem_object_pin_pages(vma->obj);
> -                       work->pinned = i915_gem_object_get(vma->obj);
> -               }
> +               __i915_gem_object_pin_pages(vma->obj);
> +               work->pinned = i915_gem_object_get(vma->obj);
>         } else {
>                 vma->ops->bind_vma(vma->vm, NULL, vma, cache_level, bind_flags);
>         }
> @@ -670,7 +668,7 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
>         }
>
>         color = 0;
> -       if (vma->obj && i915_vm_has_cache_coloring(vma->vm))
> +       if (i915_vm_has_cache_coloring(vma->vm))
>                 color = vma->obj->cache_level;
>
>         if (flags & PIN_OFFSET_FIXED) {
> @@ -795,17 +793,14 @@ static bool try_qad_pin(struct i915_vma *vma, unsigned int flags)
>  static int vma_get_pages(struct i915_vma *vma)
>  {
>         int err = 0;
> -       bool pinned_pages = false;
> +       bool pinned_pages = true;
>
>         if (atomic_add_unless(&vma->pages_count, 1, 0))
>                 return 0;
>
> -       if (vma->obj) {
> -               err = i915_gem_object_pin_pages(vma->obj);
> -               if (err)
> -                       return err;
> -               pinned_pages = true;
> -       }
> +       err = i915_gem_object_pin_pages(vma->obj);
> +       if (err)
> +               return err;
>
>         /* Allocations ahoy! */
>         if (mutex_lock_interruptible(&vma->pages_mutex)) {
> @@ -838,8 +833,8 @@ static void __vma_put_pages(struct i915_vma *vma, unsigned int count)
>         if (atomic_sub_return(count, &vma->pages_count) == 0) {
>                 vma->ops->clear_pages(vma);
>                 GEM_BUG_ON(vma->pages);
> -               if (vma->obj)
> -                       i915_gem_object_unpin_pages(vma->obj);
> +
> +               i915_gem_object_unpin_pages(vma->obj);
>         }
>         mutex_unlock(&vma->pages_mutex);
>  }
> @@ -875,7 +870,7 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
>         int err;
>
>  #ifdef CONFIG_PROVE_LOCKING
> -       if (debug_locks && !WARN_ON(!ww) && vma->resv)
> +       if (debug_locks && !WARN_ON(!ww))
>                 assert_vma_held(vma);
>  #endif
>
> @@ -983,7 +978,7 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
>
>         GEM_BUG_ON(!vma->pages);
>         err = i915_vma_bind(vma,
> -                           vma->obj ? vma->obj->cache_level : 0,
> +                           vma->obj->cache_level,
>                             flags, work);
>         if (err)
>                 goto err_remove;
> @@ -1037,7 +1032,7 @@ int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
>         GEM_BUG_ON(!i915_vma_is_ggtt(vma));
>
>  #ifdef CONFIG_LOCKDEP
> -       WARN_ON(!ww && vma->resv && dma_resv_held(vma->resv));
> +       WARN_ON(!ww && dma_resv_held(vma->resv));
>  #endif
>
>         do {
> @@ -1116,6 +1111,7 @@ void i915_vma_reopen(struct i915_vma *vma)
>  void i915_vma_release(struct kref *ref)
>  {
>         struct i915_vma *vma = container_of(ref, typeof(*vma), ref);
> +       struct drm_i915_gem_object *obj = vma->obj;
>
>         if (drm_mm_node_allocated(&vma->node)) {
>                 mutex_lock(&vma->vm->mutex);
> @@ -1126,15 +1122,11 @@ void i915_vma_release(struct kref *ref)
>         }
>         GEM_BUG_ON(i915_vma_is_active(vma));
>
> -       if (vma->obj) {
> -               struct drm_i915_gem_object *obj = vma->obj;
> -
> -               spin_lock(&obj->vma.lock);
> -               list_del(&vma->obj_link);
> -               if (!RB_EMPTY_NODE(&vma->obj_node))
> -                       rb_erase(&vma->obj_node, &obj->vma.tree);
> -               spin_unlock(&obj->vma.lock);
> -       }
> +       spin_lock(&obj->vma.lock);
> +       list_del(&vma->obj_link);
> +       if (!RB_EMPTY_NODE(&vma->obj_node))
> +               rb_erase(&vma->obj_node, &obj->vma.tree);
> +       spin_unlock(&obj->vma.lock);
>
>         __i915_vma_remove_closed(vma);
>         i915_vm_put(vma->vm);
> diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
> index b882fd7b5f99..423e0df81c87 100644
> --- a/drivers/gpu/drm/i915/i915_vma.h
> +++ b/drivers/gpu/drm/i915/i915_vma.h
> @@ -416,9 +416,6 @@ static inline void i915_vma_clear_scanout(struct i915_vma *vma)
>         list_for_each_entry(V, &(OBJ)->vma.list, obj_link)              \
>                 for_each_until(!i915_vma_is_ggtt(V))
>
> -struct i915_vma *i915_vma_alloc(void);
> -void i915_vma_free(struct i915_vma *vma);
> -
>  struct i915_vma *i915_vma_make_unshrinkable(struct i915_vma *vma);
>  void i915_vma_make_shrinkable(struct i915_vma *vma);
>  void i915_vma_make_purgeable(struct i915_vma *vma);
> --
> 2.33.0
>

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 10/28] drm/i915: Change shrink ordering to use locking around unbinding.
  2021-10-21 10:35   ` Maarten Lankhorst
  (?)
@ 2021-10-21 16:12   ` Matthew Auld
  2021-10-22 11:04     ` Maarten Lankhorst
  -1 siblings, 1 reply; 114+ messages in thread
From: Matthew Auld @ 2021-10-21 16:12 UTC (permalink / raw)
  To: Maarten Lankhorst
  Cc: Intel Graphics Development, ML dri-devel, Niranjana Vishwanathapura

On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
>
> Call drop_pages with the gem object lock held, instead of the other
> way around. This will allow us to drop the vma bindings with the
> gem object lock held.
>
> We plan to require the object lock for unpinning in the future,
> and this is an easy target.
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Reviewed-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_shrinker.c | 42 ++++++++++----------
>  1 file changed, 22 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
> index af3eb7fd951d..d3f29a66cb36 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
> @@ -36,8 +36,8 @@ static bool can_release_pages(struct drm_i915_gem_object *obj)
>         return swap_available() || obj->mm.madv == I915_MADV_DONTNEED;
>  }
>
> -static bool unsafe_drop_pages(struct drm_i915_gem_object *obj,
> -                             unsigned long shrink, bool trylock_vm)
> +static int drop_pages(struct drm_i915_gem_object *obj,
> +                      unsigned long shrink, bool trylock_vm)
>  {
>         unsigned long flags;
>
> @@ -208,26 +208,28 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww,
>
>                         spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
>
> -                       err = 0;
> -                       if (unsafe_drop_pages(obj, shrink, trylock_vm)) {
> -                               /* May arrive from get_pages on another bo */
> -                               if (!ww) {
> -                                       if (!i915_gem_object_trylock(obj))
> -                                               goto skip;
> -                               } else {
> -                                       err = i915_gem_object_lock(obj, ww);
> -                                       if (err)
> -                                               goto skip;
> -                               }
> -
> -                               if (!__i915_gem_object_put_pages(obj)) {
> -                                       try_to_writeback(obj, shrink);
> -                                       count += obj->base.size >> PAGE_SHIFT;
> -                               }
> -                               if (!ww)
> -                                       i915_gem_object_unlock(obj);
> +                       /* May arrive from get_pages on another bo */
> +                       if (!ww) {
> +                               if (!i915_gem_object_trylock(obj))
> +                                       goto skip;
> +                       } else {
> +                               err = i915_gem_object_lock(obj, ww);
> +                               if (err)
> +                                       goto skip;
>                         }
>
> +                       if (drop_pages(obj, shrink, trylock_vm) &&
> +                           !__i915_gem_object_put_pages(obj)) {
> +                               try_to_writeback(obj, shrink);
> +                               count += obj->base.size >> PAGE_SHIFT;
> +                       }
> +
> +                       if (dma_resv_test_signaled(obj->base.resv, true))
> +                               dma_resv_add_excl_fence(obj->base.resv, NULL);

I assume we want to rip out resv_prune here in the series, or
something? Instead of randomly adding this back here.

> +
> +                       if (!ww)
> +                               i915_gem_object_unlock(obj);
> +
>                         scanned += obj->base.size >> PAGE_SHIFT;
>  skip:
>                         i915_gem_object_put(obj);
> --
> 2.33.0
>

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 13/28] drm/i915: Remove pages_mutex and intel_gtt->vma_ops.set/clear_pages members
  2021-10-21 10:35   ` Maarten Lankhorst
  (?)
@ 2021-10-21 17:30   ` Matthew Auld
  2021-10-22 10:59     ` Matthew Auld
  -1 siblings, 1 reply; 114+ messages in thread
From: Matthew Auld @ 2021-10-21 17:30 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Intel Graphics Development, ML dri-devel

On Thu, 21 Oct 2021 at 11:36, Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
>
> Big delta, but boils down to moving set_pages to i915_vma.c, and removing
> the special handling, all callers use the defaults anyway. We only remap
> in ggtt, so default case will fall through.
>
> Because we still don't require locking in i915_vma_unpin(), handle this by
> using xchg in get_pages(), as it's locked with obj->mutex, and cmpxchg in
> unpin, which only fails if we race a against a new pin.
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_dpt.c      |   2 -
>  drivers/gpu/drm/i915/gt/gen6_ppgtt.c          |  15 -
>  drivers/gpu/drm/i915/gt/intel_ggtt.c          | 345 ----------------
>  drivers/gpu/drm/i915/gt/intel_gtt.c           |  13 -
>  drivers/gpu/drm/i915/gt/intel_gtt.h           |   7 -
>  drivers/gpu/drm/i915/gt/intel_ppgtt.c         |  12 -
>  drivers/gpu/drm/i915/i915_vma.c               | 388 ++++++++++++++++--
>  drivers/gpu/drm/i915/i915_vma.h               |   3 +
>  drivers/gpu/drm/i915/i915_vma_types.h         |   1 -
>  drivers/gpu/drm/i915/selftests/i915_gem_gtt.c |  12 +-
>  drivers/gpu/drm/i915/selftests/mock_gtt.c     |   4 -
>  11 files changed, 368 insertions(+), 434 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c
> index 8f7b1f7534a4..ef428f3fc538 100644
> --- a/drivers/gpu/drm/i915/display/intel_dpt.c
> +++ b/drivers/gpu/drm/i915/display/intel_dpt.c
> @@ -221,8 +221,6 @@ intel_dpt_create(struct intel_framebuffer *fb)
>
>         vm->vma_ops.bind_vma    = dpt_bind_vma;
>         vm->vma_ops.unbind_vma  = dpt_unbind_vma;
> -       vm->vma_ops.set_pages   = ggtt_set_pages;
> -       vm->vma_ops.clear_pages = clear_pages;
>
>         vm->pte_encode = gen8_ggtt_pte_encode;
>
> diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
> index 5caa1703716e..5c048b4ccd4d 100644
> --- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
> +++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
> @@ -270,19 +270,6 @@ static void gen6_ppgtt_cleanup(struct i915_address_space *vm)
>         free_pd(&ppgtt->base.vm, ppgtt->base.pd);
>  }
>
> -static int pd_vma_set_pages(struct i915_vma *vma)
> -{
> -       vma->pages = ERR_PTR(-ENODEV);
> -       return 0;
> -}
> -
> -static void pd_vma_clear_pages(struct i915_vma *vma)
> -{
> -       GEM_BUG_ON(!vma->pages);
> -
> -       vma->pages = NULL;
> -}
> -
>  static void pd_vma_bind(struct i915_address_space *vm,
>                         struct i915_vm_pt_stash *stash,
>                         struct i915_vma *vma,
> @@ -322,8 +309,6 @@ static void pd_vma_unbind(struct i915_address_space *vm, struct i915_vma *vma)
>  }
>
>  static const struct i915_vma_ops pd_vma_ops = {
> -       .set_pages = pd_vma_set_pages,
> -       .clear_pages = pd_vma_clear_pages,
>         .bind_vma = pd_vma_bind,
>         .unbind_vma = pd_vma_unbind,
>  };
> diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
> index f17383e76eb7..6da57199bb33 100644
> --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
> +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
> @@ -20,9 +20,6 @@
>  #include "intel_gtt.h"
>  #include "gen8_ppgtt.h"
>
> -static int
> -i915_get_ggtt_vma_pages(struct i915_vma *vma);
> -
>  static void i915_ggtt_color_adjust(const struct drm_mm_node *node,
>                                    unsigned long color,
>                                    u64 *start,
> @@ -875,21 +872,6 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, u64 size)
>         return 0;
>  }
>
> -int ggtt_set_pages(struct i915_vma *vma)
> -{
> -       int ret;
> -
> -       GEM_BUG_ON(vma->pages);
> -
> -       ret = i915_get_ggtt_vma_pages(vma);
> -       if (ret)
> -               return ret;
> -
> -       vma->page_sizes = vma->obj->mm.page_sizes;
> -
> -       return 0;
> -}
> -
>  static void gen6_gmch_remove(struct i915_address_space *vm)
>  {
>         struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
> @@ -950,8 +932,6 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
>
>         ggtt->vm.vma_ops.bind_vma    = ggtt_bind_vma;
>         ggtt->vm.vma_ops.unbind_vma  = ggtt_unbind_vma;
> -       ggtt->vm.vma_ops.set_pages   = ggtt_set_pages;
> -       ggtt->vm.vma_ops.clear_pages = clear_pages;
>
>         ggtt->vm.pte_encode = gen8_ggtt_pte_encode;
>
> @@ -1100,8 +1080,6 @@ static int gen6_gmch_probe(struct i915_ggtt *ggtt)
>
>         ggtt->vm.vma_ops.bind_vma    = ggtt_bind_vma;
>         ggtt->vm.vma_ops.unbind_vma  = ggtt_unbind_vma;
> -       ggtt->vm.vma_ops.set_pages   = ggtt_set_pages;
> -       ggtt->vm.vma_ops.clear_pages = clear_pages;
>
>         return ggtt_probe_common(ggtt, size);
>  }
> @@ -1145,8 +1123,6 @@ static int i915_gmch_probe(struct i915_ggtt *ggtt)
>
>         ggtt->vm.vma_ops.bind_vma    = ggtt_bind_vma;
>         ggtt->vm.vma_ops.unbind_vma  = ggtt_unbind_vma;
> -       ggtt->vm.vma_ops.set_pages   = ggtt_set_pages;
> -       ggtt->vm.vma_ops.clear_pages = clear_pages;
>
>         if (unlikely(ggtt->do_idle_maps))
>                 drm_notice(&i915->drm,
> @@ -1294,324 +1270,3 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
>
>         intel_ggtt_restore_fences(ggtt);
>  }
> -
> -static struct scatterlist *
> -rotate_pages(struct drm_i915_gem_object *obj, unsigned int offset,
> -            unsigned int width, unsigned int height,
> -            unsigned int src_stride, unsigned int dst_stride,
> -            struct sg_table *st, struct scatterlist *sg)
> -{
> -       unsigned int column, row;
> -       unsigned int src_idx;
> -
> -       for (column = 0; column < width; column++) {
> -               unsigned int left;
> -
> -               src_idx = src_stride * (height - 1) + column + offset;
> -               for (row = 0; row < height; row++) {
> -                       st->nents++;
> -                       /*
> -                        * We don't need the pages, but need to initialize
> -                        * the entries so the sg list can be happily traversed.
> -                        * The only thing we need are DMA addresses.
> -                        */
> -                       sg_set_page(sg, NULL, I915_GTT_PAGE_SIZE, 0);
> -                       sg_dma_address(sg) =
> -                               i915_gem_object_get_dma_address(obj, src_idx);
> -                       sg_dma_len(sg) = I915_GTT_PAGE_SIZE;
> -                       sg = sg_next(sg);
> -                       src_idx -= src_stride;
> -               }
> -
> -               left = (dst_stride - height) * I915_GTT_PAGE_SIZE;
> -
> -               if (!left)
> -                       continue;
> -
> -               st->nents++;
> -
> -               /*
> -                * The DE ignores the PTEs for the padding tiles, the sg entry
> -                * here is just a conenience to indicate how many padding PTEs
> -                * to insert at this spot.
> -                */
> -               sg_set_page(sg, NULL, left, 0);
> -               sg_dma_address(sg) = 0;
> -               sg_dma_len(sg) = left;
> -               sg = sg_next(sg);
> -       }
> -
> -       return sg;
> -}
> -
> -static noinline struct sg_table *
> -intel_rotate_pages(struct intel_rotation_info *rot_info,
> -                  struct drm_i915_gem_object *obj)
> -{
> -       unsigned int size = intel_rotation_info_size(rot_info);
> -       struct drm_i915_private *i915 = to_i915(obj->base.dev);
> -       struct sg_table *st;
> -       struct scatterlist *sg;
> -       int ret = -ENOMEM;
> -       int i;
> -
> -       /* Allocate target SG list. */
> -       st = kmalloc(sizeof(*st), GFP_KERNEL);
> -       if (!st)
> -               goto err_st_alloc;
> -
> -       ret = sg_alloc_table(st, size, GFP_KERNEL);
> -       if (ret)
> -               goto err_sg_alloc;
> -
> -       st->nents = 0;
> -       sg = st->sgl;
> -
> -       for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++)
> -               sg = rotate_pages(obj, rot_info->plane[i].offset,
> -                                 rot_info->plane[i].width, rot_info->plane[i].height,
> -                                 rot_info->plane[i].src_stride,
> -                                 rot_info->plane[i].dst_stride,
> -                                 st, sg);
> -
> -       return st;
> -
> -err_sg_alloc:
> -       kfree(st);
> -err_st_alloc:
> -
> -       drm_dbg(&i915->drm, "Failed to create rotated mapping for object size %zu! (%ux%u tiles, %u pages)\n",
> -               obj->base.size, rot_info->plane[0].width,
> -               rot_info->plane[0].height, size);
> -
> -       return ERR_PTR(ret);
> -}
> -
> -static struct scatterlist *
> -remap_pages(struct drm_i915_gem_object *obj,
> -           unsigned int offset, unsigned int alignment_pad,
> -           unsigned int width, unsigned int height,
> -           unsigned int src_stride, unsigned int dst_stride,
> -           struct sg_table *st, struct scatterlist *sg)
> -{
> -       unsigned int row;
> -
> -       if (alignment_pad) {
> -               st->nents++;
> -
> -               /*
> -                * The DE ignores the PTEs for the padding tiles, the sg entry
> -                * here is just a convenience to indicate how many padding PTEs
> -                * to insert at this spot.
> -                */
> -               sg_set_page(sg, NULL, alignment_pad * 4096, 0);
> -               sg_dma_address(sg) = 0;
> -               sg_dma_len(sg) = alignment_pad * 4096;
> -               sg = sg_next(sg);
> -       }
> -
> -       for (row = 0; row < height; row++) {
> -               unsigned int left = width * I915_GTT_PAGE_SIZE;
> -
> -               while (left) {
> -                       dma_addr_t addr;
> -                       unsigned int length;
> -
> -                       /*
> -                        * We don't need the pages, but need to initialize
> -                        * the entries so the sg list can be happily traversed.
> -                        * The only thing we need are DMA addresses.
> -                        */
> -
> -                       addr = i915_gem_object_get_dma_address_len(obj, offset, &length);
> -
> -                       length = min(left, length);
> -
> -                       st->nents++;
> -
> -                       sg_set_page(sg, NULL, length, 0);
> -                       sg_dma_address(sg) = addr;
> -                       sg_dma_len(sg) = length;
> -                       sg = sg_next(sg);
> -
> -                       offset += length / I915_GTT_PAGE_SIZE;
> -                       left -= length;
> -               }
> -
> -               offset += src_stride - width;
> -
> -               left = (dst_stride - width) * I915_GTT_PAGE_SIZE;
> -
> -               if (!left)
> -                       continue;
> -
> -               st->nents++;
> -
> -               /*
> -                * The DE ignores the PTEs for the padding tiles, the sg entry
> -                * here is just a conenience to indicate how many padding PTEs
> -                * to insert at this spot.
> -                */
> -               sg_set_page(sg, NULL, left, 0);
> -               sg_dma_address(sg) = 0;
> -               sg_dma_len(sg) = left;
> -               sg = sg_next(sg);
> -       }
> -
> -       return sg;
> -}
> -
> -static noinline struct sg_table *
> -intel_remap_pages(struct intel_remapped_info *rem_info,
> -                 struct drm_i915_gem_object *obj)
> -{
> -       unsigned int size = intel_remapped_info_size(rem_info);
> -       struct drm_i915_private *i915 = to_i915(obj->base.dev);
> -       struct sg_table *st;
> -       struct scatterlist *sg;
> -       unsigned int gtt_offset = 0;
> -       int ret = -ENOMEM;
> -       int i;
> -
> -       /* Allocate target SG list. */
> -       st = kmalloc(sizeof(*st), GFP_KERNEL);
> -       if (!st)
> -               goto err_st_alloc;
> -
> -       ret = sg_alloc_table(st, size, GFP_KERNEL);
> -       if (ret)
> -               goto err_sg_alloc;
> -
> -       st->nents = 0;
> -       sg = st->sgl;
> -
> -       for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
> -               unsigned int alignment_pad = 0;
> -
> -               if (rem_info->plane_alignment)
> -                       alignment_pad = ALIGN(gtt_offset, rem_info->plane_alignment) - gtt_offset;
> -
> -               sg = remap_pages(obj,
> -                                rem_info->plane[i].offset, alignment_pad,
> -                                rem_info->plane[i].width, rem_info->plane[i].height,
> -                                rem_info->plane[i].src_stride, rem_info->plane[i].dst_stride,
> -                                st, sg);
> -
> -               gtt_offset += alignment_pad +
> -                             rem_info->plane[i].dst_stride * rem_info->plane[i].height;
> -       }
> -
> -       i915_sg_trim(st);
> -
> -       return st;
> -
> -err_sg_alloc:
> -       kfree(st);
> -err_st_alloc:
> -
> -       drm_dbg(&i915->drm, "Failed to create remapped mapping for object size %zu! (%ux%u tiles, %u pages)\n",
> -               obj->base.size, rem_info->plane[0].width,
> -               rem_info->plane[0].height, size);
> -
> -       return ERR_PTR(ret);
> -}
> -
> -static noinline struct sg_table *
> -intel_partial_pages(const struct i915_ggtt_view *view,
> -                   struct drm_i915_gem_object *obj)
> -{
> -       struct sg_table *st;
> -       struct scatterlist *sg, *iter;
> -       unsigned int count = view->partial.size;
> -       unsigned int offset;
> -       int ret = -ENOMEM;
> -
> -       st = kmalloc(sizeof(*st), GFP_KERNEL);
> -       if (!st)
> -               goto err_st_alloc;
> -
> -       ret = sg_alloc_table(st, count, GFP_KERNEL);
> -       if (ret)
> -               goto err_sg_alloc;
> -
> -       iter = i915_gem_object_get_sg_dma(obj, view->partial.offset, &offset);
> -       GEM_BUG_ON(!iter);
> -
> -       sg = st->sgl;
> -       st->nents = 0;
> -       do {
> -               unsigned int len;
> -
> -               len = min(sg_dma_len(iter) - (offset << PAGE_SHIFT),
> -                         count << PAGE_SHIFT);
> -               sg_set_page(sg, NULL, len, 0);
> -               sg_dma_address(sg) =
> -                       sg_dma_address(iter) + (offset << PAGE_SHIFT);
> -               sg_dma_len(sg) = len;
> -
> -               st->nents++;
> -               count -= len >> PAGE_SHIFT;
> -               if (count == 0) {
> -                       sg_mark_end(sg);
> -                       i915_sg_trim(st); /* Drop any unused tail entries. */
> -
> -                       return st;
> -               }
> -
> -               sg = __sg_next(sg);
> -               iter = __sg_next(iter);
> -               offset = 0;
> -       } while (1);
> -
> -err_sg_alloc:
> -       kfree(st);
> -err_st_alloc:
> -       return ERR_PTR(ret);
> -}
> -
> -static int
> -i915_get_ggtt_vma_pages(struct i915_vma *vma)
> -{
> -       int ret;
> -
> -       /*
> -        * The vma->pages are only valid within the lifespan of the borrowed
> -        * obj->mm.pages. When the obj->mm.pages sg_table is regenerated, so
> -        * must be the vma->pages. A simple rule is that vma->pages must only
> -        * be accessed when the obj->mm.pages are pinned.
> -        */
> -       GEM_BUG_ON(!i915_gem_object_has_pinned_pages(vma->obj));
> -
> -       switch (vma->ggtt_view.type) {
> -       default:
> -               GEM_BUG_ON(vma->ggtt_view.type);
> -               fallthrough;
> -       case I915_GGTT_VIEW_NORMAL:
> -               vma->pages = vma->obj->mm.pages;
> -               return 0;
> -
> -       case I915_GGTT_VIEW_ROTATED:
> -               vma->pages =
> -                       intel_rotate_pages(&vma->ggtt_view.rotated, vma->obj);
> -               break;
> -
> -       case I915_GGTT_VIEW_REMAPPED:
> -               vma->pages =
> -                       intel_remap_pages(&vma->ggtt_view.remapped, vma->obj);
> -               break;
> -
> -       case I915_GGTT_VIEW_PARTIAL:
> -               vma->pages = intel_partial_pages(&vma->ggtt_view, vma->obj);
> -               break;
> -       }
> -
> -       ret = 0;
> -       if (IS_ERR(vma->pages)) {
> -               ret = PTR_ERR(vma->pages);
> -               vma->pages = NULL;
> -               drm_err(&vma->vm->i915->drm,
> -                       "Failed to get pages for VMA view type %u (%d)!\n",
> -                       vma->ggtt_view.type, ret);
> -       }
> -       return ret;
> -}
> diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c b/drivers/gpu/drm/i915/gt/intel_gtt.c
> index 67d14afa6623..12eed5fcb17a 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gtt.c
> +++ b/drivers/gpu/drm/i915/gt/intel_gtt.c
> @@ -221,19 +221,6 @@ void i915_address_space_init(struct i915_address_space *vm, int subclass)
>         INIT_LIST_HEAD(&vm->bound_list);
>  }
>
> -void clear_pages(struct i915_vma *vma)
> -{
> -       GEM_BUG_ON(!vma->pages);
> -
> -       if (vma->pages != vma->obj->mm.pages) {
> -               sg_free_table(vma->pages);
> -               kfree(vma->pages);
> -       }
> -       vma->pages = NULL;
> -
> -       memset(&vma->page_sizes, 0, sizeof(vma->page_sizes));
> -}
> -
>  void *__px_vaddr(struct drm_i915_gem_object *p)
>  {
>         enum i915_map_type type;
> diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.h b/drivers/gpu/drm/i915/gt/intel_gtt.h
> index bc6750263359..306e7645fdc5 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gtt.h
> +++ b/drivers/gpu/drm/i915/gt/intel_gtt.h
> @@ -206,9 +206,6 @@ struct i915_vma_ops {
>          */
>         void (*unbind_vma)(struct i915_address_space *vm,
>                            struct i915_vma *vma);
> -
> -       int (*set_pages)(struct i915_vma *vma);
> -       void (*clear_pages)(struct i915_vma *vma);
>  };
>
>  struct i915_address_space {
> @@ -594,10 +591,6 @@ release_pd_entry(struct i915_page_directory * const pd,
>                  const struct drm_i915_gem_object * const scratch);
>  void gen6_ggtt_invalidate(struct i915_ggtt *ggtt);
>
> -int ggtt_set_pages(struct i915_vma *vma);
> -int ppgtt_set_pages(struct i915_vma *vma);
> -void clear_pages(struct i915_vma *vma);
> -
>  void ppgtt_bind_vma(struct i915_address_space *vm,
>                     struct i915_vm_pt_stash *stash,
>                     struct i915_vma *vma,
> diff --git a/drivers/gpu/drm/i915/gt/intel_ppgtt.c b/drivers/gpu/drm/i915/gt/intel_ppgtt.c
> index 4396bfd630d8..083b3090c69c 100644
> --- a/drivers/gpu/drm/i915/gt/intel_ppgtt.c
> +++ b/drivers/gpu/drm/i915/gt/intel_ppgtt.c
> @@ -289,16 +289,6 @@ void i915_vm_free_pt_stash(struct i915_address_space *vm,
>         }
>  }
>
> -int ppgtt_set_pages(struct i915_vma *vma)
> -{
> -       GEM_BUG_ON(vma->pages);
> -
> -       vma->pages = vma->obj->mm.pages;
> -       vma->page_sizes = vma->obj->mm.page_sizes;
> -
> -       return 0;
> -}
> -
>  void ppgtt_init(struct i915_ppgtt *ppgtt, struct intel_gt *gt,
>                 unsigned long lmem_pt_obj_flags)
>  {
> @@ -315,6 +305,4 @@ void ppgtt_init(struct i915_ppgtt *ppgtt, struct intel_gt *gt,
>
>         ppgtt->vm.vma_ops.bind_vma    = ppgtt_bind_vma;
>         ppgtt->vm.vma_ops.unbind_vma  = ppgtt_unbind_vma;
> -       ppgtt->vm.vma_ops.set_pages   = ppgtt_set_pages;
> -       ppgtt->vm.vma_ops.clear_pages = clear_pages;
>  }
> diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
> index ac09b685678a..bacc8d68e495 100644
> --- a/drivers/gpu/drm/i915/i915_vma.c
> +++ b/drivers/gpu/drm/i915/i915_vma.c
> @@ -112,7 +112,6 @@ vma_create(struct drm_i915_gem_object *obj,
>                 return ERR_PTR(-ENOMEM);
>
>         kref_init(&vma->ref);
> -       mutex_init(&vma->pages_mutex);
>         vma->vm = i915_vm_get(vm);
>         vma->ops = &vm->vma_ops;
>         vma->obj = obj;
> @@ -789,10 +788,343 @@ static bool try_qad_pin(struct i915_vma *vma, unsigned int flags)
>         return pinned;
>  }
>
> -static int vma_get_pages(struct i915_vma *vma)
> +
> +
> +static struct scatterlist *
> +rotate_pages(struct drm_i915_gem_object *obj, unsigned int offset,
> +            unsigned int width, unsigned int height,
> +            unsigned int src_stride, unsigned int dst_stride,
> +            struct sg_table *st, struct scatterlist *sg)
>  {
> -       int err = 0;
> -       bool pinned_pages = true;
> +       unsigned int column, row;
> +       unsigned int src_idx;
> +
> +       for (column = 0; column < width; column++) {
> +               unsigned int left;
> +
> +               src_idx = src_stride * (height - 1) + column + offset;
> +               for (row = 0; row < height; row++) {
> +                       st->nents++;
> +                       /*
> +                        * We don't need the pages, but need to initialize
> +                        * the entries so the sg list can be happily traversed.
> +                        * The only thing we need are DMA addresses.
> +                        */
> +                       sg_set_page(sg, NULL, I915_GTT_PAGE_SIZE, 0);
> +                       sg_dma_address(sg) =
> +                               i915_gem_object_get_dma_address(obj, src_idx);
> +                       sg_dma_len(sg) = I915_GTT_PAGE_SIZE;
> +                       sg = sg_next(sg);
> +                       src_idx -= src_stride;
> +               }
> +
> +               left = (dst_stride - height) * I915_GTT_PAGE_SIZE;
> +
> +               if (!left)
> +                       continue;
> +
> +               st->nents++;
> +
> +               /*
> +                * The DE ignores the PTEs for the padding tiles, the sg entry
> +                * here is just a conenience to indicate how many padding PTEs
> +                * to insert at this spot.
> +                */
> +               sg_set_page(sg, NULL, left, 0);
> +               sg_dma_address(sg) = 0;
> +               sg_dma_len(sg) = left;
> +               sg = sg_next(sg);
> +       }
> +
> +       return sg;
> +}
> +
> +static noinline struct sg_table *
> +intel_rotate_pages(struct intel_rotation_info *rot_info,
> +                  struct drm_i915_gem_object *obj)
> +{
> +       unsigned int size = intel_rotation_info_size(rot_info);
> +       struct drm_i915_private *i915 = to_i915(obj->base.dev);
> +       struct sg_table *st;
> +       struct scatterlist *sg;
> +       int ret = -ENOMEM;
> +       int i;
> +
> +       /* Allocate target SG list. */
> +       st = kmalloc(sizeof(*st), GFP_KERNEL);
> +       if (!st)
> +               goto err_st_alloc;
> +
> +       ret = sg_alloc_table(st, size, GFP_KERNEL);
> +       if (ret)
> +               goto err_sg_alloc;
> +
> +       st->nents = 0;
> +       sg = st->sgl;
> +
> +       for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++)
> +               sg = rotate_pages(obj, rot_info->plane[i].offset,
> +                                 rot_info->plane[i].width, rot_info->plane[i].height,
> +                                 rot_info->plane[i].src_stride,
> +                                 rot_info->plane[i].dst_stride,
> +                                 st, sg);
> +
> +       return st;
> +
> +err_sg_alloc:
> +       kfree(st);
> +err_st_alloc:
> +
> +       drm_dbg(&i915->drm, "Failed to create rotated mapping for object size %zu! (%ux%u tiles, %u pages)\n",
> +               obj->base.size, rot_info->plane[0].width,
> +               rot_info->plane[0].height, size);
> +
> +       return ERR_PTR(ret);
> +}
> +
> +static struct scatterlist *
> +remap_pages(struct drm_i915_gem_object *obj,
> +           unsigned int offset, unsigned int alignment_pad,
> +           unsigned int width, unsigned int height,
> +           unsigned int src_stride, unsigned int dst_stride,
> +           struct sg_table *st, struct scatterlist *sg)
> +{
> +       unsigned int row;
> +
> +       if (alignment_pad) {
> +               st->nents++;
> +
> +               /*
> +                * The DE ignores the PTEs for the padding tiles, the sg entry
> +                * here is just a convenience to indicate how many padding PTEs
> +                * to insert at this spot.
> +                */
> +               sg_set_page(sg, NULL, alignment_pad * 4096, 0);
> +               sg_dma_address(sg) = 0;
> +               sg_dma_len(sg) = alignment_pad * 4096;
> +               sg = sg_next(sg);
> +       }
> +
> +       for (row = 0; row < height; row++) {
> +               unsigned int left = width * I915_GTT_PAGE_SIZE;
> +
> +               while (left) {
> +                       dma_addr_t addr;
> +                       unsigned int length;
> +
> +                       /*
> +                        * We don't need the pages, but need to initialize
> +                        * the entries so the sg list can be happily traversed.
> +                        * The only thing we need are DMA addresses.
> +                        */
> +
> +                       addr = i915_gem_object_get_dma_address_len(obj, offset, &length);
> +
> +                       length = min(left, length);
> +
> +                       st->nents++;
> +
> +                       sg_set_page(sg, NULL, length, 0);
> +                       sg_dma_address(sg) = addr;
> +                       sg_dma_len(sg) = length;
> +                       sg = sg_next(sg);
> +
> +                       offset += length / I915_GTT_PAGE_SIZE;
> +                       left -= length;
> +               }
> +
> +               offset += src_stride - width;
> +
> +               left = (dst_stride - width) * I915_GTT_PAGE_SIZE;
> +
> +               if (!left)
> +                       continue;
> +
> +               st->nents++;
> +
> +               /*
> +                * The DE ignores the PTEs for the padding tiles, the sg entry
> +                * here is just a conenience to indicate how many padding PTEs
> +                * to insert at this spot.
> +                */
> +               sg_set_page(sg, NULL, left, 0);
> +               sg_dma_address(sg) = 0;
> +               sg_dma_len(sg) = left;
> +               sg = sg_next(sg);
> +       }
> +
> +       return sg;
> +}
> +
> +static noinline struct sg_table *
> +intel_remap_pages(struct intel_remapped_info *rem_info,
> +                 struct drm_i915_gem_object *obj)
> +{
> +       unsigned int size = intel_remapped_info_size(rem_info);
> +       struct drm_i915_private *i915 = to_i915(obj->base.dev);
> +       struct sg_table *st;
> +       struct scatterlist *sg;
> +       unsigned int gtt_offset = 0;
> +       int ret = -ENOMEM;
> +       int i;
> +
> +       /* Allocate target SG list. */
> +       st = kmalloc(sizeof(*st), GFP_KERNEL);
> +       if (!st)
> +               goto err_st_alloc;
> +
> +       ret = sg_alloc_table(st, size, GFP_KERNEL);
> +       if (ret)
> +               goto err_sg_alloc;
> +
> +       st->nents = 0;
> +       sg = st->sgl;
> +
> +       for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
> +               unsigned int alignment_pad = 0;
> +
> +               if (rem_info->plane_alignment)
> +                       alignment_pad = ALIGN(gtt_offset, rem_info->plane_alignment) - gtt_offset;
> +
> +               sg = remap_pages(obj,
> +                                rem_info->plane[i].offset, alignment_pad,
> +                                rem_info->plane[i].width, rem_info->plane[i].height,
> +                                rem_info->plane[i].src_stride, rem_info->plane[i].dst_stride,
> +                                st, sg);
> +
> +               gtt_offset += alignment_pad +
> +                             rem_info->plane[i].dst_stride * rem_info->plane[i].height;
> +       }
> +
> +       i915_sg_trim(st);
> +
> +       return st;
> +
> +err_sg_alloc:
> +       kfree(st);
> +err_st_alloc:
> +
> +       drm_dbg(&i915->drm, "Failed to create remapped mapping for object size %zu! (%ux%u tiles, %u pages)\n",
> +               obj->base.size, rem_info->plane[0].width,
> +               rem_info->plane[0].height, size);
> +
> +       return ERR_PTR(ret);
> +}
> +
> +static noinline struct sg_table *
> +intel_partial_pages(const struct i915_ggtt_view *view,
> +                   struct drm_i915_gem_object *obj)
> +{
> +       struct sg_table *st;
> +       struct scatterlist *sg, *iter;
> +       unsigned int count = view->partial.size;
> +       unsigned int offset;
> +       int ret = -ENOMEM;
> +
> +       st = kmalloc(sizeof(*st), GFP_KERNEL);
> +       if (!st)
> +               goto err_st_alloc;
> +
> +       ret = sg_alloc_table(st, count, GFP_KERNEL);
> +       if (ret)
> +               goto err_sg_alloc;
> +
> +       iter = i915_gem_object_get_sg_dma(obj, view->partial.offset, &offset);
> +       GEM_BUG_ON(!iter);
> +
> +       sg = st->sgl;
> +       st->nents = 0;
> +       do {
> +               unsigned int len;
> +
> +               len = min(sg_dma_len(iter) - (offset << PAGE_SHIFT),
> +                         count << PAGE_SHIFT);
> +               sg_set_page(sg, NULL, len, 0);
> +               sg_dma_address(sg) =
> +                       sg_dma_address(iter) + (offset << PAGE_SHIFT);
> +               sg_dma_len(sg) = len;
> +
> +               st->nents++;
> +               count -= len >> PAGE_SHIFT;
> +               if (count == 0) {
> +                       sg_mark_end(sg);
> +                       i915_sg_trim(st); /* Drop any unused tail entries. */
> +
> +                       return st;
> +               }
> +
> +               sg = __sg_next(sg);
> +               iter = __sg_next(iter);
> +               offset = 0;
> +       } while (1);
> +
> +err_sg_alloc:
> +       kfree(st);
> +err_st_alloc:
> +       return ERR_PTR(ret);
> +}
> +
> +static int
> +__i915_vma_get_pages(struct i915_vma *vma)
> +{
> +       struct sg_table *pages;
> +       int ret;
> +
> +       /*
> +        * The vma->pages are only valid within the lifespan of the borrowed
> +        * obj->mm.pages. When the obj->mm.pages sg_table is regenerated, so
> +        * must be the vma->pages. A simple rule is that vma->pages must only
> +        * be accessed when the obj->mm.pages are pinned.
> +        */
> +       GEM_BUG_ON(!i915_gem_object_has_pinned_pages(vma->obj));
> +
> +       switch (vma->ggtt_view.type) {
> +       default:
> +               GEM_BUG_ON(vma->ggtt_view.type);
> +               fallthrough;
> +       case I915_GGTT_VIEW_NORMAL:
> +               pages = vma->obj->mm.pages;
> +               break;
> +
> +       case I915_GGTT_VIEW_ROTATED:
> +               pages =
> +                       intel_rotate_pages(&vma->ggtt_view.rotated, vma->obj);
> +               break;
> +
> +       case I915_GGTT_VIEW_REMAPPED:
> +               pages =
> +                       intel_remap_pages(&vma->ggtt_view.remapped, vma->obj);
> +               break;
> +
> +       case I915_GGTT_VIEW_PARTIAL:
> +               pages = intel_partial_pages(&vma->ggtt_view, vma->obj);
> +               break;
> +       }
> +
> +       ret = 0;
> +       /* gen6 ppgtt doesn't have backing pages, special-case it */
> +       if (IS_ERR(pages) && pages != ERR_PTR(-ENODEV)) {

Where does this -ENODEV come from? AFAIK for the gen6 thing mm.pages =
ZERO_SIZE_PTR. Also, just checking, I assume we always hit the
VIEW_NORMAL for that?

> +               ret = PTR_ERR(pages);
> +               pages = NULL;
> +               drm_err(&vma->vm->i915->drm,
> +                       "Failed to get pages for VMA view type %u (%d)!\n",
> +                       vma->ggtt_view.type, ret);

Can we just return here?

> +       }
> +
> +       pages = xchg(&vma->pages, pages);
> +
> +       /* did we race against a put_pages? */
> +       if (pages && pages != vma->obj->mm.pages) {
> +               sg_free_table(vma->pages);
> +               kfree(vma->pages);
> +       }

What is this race exactly, can we add some more details here please?
So we can more easily evaluate the lockless trickery here.

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 14/28] drm/i915: Take object lock in i915_ggtt_pin if ww is not set
  2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
  (?)
@ 2021-10-21 17:39   ` Matthew Auld
  2021-11-29 12:46     ` Maarten Lankhorst
  -1 siblings, 1 reply; 114+ messages in thread
From: Matthew Auld @ 2021-10-21 17:39 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Intel Graphics Development, ML dri-devel

On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
>
> i915_vma_wait_for_bind needs the vma lock held, fix the caller.
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_vma.c | 40 +++++++++++++++++++++++----------
>  1 file changed, 28 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
> index bacc8d68e495..2877dcd62acb 100644
> --- a/drivers/gpu/drm/i915/i915_vma.c
> +++ b/drivers/gpu/drm/i915/i915_vma.c
> @@ -1348,23 +1348,15 @@ static void flush_idle_contexts(struct intel_gt *gt)
>         intel_gt_wait_for_idle(gt, MAX_SCHEDULE_TIMEOUT);
>  }
>
> -int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
> -                 u32 align, unsigned int flags)
> +static int __i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
> +                          u32 align, unsigned int flags)
>  {
>         struct i915_address_space *vm = vma->vm;
>         int err;
>
> -       GEM_BUG_ON(!i915_vma_is_ggtt(vma));
> -
> -#ifdef CONFIG_LOCKDEP
> -       WARN_ON(!ww && dma_resv_held(vma->obj->base.resv));
> -#endif
> -
>         do {
> -               if (ww)
> -                       err = i915_vma_pin_ww(vma, ww, 0, align, flags | PIN_GLOBAL);
> -               else
> -                       err = i915_vma_pin(vma, 0, align, flags | PIN_GLOBAL);
> +               err = i915_vma_pin_ww(vma, ww, 0, align, flags | PIN_GLOBAL);
> +
>                 if (err != -ENOSPC) {
>                         if (!err) {
>                                 err = i915_vma_wait_for_bind(vma);
> @@ -1383,6 +1375,30 @@ int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
>         } while (1);
>  }
>
> +int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
> +                 u32 align, unsigned int flags)
> +{
> +       struct i915_gem_ww_ctx _ww;
> +       int err;
> +
> +       GEM_BUG_ON(!i915_vma_is_ggtt(vma));
> +
> +       if (ww)
> +               return __i915_ggtt_pin(vma, ww, align, flags);
> +
> +#ifdef CONFIG_LOCKDEP
> +       WARN_ON(dma_resv_held(vma->obj->base.resv));

Hmm, so this can't trigger, say if shrinker grabs the lock, or some
other concurrent user?

> +#endif
> +
> +       for_i915_gem_ww(&_ww, err, true) {
> +               err = i915_gem_object_lock(vma->obj, &_ww);
> +               if (!err)
> +                       err = __i915_ggtt_pin(vma, &_ww, align, flags);
> +       }
> +
> +       return err;
> +}
> +
>  static void __vma_close(struct i915_vma *vma, struct intel_gt *gt)
>  {
>         /*
> --
> 2.33.0
>

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 15/28] drm/i915: Add lock for unbinding to i915_gem_object_ggtt_pin_ww
  2021-10-21 10:35   ` Maarten Lankhorst
  (?)
@ 2021-10-21 17:48   ` Matthew Auld
  2021-11-29 13:25     ` Maarten Lankhorst
  -1 siblings, 1 reply; 114+ messages in thread
From: Matthew Auld @ 2021-10-21 17:48 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Intel Graphics Development, ML dri-devel

On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

Needs a proper commit message.

> ---
>  drivers/gpu/drm/i915/i915_gem.c | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 981e383d1a5d..6aa9e465b48e 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -931,7 +931,14 @@ i915_gem_object_ggtt_pin_ww(struct drm_i915_gem_object *obj,
>                         goto new_vma;
>                 }
>
> -               ret = i915_vma_unbind(vma);
> +               ret = 0;
> +               if (!ww)
> +                       ret = i915_gem_object_lock_interruptible(obj, NULL);
> +               if (!ret) {
> +                       ret = i915_vma_unbind(vma);
> +                       if (!ww)
> +                               i915_gem_object_unlock(obj);
> +               }

There is also a wait_for_bind below. Do we need the lock for that also?

>                 if (ret)
>                         return ERR_PTR(ret);
>         }
> --
> 2.33.0
>

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 16/28] drm/i915: Rework context handling in hugepages selftests
  2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
  (?)
@ 2021-10-21 17:55   ` Matthew Auld
  -1 siblings, 0 replies; 114+ messages in thread
From: Matthew Auld @ 2021-10-21 17:55 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Intel Graphics Development, ML dri-devel

On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
>
> In the next commit, we don't evict when refcount = 0, so we need to
> call drain freed objects, because we want to pin new bo's in the same
> place, causing a test failure.
>
> Furthermore, since each subtest is separated, it's a lot better to use
> i915_live_selftests, so each subtest starts with a clean slate, and a
> clean address space.
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 18/28] drm/i915: Take trylock during eviction, v2.
  2021-10-21 10:35   ` Maarten Lankhorst
  (?)
@ 2021-10-21 17:59   ` Matthew Auld
  2021-10-22  8:44       ` Maarten Lankhorst
  -1 siblings, 1 reply; 114+ messages in thread
From: Matthew Auld @ 2021-10-21 17:59 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Intel Graphics Development, ML dri-devel

On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
>
> Now that freeing objects takes the object lock when destroying the
> backing pages, we can confidently take the object lock even for dead
> objects.
>
> Use this fact to take the object lock in the shrinker, without requiring
> a reference to the object, so all calls to unbind take the object lock.
>
> This is the last step to requiring the object lock for vma_unbind.

For the eviction what is the reason for only trylock here, assuming we
are given a ww context? Maybe the back off is annoying? And the full
lock version comes later?

>
> Changes since v1:
> - No longer require the refcount, as every freed object now holds the lock
>   when unbinding VMA's.
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_shrinker.c |  6 ++++
>  drivers/gpu/drm/i915/i915_gem_evict.c        | 34 +++++++++++++++++---
>  2 files changed, 35 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
> index d3f29a66cb36..34c12e5983eb 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
> @@ -403,12 +403,18 @@ i915_gem_shrinker_vmap(struct notifier_block *nb, unsigned long event, void *ptr
>         list_for_each_entry_safe(vma, next,
>                                  &i915->ggtt.vm.bound_list, vm_link) {
>                 unsigned long count = vma->node.size >> PAGE_SHIFT;
> +               struct drm_i915_gem_object *obj = vma->obj;
>
>                 if (!vma->iomap || i915_vma_is_active(vma))
>                         continue;
>
> +               if (!i915_gem_object_trylock(obj))
> +                       continue;
> +
>                 if (__i915_vma_unbind(vma) == 0)
>                         freed_pages += count;
> +
> +               i915_gem_object_unlock(obj);
>         }
>         mutex_unlock(&i915->ggtt.vm.mutex);
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
> index 2b73ddb11c66..286efa462eca 100644
> --- a/drivers/gpu/drm/i915/i915_gem_evict.c
> +++ b/drivers/gpu/drm/i915/i915_gem_evict.c
> @@ -58,6 +58,9 @@ mark_free(struct drm_mm_scan *scan,
>         if (i915_vma_is_pinned(vma))
>                 return false;
>
> +       if (!i915_gem_object_trylock(vma->obj))
> +               return false;
> +
>         list_add(&vma->evict_link, unwind);
>         return drm_mm_scan_add_block(scan, &vma->node);
>  }
> @@ -178,6 +181,7 @@ i915_gem_evict_something(struct i915_address_space *vm,
>         list_for_each_entry_safe(vma, next, &eviction_list, evict_link) {
>                 ret = drm_mm_scan_remove_block(&scan, &vma->node);
>                 BUG_ON(ret);
> +               i915_gem_object_unlock(vma->obj);
>         }
>
>         /*
> @@ -222,10 +226,12 @@ i915_gem_evict_something(struct i915_address_space *vm,
>          * of any of our objects, thus corrupting the list).
>          */
>         list_for_each_entry_safe(vma, next, &eviction_list, evict_link) {
> -               if (drm_mm_scan_remove_block(&scan, &vma->node))
> +               if (drm_mm_scan_remove_block(&scan, &vma->node)) {
>                         __i915_vma_pin(vma);
> -               else
> +               } else {
>                         list_del(&vma->evict_link);
> +                       i915_gem_object_unlock(vma->obj);
> +               }
>         }
>
>         /* Unbinding will emit any required flushes */
> @@ -234,16 +240,22 @@ i915_gem_evict_something(struct i915_address_space *vm,
>                 __i915_vma_unpin(vma);
>                 if (ret == 0)
>                         ret = __i915_vma_unbind(vma);
> +
> +               i915_gem_object_unlock(vma->obj);
>         }
>
>         while (ret == 0 && (node = drm_mm_scan_color_evict(&scan))) {
>                 vma = container_of(node, struct i915_vma, node);
>
> +
>                 /* If we find any non-objects (!vma), we cannot evict them */
> -               if (vma->node.color != I915_COLOR_UNEVICTABLE)
> +               if (vma->node.color != I915_COLOR_UNEVICTABLE &&
> +                   i915_gem_object_trylock(vma->obj)) {
>                         ret = __i915_vma_unbind(vma);
> -               else
> -                       ret = -ENOSPC; /* XXX search failed, try again? */
> +                       i915_gem_object_unlock(vma->obj);
> +               } else {
> +                       ret = -ENOSPC;
> +               }
>         }
>
>         return ret;
> @@ -333,6 +345,11 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
>                         break;
>                 }
>
> +               if (!i915_gem_object_trylock(vma->obj)) {
> +                       ret = -ENOSPC;
> +                       break;
> +               }
> +
>                 /*
>                  * Never show fear in the face of dragons!
>                  *
> @@ -350,6 +367,8 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
>                 __i915_vma_unpin(vma);
>                 if (ret == 0)
>                         ret = __i915_vma_unbind(vma);
> +
> +               i915_gem_object_unlock(vma->obj);
>         }
>
>         return ret;
> @@ -393,6 +412,9 @@ int i915_gem_evict_vm(struct i915_address_space *vm)
>                         if (i915_vma_is_pinned(vma))
>                                 continue;
>
> +                       if (!i915_gem_object_trylock(vma->obj))
> +                               continue;
> +
>                         __i915_vma_pin(vma);
>                         list_add(&vma->evict_link, &eviction_list);
>                 }
> @@ -406,6 +428,8 @@ int i915_gem_evict_vm(struct i915_address_space *vm)
>                                 ret = __i915_vma_unbind(vma);
>                         if (ret != -EINTR) /* "Get me out of here!" */
>                                 ret = 0;
> +
> +                       i915_gem_object_unlock(vma->obj);
>                 }
>         } while (ret == 0);
>
> --
> 2.33.0
>

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 19/28] drm/i915: Pass trylock context to callers
  2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
  (?)
@ 2021-10-21 18:03   ` Matthew Auld
  2021-10-22  8:52     ` Maarten Lankhorst
  -1 siblings, 1 reply; 114+ messages in thread
From: Matthew Auld @ 2021-10-21 18:03 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Intel Graphics Development, ML dri-devel

On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

Needs a proper commit message.

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 16/28] drm/i915: Rework context handling in hugepages selftests
  2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-22  6:51     ` kernel test robot
  -1 siblings, 0 replies; 114+ messages in thread
From: kernel test robot @ 2021-10-22  6:51 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx; +Cc: kbuild-all, dri-devel, Maarten Lankhorst

[-- Attachment #1: Type: text/plain, Size: 2283 bytes --]

Hi Maarten,

I love your patch! Perhaps something to improve:

[auto build test WARNING on drm-tip/drm-tip]
[cannot apply to drm-intel/for-linux-next drm-exynos/exynos-drm-next tegra-drm/drm/tegra/for-next airlied/drm-next v5.15-rc6 next-20211021]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Maarten-Lankhorst/drm-i915-Fix-i915_request-fence-wait-semantics/20211021-183839
base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
config: x86_64-randconfig-a016-20211021 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/0day-ci/linux/commit/536df9470ecdddde67095f4f40f37752d944c343
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Maarten-Lankhorst/drm-i915-Fix-i915_request-fence-wait-semantics/20211021-183839
        git checkout 536df9470ecdddde67095f4f40f37752d944c343
        # save the attached .config to linux build tree
        make W=1 ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from drivers/gpu/drm/i915/gem/i915_gem_object.c:737:
>> drivers/gpu/drm/i915/gem/selftests/huge_pages.c:25:26: warning: no previous prototype for 'hugepage_ctx' [-Wmissing-prototypes]
      25 | struct i915_gem_context *hugepage_ctx(struct drm_i915_private *i915, struct file *file)
         |                          ^~~~~~~~~~~~


vim +/hugepage_ctx +25 drivers/gpu/drm/i915/gem/selftests/huge_pages.c

    24	
  > 25	struct i915_gem_context *hugepage_ctx(struct drm_i915_private *i915, struct file *file)
    26	{
    27		struct i915_gem_context *ctx = live_context(i915, file);
    28		struct i915_address_space *vm;
    29	
    30		if (IS_ERR(ctx))
    31			return ctx;
    32	
    33		vm = ctx->vm;
    34		if (vm)
    35			WRITE_ONCE(vm->scrub_64K, true);
    36	
    37		return ctx;
    38	}
    39	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 38432 bytes --]

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 16/28] drm/i915: Rework context handling in hugepages selftests
@ 2021-10-22  6:51     ` kernel test robot
  0 siblings, 0 replies; 114+ messages in thread
From: kernel test robot @ 2021-10-22  6:51 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 2340 bytes --]

Hi Maarten,

I love your patch! Perhaps something to improve:

[auto build test WARNING on drm-tip/drm-tip]
[cannot apply to drm-intel/for-linux-next drm-exynos/exynos-drm-next tegra-drm/drm/tegra/for-next airlied/drm-next v5.15-rc6 next-20211021]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Maarten-Lankhorst/drm-i915-Fix-i915_request-fence-wait-semantics/20211021-183839
base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
config: x86_64-randconfig-a016-20211021 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/0day-ci/linux/commit/536df9470ecdddde67095f4f40f37752d944c343
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Maarten-Lankhorst/drm-i915-Fix-i915_request-fence-wait-semantics/20211021-183839
        git checkout 536df9470ecdddde67095f4f40f37752d944c343
        # save the attached .config to linux build tree
        make W=1 ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from drivers/gpu/drm/i915/gem/i915_gem_object.c:737:
>> drivers/gpu/drm/i915/gem/selftests/huge_pages.c:25:26: warning: no previous prototype for 'hugepage_ctx' [-Wmissing-prototypes]
      25 | struct i915_gem_context *hugepage_ctx(struct drm_i915_private *i915, struct file *file)
         |                          ^~~~~~~~~~~~


vim +/hugepage_ctx +25 drivers/gpu/drm/i915/gem/selftests/huge_pages.c

    24	
  > 25	struct i915_gem_context *hugepage_ctx(struct drm_i915_private *i915, struct file *file)
    26	{
    27		struct i915_gem_context *ctx = live_context(i915, file);
    28		struct i915_address_space *vm;
    29	
    30		if (IS_ERR(ctx))
    31			return ctx;
    32	
    33		vm = ctx->vm;
    34		if (vm)
    35			WRITE_ONCE(vm->scrub_64K, true);
    36	
    37		return ctx;
    38	}
    39	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 38432 bytes --]

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 16/28] drm/i915: Rework context handling in hugepages selftests
  2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-22  7:21     ` kernel test robot
  -1 siblings, 0 replies; 114+ messages in thread
From: kernel test robot @ 2021-10-22  7:21 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx; +Cc: kbuild-all, dri-devel, Maarten Lankhorst

[-- Attachment #1: Type: text/plain, Size: 2324 bytes --]

Hi Maarten,

I love your patch! Yet something to improve:

[auto build test ERROR on drm-tip/drm-tip]
[cannot apply to drm-intel/for-linux-next drm-exynos/exynos-drm-next tegra-drm/drm/tegra/for-next airlied/drm-next v5.15-rc6 next-20211021]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Maarten-Lankhorst/drm-i915-Fix-i915_request-fence-wait-semantics/20211021-183839
base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
config: x86_64-randconfig-a011-20211021 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/0day-ci/linux/commit/536df9470ecdddde67095f4f40f37752d944c343
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Maarten-Lankhorst/drm-i915-Fix-i915_request-fence-wait-semantics/20211021-183839
        git checkout 536df9470ecdddde67095f4f40f37752d944c343
        # save the attached .config to linux build tree
        make W=1 ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from drivers/gpu/drm/i915/gem/i915_gem_object.c:737:
>> drivers/gpu/drm/i915/gem/selftests/huge_pages.c:25:26: error: no previous prototype for 'hugepage_ctx' [-Werror=missing-prototypes]
      25 | struct i915_gem_context *hugepage_ctx(struct drm_i915_private *i915, struct file *file)
         |                          ^~~~~~~~~~~~
   cc1: all warnings being treated as errors


vim +/hugepage_ctx +25 drivers/gpu/drm/i915/gem/selftests/huge_pages.c

    24	
  > 25	struct i915_gem_context *hugepage_ctx(struct drm_i915_private *i915, struct file *file)
    26	{
    27		struct i915_gem_context *ctx = live_context(i915, file);
    28		struct i915_address_space *vm;
    29	
    30		if (IS_ERR(ctx))
    31			return ctx;
    32	
    33		vm = ctx->vm;
    34		if (vm)
    35			WRITE_ONCE(vm->scrub_64K, true);
    36	
    37		return ctx;
    38	}
    39	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 35457 bytes --]

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 16/28] drm/i915: Rework context handling in hugepages selftests
@ 2021-10-22  7:21     ` kernel test robot
  0 siblings, 0 replies; 114+ messages in thread
From: kernel test robot @ 2021-10-22  7:21 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 2382 bytes --]

Hi Maarten,

I love your patch! Yet something to improve:

[auto build test ERROR on drm-tip/drm-tip]
[cannot apply to drm-intel/for-linux-next drm-exynos/exynos-drm-next tegra-drm/drm/tegra/for-next airlied/drm-next v5.15-rc6 next-20211021]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Maarten-Lankhorst/drm-i915-Fix-i915_request-fence-wait-semantics/20211021-183839
base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
config: x86_64-randconfig-a011-20211021 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/0day-ci/linux/commit/536df9470ecdddde67095f4f40f37752d944c343
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Maarten-Lankhorst/drm-i915-Fix-i915_request-fence-wait-semantics/20211021-183839
        git checkout 536df9470ecdddde67095f4f40f37752d944c343
        # save the attached .config to linux build tree
        make W=1 ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from drivers/gpu/drm/i915/gem/i915_gem_object.c:737:
>> drivers/gpu/drm/i915/gem/selftests/huge_pages.c:25:26: error: no previous prototype for 'hugepage_ctx' [-Werror=missing-prototypes]
      25 | struct i915_gem_context *hugepage_ctx(struct drm_i915_private *i915, struct file *file)
         |                          ^~~~~~~~~~~~
   cc1: all warnings being treated as errors


vim +/hugepage_ctx +25 drivers/gpu/drm/i915/gem/selftests/huge_pages.c

    24	
  > 25	struct i915_gem_context *hugepage_ctx(struct drm_i915_private *i915, struct file *file)
    26	{
    27		struct i915_gem_context *ctx = live_context(i915, file);
    28		struct i915_address_space *vm;
    29	
    30		if (IS_ERR(ctx))
    31			return ctx;
    32	
    33		vm = ctx->vm;
    34		if (vm)
    35			WRITE_ONCE(vm->scrub_64K, true);
    36	
    37		return ctx;
    38	}
    39	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 35457 bytes --]

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 18/28] drm/i915: Take trylock during eviction, v2.
  2021-10-21 17:59   ` [Intel-gfx] " Matthew Auld
@ 2021-10-22  8:44       ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-22  8:44 UTC (permalink / raw)
  To: Matthew Auld; +Cc: Intel Graphics Development, ML dri-devel

Op 21-10-2021 om 19:59 schreef Matthew Auld:
> On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
> <maarten.lankhorst@linux.intel.com> wrote:
>> Now that freeing objects takes the object lock when destroying the
>> backing pages, we can confidently take the object lock even for dead
>> objects.
>>
>> Use this fact to take the object lock in the shrinker, without requiring
>> a reference to the object, so all calls to unbind take the object lock.
>>
>> This is the last step to requiring the object lock for vma_unbind.
> For the eviction what is the reason for only trylock here, assuming we
> are given a ww context? Maybe the back off is annoying? And the full
> lock version comes later?

2 reasons:

1. We can't take the full lock, because we already hold vm->mutex, which may be held inside dma_resv_lock. This inverts the locking, and is also why we could not keep obj->mm.lock. Until locking for vm is reworked, you cannot do this anyway.

Lockdep will complain about the following lock cycle: dma_resv_lock -> vm->mutex -> dma_resv_lock, and will eventually deadlock.

2. Until locking or delayed destroy is reworked, we cannot call a blocking dma_resv_lock for objects in the list when the refcount may be 0.

 "[PATCH 25/28] drm/i915: Require object lock when freeing pages during destruction".

When destroying the object, we will take dma_resv_lock in blocking mode one last time, then unbind all its vma's. The fact we're holding vm->mutex prevents the object from disappearing, because its vma is not yet unbound. This is how we can get away with unbinding dead objects currently, before and after the changes. This also means we can only trylock, because we can only trylock inside vm->mutex.

If we start reworking vm locking, we may need to handle waiting on dead objects better. It's worth noting that TTM has to handle the exact same race, which can be seen inside ttm_bo_cleanup_refs().

>> Changes since v1:
>> - No longer require the refcount, as every freed object now holds the lock
>>   when unbinding VMA's.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/gem/i915_gem_shrinker.c |  6 ++++
>>  drivers/gpu/drm/i915/i915_gem_evict.c        | 34 +++++++++++++++++---
>>  2 files changed, 35 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
>> index d3f29a66cb36..34c12e5983eb 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
>> @@ -403,12 +403,18 @@ i915_gem_shrinker_vmap(struct notifier_block *nb, unsigned long event, void *ptr
>>         list_for_each_entry_safe(vma, next,
>>                                  &i915->ggtt.vm.bound_list, vm_link) {
>>                 unsigned long count = vma->node.size >> PAGE_SHIFT;
>> +               struct drm_i915_gem_object *obj = vma->obj;
>>
>>                 if (!vma->iomap || i915_vma_is_active(vma))
>>                         continue;
>>
>> +               if (!i915_gem_object_trylock(obj))
>> +                       continue;
>> +
>>                 if (__i915_vma_unbind(vma) == 0)
>>                         freed_pages += count;
>> +
>> +               i915_gem_object_unlock(obj);
>>         }
>>         mutex_unlock(&i915->ggtt.vm.mutex);
>>
>> diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
>> index 2b73ddb11c66..286efa462eca 100644
>> --- a/drivers/gpu/drm/i915/i915_gem_evict.c
>> +++ b/drivers/gpu/drm/i915/i915_gem_evict.c
>> @@ -58,6 +58,9 @@ mark_free(struct drm_mm_scan *scan,
>>         if (i915_vma_is_pinned(vma))
>>                 return false;
>>
>> +       if (!i915_gem_object_trylock(vma->obj))
>> +               return false;
>> +
>>         list_add(&vma->evict_link, unwind);
>>         return drm_mm_scan_add_block(scan, &vma->node);
>>  }
>> @@ -178,6 +181,7 @@ i915_gem_evict_something(struct i915_address_space *vm,
>>         list_for_each_entry_safe(vma, next, &eviction_list, evict_link) {
>>                 ret = drm_mm_scan_remove_block(&scan, &vma->node);
>>                 BUG_ON(ret);
>> +               i915_gem_object_unlock(vma->obj);
>>         }
>>
>>         /*
>> @@ -222,10 +226,12 @@ i915_gem_evict_something(struct i915_address_space *vm,
>>          * of any of our objects, thus corrupting the list).
>>          */
>>         list_for_each_entry_safe(vma, next, &eviction_list, evict_link) {
>> -               if (drm_mm_scan_remove_block(&scan, &vma->node))
>> +               if (drm_mm_scan_remove_block(&scan, &vma->node)) {
>>                         __i915_vma_pin(vma);
>> -               else
>> +               } else {
>>                         list_del(&vma->evict_link);
>> +                       i915_gem_object_unlock(vma->obj);
>> +               }
>>         }
>>
>>         /* Unbinding will emit any required flushes */
>> @@ -234,16 +240,22 @@ i915_gem_evict_something(struct i915_address_space *vm,
>>                 __i915_vma_unpin(vma);
>>                 if (ret == 0)
>>                         ret = __i915_vma_unbind(vma);
>> +
>> +               i915_gem_object_unlock(vma->obj);
>>         }
>>
>>         while (ret == 0 && (node = drm_mm_scan_color_evict(&scan))) {
>>                 vma = container_of(node, struct i915_vma, node);
>>
>> +
>>                 /* If we find any non-objects (!vma), we cannot evict them */
>> -               if (vma->node.color != I915_COLOR_UNEVICTABLE)
>> +               if (vma->node.color != I915_COLOR_UNEVICTABLE &&
>> +                   i915_gem_object_trylock(vma->obj)) {
>>                         ret = __i915_vma_unbind(vma);
>> -               else
>> -                       ret = -ENOSPC; /* XXX search failed, try again? */
>> +                       i915_gem_object_unlock(vma->obj);
>> +               } else {
>> +                       ret = -ENOSPC;
>> +               }
>>         }
>>
>>         return ret;
>> @@ -333,6 +345,11 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
>>                         break;
>>                 }
>>
>> +               if (!i915_gem_object_trylock(vma->obj)) {
>> +                       ret = -ENOSPC;
>> +                       break;
>> +               }
>> +
>>                 /*
>>                  * Never show fear in the face of dragons!
>>                  *
>> @@ -350,6 +367,8 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
>>                 __i915_vma_unpin(vma);
>>                 if (ret == 0)
>>                         ret = __i915_vma_unbind(vma);
>> +
>> +               i915_gem_object_unlock(vma->obj);
>>         }
>>
>>         return ret;
>> @@ -393,6 +412,9 @@ int i915_gem_evict_vm(struct i915_address_space *vm)
>>                         if (i915_vma_is_pinned(vma))
>>                                 continue;
>>
>> +                       if (!i915_gem_object_trylock(vma->obj))
>> +                               continue;
>> +
>>                         __i915_vma_pin(vma);
>>                         list_add(&vma->evict_link, &eviction_list);
>>                 }
>> @@ -406,6 +428,8 @@ int i915_gem_evict_vm(struct i915_address_space *vm)
>>                                 ret = __i915_vma_unbind(vma);
>>                         if (ret != -EINTR) /* "Get me out of here!" */
>>                                 ret = 0;
>> +
>> +                       i915_gem_object_unlock(vma->obj);
>>                 }
>>         } while (ret == 0);
>>
>> --
>> 2.33.0
>>


^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 18/28] drm/i915: Take trylock during eviction,  v2.
@ 2021-10-22  8:44       ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-22  8:44 UTC (permalink / raw)
  To: Matthew Auld; +Cc: Intel Graphics Development, ML dri-devel

Op 21-10-2021 om 19:59 schreef Matthew Auld:
> On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
> <maarten.lankhorst@linux.intel.com> wrote:
>> Now that freeing objects takes the object lock when destroying the
>> backing pages, we can confidently take the object lock even for dead
>> objects.
>>
>> Use this fact to take the object lock in the shrinker, without requiring
>> a reference to the object, so all calls to unbind take the object lock.
>>
>> This is the last step to requiring the object lock for vma_unbind.
> For the eviction what is the reason for only trylock here, assuming we
> are given a ww context? Maybe the back off is annoying? And the full
> lock version comes later?

2 reasons:

1. We can't take the full lock, because we already hold vm->mutex, which may be held inside dma_resv_lock. This inverts the locking, and is also why we could not keep obj->mm.lock. Until locking for vm is reworked, you cannot do this anyway.

Lockdep will complain about the following lock cycle: dma_resv_lock -> vm->mutex -> dma_resv_lock, and will eventually deadlock.

2. Until locking or delayed destroy is reworked, we cannot call a blocking dma_resv_lock for objects in the list when the refcount may be 0.

 "[PATCH 25/28] drm/i915: Require object lock when freeing pages during destruction".

When destroying the object, we will take dma_resv_lock in blocking mode one last time, then unbind all its vma's. The fact we're holding vm->mutex prevents the object from disappearing, because its vma is not yet unbound. This is how we can get away with unbinding dead objects currently, before and after the changes. This also means we can only trylock, because we can only trylock inside vm->mutex.

If we start reworking vm locking, we may need to handle waiting on dead objects better. It's worth noting that TTM has to handle the exact same race, which can be seen inside ttm_bo_cleanup_refs().

>> Changes since v1:
>> - No longer require the refcount, as every freed object now holds the lock
>>   when unbinding VMA's.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/gem/i915_gem_shrinker.c |  6 ++++
>>  drivers/gpu/drm/i915/i915_gem_evict.c        | 34 +++++++++++++++++---
>>  2 files changed, 35 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
>> index d3f29a66cb36..34c12e5983eb 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
>> @@ -403,12 +403,18 @@ i915_gem_shrinker_vmap(struct notifier_block *nb, unsigned long event, void *ptr
>>         list_for_each_entry_safe(vma, next,
>>                                  &i915->ggtt.vm.bound_list, vm_link) {
>>                 unsigned long count = vma->node.size >> PAGE_SHIFT;
>> +               struct drm_i915_gem_object *obj = vma->obj;
>>
>>                 if (!vma->iomap || i915_vma_is_active(vma))
>>                         continue;
>>
>> +               if (!i915_gem_object_trylock(obj))
>> +                       continue;
>> +
>>                 if (__i915_vma_unbind(vma) == 0)
>>                         freed_pages += count;
>> +
>> +               i915_gem_object_unlock(obj);
>>         }
>>         mutex_unlock(&i915->ggtt.vm.mutex);
>>
>> diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
>> index 2b73ddb11c66..286efa462eca 100644
>> --- a/drivers/gpu/drm/i915/i915_gem_evict.c
>> +++ b/drivers/gpu/drm/i915/i915_gem_evict.c
>> @@ -58,6 +58,9 @@ mark_free(struct drm_mm_scan *scan,
>>         if (i915_vma_is_pinned(vma))
>>                 return false;
>>
>> +       if (!i915_gem_object_trylock(vma->obj))
>> +               return false;
>> +
>>         list_add(&vma->evict_link, unwind);
>>         return drm_mm_scan_add_block(scan, &vma->node);
>>  }
>> @@ -178,6 +181,7 @@ i915_gem_evict_something(struct i915_address_space *vm,
>>         list_for_each_entry_safe(vma, next, &eviction_list, evict_link) {
>>                 ret = drm_mm_scan_remove_block(&scan, &vma->node);
>>                 BUG_ON(ret);
>> +               i915_gem_object_unlock(vma->obj);
>>         }
>>
>>         /*
>> @@ -222,10 +226,12 @@ i915_gem_evict_something(struct i915_address_space *vm,
>>          * of any of our objects, thus corrupting the list).
>>          */
>>         list_for_each_entry_safe(vma, next, &eviction_list, evict_link) {
>> -               if (drm_mm_scan_remove_block(&scan, &vma->node))
>> +               if (drm_mm_scan_remove_block(&scan, &vma->node)) {
>>                         __i915_vma_pin(vma);
>> -               else
>> +               } else {
>>                         list_del(&vma->evict_link);
>> +                       i915_gem_object_unlock(vma->obj);
>> +               }
>>         }
>>
>>         /* Unbinding will emit any required flushes */
>> @@ -234,16 +240,22 @@ i915_gem_evict_something(struct i915_address_space *vm,
>>                 __i915_vma_unpin(vma);
>>                 if (ret == 0)
>>                         ret = __i915_vma_unbind(vma);
>> +
>> +               i915_gem_object_unlock(vma->obj);
>>         }
>>
>>         while (ret == 0 && (node = drm_mm_scan_color_evict(&scan))) {
>>                 vma = container_of(node, struct i915_vma, node);
>>
>> +
>>                 /* If we find any non-objects (!vma), we cannot evict them */
>> -               if (vma->node.color != I915_COLOR_UNEVICTABLE)
>> +               if (vma->node.color != I915_COLOR_UNEVICTABLE &&
>> +                   i915_gem_object_trylock(vma->obj)) {
>>                         ret = __i915_vma_unbind(vma);
>> -               else
>> -                       ret = -ENOSPC; /* XXX search failed, try again? */
>> +                       i915_gem_object_unlock(vma->obj);
>> +               } else {
>> +                       ret = -ENOSPC;
>> +               }
>>         }
>>
>>         return ret;
>> @@ -333,6 +345,11 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
>>                         break;
>>                 }
>>
>> +               if (!i915_gem_object_trylock(vma->obj)) {
>> +                       ret = -ENOSPC;
>> +                       break;
>> +               }
>> +
>>                 /*
>>                  * Never show fear in the face of dragons!
>>                  *
>> @@ -350,6 +367,8 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
>>                 __i915_vma_unpin(vma);
>>                 if (ret == 0)
>>                         ret = __i915_vma_unbind(vma);
>> +
>> +               i915_gem_object_unlock(vma->obj);
>>         }
>>
>>         return ret;
>> @@ -393,6 +412,9 @@ int i915_gem_evict_vm(struct i915_address_space *vm)
>>                         if (i915_vma_is_pinned(vma))
>>                                 continue;
>>
>> +                       if (!i915_gem_object_trylock(vma->obj))
>> +                               continue;
>> +
>>                         __i915_vma_pin(vma);
>>                         list_add(&vma->evict_link, &eviction_list);
>>                 }
>> @@ -406,6 +428,8 @@ int i915_gem_evict_vm(struct i915_address_space *vm)
>>                                 ret = __i915_vma_unbind(vma);
>>                         if (ret != -EINTR) /* "Get me out of here!" */
>>                                 ret = 0;
>> +
>> +                       i915_gem_object_unlock(vma->obj);
>>                 }
>>         } while (ret == 0);
>>
>> --
>> 2.33.0
>>


^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [PATCH 03/28] drm/i915: Remove dma_resv_prune
  2021-10-21 14:43     ` [Intel-gfx] " Matthew Auld
@ 2021-10-22  8:48       ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-22  8:48 UTC (permalink / raw)
  To: Matthew Auld; +Cc: Intel Graphics Development, ML dri-devel

Op 21-10-2021 om 16:43 schreef Matthew Auld:
> On Thu, 21 Oct 2021 at 11:36, Maarten Lankhorst
> <maarten.lankhorst@linux.intel.com> wrote:
>> The signaled bit is already used for quick testing if a fence is signaled.
> Why do we need this change? Can you add some more details to the commit please?

It's a terrible abuse of dma-fence api, and in the common case where the object is already locked by the caller, the trylock will fail.

If it were useful, the core dma-api would have exposed the same functionality.

On top of that, the fact that i915 has a dma_resv_utils.c file should be a warning that the functionality either belongs in core, or is not very useful at all. In this case the latter.

>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/Makefile                |  1 -
>>  drivers/gpu/drm/i915/dma_resv_utils.c        | 17 -----------------
>>  drivers/gpu/drm/i915/dma_resv_utils.h        | 13 -------------
>>  drivers/gpu/drm/i915/gem/i915_gem_shrinker.c |  3 ---
>>  drivers/gpu/drm/i915/gem/i915_gem_wait.c     |  8 --------
>>  5 files changed, 42 deletions(-)
>>  delete mode 100644 drivers/gpu/drm/i915/dma_resv_utils.c
>>  delete mode 100644 drivers/gpu/drm/i915/dma_resv_utils.h
>>
>> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
>> index 467872cca027..b87e3ed10d86 100644
>> --- a/drivers/gpu/drm/i915/Makefile
>> +++ b/drivers/gpu/drm/i915/Makefile
>> @@ -60,7 +60,6 @@ i915-y += i915_drv.o \
>>
>>  # core library code
>>  i915-y += \
>> -       dma_resv_utils.o \
>>         i915_memcpy.o \
>>         i915_mm.o \
>>         i915_sw_fence.o \
>> diff --git a/drivers/gpu/drm/i915/dma_resv_utils.c b/drivers/gpu/drm/i915/dma_resv_utils.c
>> deleted file mode 100644
>> index 7df91b7e4ca8..000000000000
>> --- a/drivers/gpu/drm/i915/dma_resv_utils.c
>> +++ /dev/null
>> @@ -1,17 +0,0 @@
>> -// SPDX-License-Identifier: MIT
>> -/*
>> - * Copyright © 2020 Intel Corporation
>> - */
>> -
>> -#include <linux/dma-resv.h>
>> -
>> -#include "dma_resv_utils.h"
>> -
>> -void dma_resv_prune(struct dma_resv *resv)
>> -{
>> -       if (dma_resv_trylock(resv)) {
>> -               if (dma_resv_test_signaled(resv, true))
>> -                       dma_resv_add_excl_fence(resv, NULL);
>> -               dma_resv_unlock(resv);
>> -       }
>> -}
>> diff --git a/drivers/gpu/drm/i915/dma_resv_utils.h b/drivers/gpu/drm/i915/dma_resv_utils.h
>> deleted file mode 100644
>> index b9d8fb5f8367..000000000000
>> --- a/drivers/gpu/drm/i915/dma_resv_utils.h
>> +++ /dev/null
>> @@ -1,13 +0,0 @@
>> -/* SPDX-License-Identifier: MIT */
>> -/*
>> - * Copyright © 2020 Intel Corporation
>> - */
>> -
>> -#ifndef DMA_RESV_UTILS_H
>> -#define DMA_RESV_UTILS_H
>> -
>> -struct dma_resv;
>> -
>> -void dma_resv_prune(struct dma_resv *resv);
>> -
>> -#endif /* DMA_RESV_UTILS_H */
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
>> index 5ab136ffdeb2..af3eb7fd951d 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
>> @@ -15,7 +15,6 @@
>>
>>  #include "gt/intel_gt_requests.h"
>>
>> -#include "dma_resv_utils.h"
>>  #include "i915_trace.h"
>>
>>  static bool swap_available(void)
>> @@ -229,8 +228,6 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww,
>>                                         i915_gem_object_unlock(obj);
>>                         }
>>
>> -                       dma_resv_prune(obj->base.resv);
> Like here, why do we want to drop this? Later in the series it looks
> like it gets added back, just in a slightly different form.
>
>> -
>>                         scanned += obj->base.size >> PAGE_SHIFT;
>>  skip:
>>                         i915_gem_object_put(obj);
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_wait.c b/drivers/gpu/drm/i915/gem/i915_gem_wait.c
>> index 840c13706999..1592d95c3ead 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_wait.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_wait.c
>> @@ -10,7 +10,6 @@
>>
>>  #include "gt/intel_engine.h"
>>
>> -#include "dma_resv_utils.h"
>>  #include "i915_gem_ioctls.h"
>>  #include "i915_gem_object.h"
>>
>> @@ -52,13 +51,6 @@ i915_gem_object_wait_reservation(struct dma_resv *resv,
>>         }
>>         dma_resv_iter_end(&cursor);
>>
>> -       /*
>> -        * Opportunistically prune the fences iff we know they have *all* been
>> -        * signaled.
>> -        */
>> -       if (timeout > 0)
>> -               dma_resv_prune(resv);
>> -
>>         return ret;
>>  }
>>
>> --
>> 2.33.0
>>


^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 03/28] drm/i915: Remove dma_resv_prune
@ 2021-10-22  8:48       ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-22  8:48 UTC (permalink / raw)
  To: Matthew Auld; +Cc: Intel Graphics Development, ML dri-devel

Op 21-10-2021 om 16:43 schreef Matthew Auld:
> On Thu, 21 Oct 2021 at 11:36, Maarten Lankhorst
> <maarten.lankhorst@linux.intel.com> wrote:
>> The signaled bit is already used for quick testing if a fence is signaled.
> Why do we need this change? Can you add some more details to the commit please?

It's a terrible abuse of dma-fence api, and in the common case where the object is already locked by the caller, the trylock will fail.

If it were useful, the core dma-api would have exposed the same functionality.

On top of that, the fact that i915 has a dma_resv_utils.c file should be a warning that the functionality either belongs in core, or is not very useful at all. In this case the latter.

>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/Makefile                |  1 -
>>  drivers/gpu/drm/i915/dma_resv_utils.c        | 17 -----------------
>>  drivers/gpu/drm/i915/dma_resv_utils.h        | 13 -------------
>>  drivers/gpu/drm/i915/gem/i915_gem_shrinker.c |  3 ---
>>  drivers/gpu/drm/i915/gem/i915_gem_wait.c     |  8 --------
>>  5 files changed, 42 deletions(-)
>>  delete mode 100644 drivers/gpu/drm/i915/dma_resv_utils.c
>>  delete mode 100644 drivers/gpu/drm/i915/dma_resv_utils.h
>>
>> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
>> index 467872cca027..b87e3ed10d86 100644
>> --- a/drivers/gpu/drm/i915/Makefile
>> +++ b/drivers/gpu/drm/i915/Makefile
>> @@ -60,7 +60,6 @@ i915-y += i915_drv.o \
>>
>>  # core library code
>>  i915-y += \
>> -       dma_resv_utils.o \
>>         i915_memcpy.o \
>>         i915_mm.o \
>>         i915_sw_fence.o \
>> diff --git a/drivers/gpu/drm/i915/dma_resv_utils.c b/drivers/gpu/drm/i915/dma_resv_utils.c
>> deleted file mode 100644
>> index 7df91b7e4ca8..000000000000
>> --- a/drivers/gpu/drm/i915/dma_resv_utils.c
>> +++ /dev/null
>> @@ -1,17 +0,0 @@
>> -// SPDX-License-Identifier: MIT
>> -/*
>> - * Copyright © 2020 Intel Corporation
>> - */
>> -
>> -#include <linux/dma-resv.h>
>> -
>> -#include "dma_resv_utils.h"
>> -
>> -void dma_resv_prune(struct dma_resv *resv)
>> -{
>> -       if (dma_resv_trylock(resv)) {
>> -               if (dma_resv_test_signaled(resv, true))
>> -                       dma_resv_add_excl_fence(resv, NULL);
>> -               dma_resv_unlock(resv);
>> -       }
>> -}
>> diff --git a/drivers/gpu/drm/i915/dma_resv_utils.h b/drivers/gpu/drm/i915/dma_resv_utils.h
>> deleted file mode 100644
>> index b9d8fb5f8367..000000000000
>> --- a/drivers/gpu/drm/i915/dma_resv_utils.h
>> +++ /dev/null
>> @@ -1,13 +0,0 @@
>> -/* SPDX-License-Identifier: MIT */
>> -/*
>> - * Copyright © 2020 Intel Corporation
>> - */
>> -
>> -#ifndef DMA_RESV_UTILS_H
>> -#define DMA_RESV_UTILS_H
>> -
>> -struct dma_resv;
>> -
>> -void dma_resv_prune(struct dma_resv *resv);
>> -
>> -#endif /* DMA_RESV_UTILS_H */
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
>> index 5ab136ffdeb2..af3eb7fd951d 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
>> @@ -15,7 +15,6 @@
>>
>>  #include "gt/intel_gt_requests.h"
>>
>> -#include "dma_resv_utils.h"
>>  #include "i915_trace.h"
>>
>>  static bool swap_available(void)
>> @@ -229,8 +228,6 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww,
>>                                         i915_gem_object_unlock(obj);
>>                         }
>>
>> -                       dma_resv_prune(obj->base.resv);
> Like here, why do we want to drop this? Later in the series it looks
> like it gets added back, just in a slightly different form.
>
>> -
>>                         scanned += obj->base.size >> PAGE_SHIFT;
>>  skip:
>>                         i915_gem_object_put(obj);
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_wait.c b/drivers/gpu/drm/i915/gem/i915_gem_wait.c
>> index 840c13706999..1592d95c3ead 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_wait.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_wait.c
>> @@ -10,7 +10,6 @@
>>
>>  #include "gt/intel_engine.h"
>>
>> -#include "dma_resv_utils.h"
>>  #include "i915_gem_ioctls.h"
>>  #include "i915_gem_object.h"
>>
>> @@ -52,13 +51,6 @@ i915_gem_object_wait_reservation(struct dma_resv *resv,
>>         }
>>         dma_resv_iter_end(&cursor);
>>
>> -       /*
>> -        * Opportunistically prune the fences iff we know they have *all* been
>> -        * signaled.
>> -        */
>> -       if (timeout > 0)
>> -               dma_resv_prune(resv);
>> -
>>         return ret;
>>  }
>>
>> --
>> 2.33.0
>>


^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 19/28] drm/i915: Pass trylock context to callers
  2021-10-21 18:03   ` Matthew Auld
@ 2021-10-22  8:52     ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-22  8:52 UTC (permalink / raw)
  To: Matthew Auld; +Cc: Intel Graphics Development, ML dri-devel

Op 21-10-2021 om 20:03 schreef Matthew Auld:
> On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
> <maarten.lankhorst@linux.intel.com> wrote:
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Needs a proper commit message.

What about this?

drm/i915: Pass trylock context to callers

We are moving away from short term pinning, and need a way to evict objects locked by the current context. Pass the ww context to all eviction functions, so that they can evict objects that are already locked by the current ww context.

On top of that, this slightly improves ww handling because the locked objects are marked as locked by the correct ww.


^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 13/28] drm/i915: Remove pages_mutex and intel_gtt->vma_ops.set/clear_pages members
  2021-10-21 17:30   ` [Intel-gfx] " Matthew Auld
@ 2021-10-22 10:59     ` Matthew Auld
  2021-11-29 12:40       ` Maarten Lankhorst
  0 siblings, 1 reply; 114+ messages in thread
From: Matthew Auld @ 2021-10-22 10:59 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Intel Graphics Development, ML dri-devel

On Thu, 21 Oct 2021 at 18:30, Matthew Auld
<matthew.william.auld@gmail.com> wrote:
>
> On Thu, 21 Oct 2021 at 11:36, Maarten Lankhorst
> <maarten.lankhorst@linux.intel.com> wrote:
> >
> > Big delta, but boils down to moving set_pages to i915_vma.c, and removing
> > the special handling, all callers use the defaults anyway. We only remap
> > in ggtt, so default case will fall through.
> >
> > Because we still don't require locking in i915_vma_unpin(), handle this by
> > using xchg in get_pages(), as it's locked with obj->mutex, and cmpxchg in
> > unpin, which only fails if we race a against a new pin.
> >
> > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_dpt.c      |   2 -
> >  drivers/gpu/drm/i915/gt/gen6_ppgtt.c          |  15 -
> >  drivers/gpu/drm/i915/gt/intel_ggtt.c          | 345 ----------------
> >  drivers/gpu/drm/i915/gt/intel_gtt.c           |  13 -
> >  drivers/gpu/drm/i915/gt/intel_gtt.h           |   7 -
> >  drivers/gpu/drm/i915/gt/intel_ppgtt.c         |  12 -
> >  drivers/gpu/drm/i915/i915_vma.c               | 388 ++++++++++++++++--
> >  drivers/gpu/drm/i915/i915_vma.h               |   3 +
> >  drivers/gpu/drm/i915/i915_vma_types.h         |   1 -
> >  drivers/gpu/drm/i915/selftests/i915_gem_gtt.c |  12 +-
> >  drivers/gpu/drm/i915/selftests/mock_gtt.c     |   4 -
> >  11 files changed, 368 insertions(+), 434 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c
> > index 8f7b1f7534a4..ef428f3fc538 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dpt.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dpt.c
> > @@ -221,8 +221,6 @@ intel_dpt_create(struct intel_framebuffer *fb)
> >
> >         vm->vma_ops.bind_vma    = dpt_bind_vma;
> >         vm->vma_ops.unbind_vma  = dpt_unbind_vma;
> > -       vm->vma_ops.set_pages   = ggtt_set_pages;
> > -       vm->vma_ops.clear_pages = clear_pages;
> >
> >         vm->pte_encode = gen8_ggtt_pte_encode;
> >
> > diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
> > index 5caa1703716e..5c048b4ccd4d 100644
> > --- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
> > +++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
> > @@ -270,19 +270,6 @@ static void gen6_ppgtt_cleanup(struct i915_address_space *vm)
> >         free_pd(&ppgtt->base.vm, ppgtt->base.pd);
> >  }
> >
> > -static int pd_vma_set_pages(struct i915_vma *vma)
> > -{
> > -       vma->pages = ERR_PTR(-ENODEV);
> > -       return 0;
> > -}
> > -
> > -static void pd_vma_clear_pages(struct i915_vma *vma)
> > -{
> > -       GEM_BUG_ON(!vma->pages);
> > -
> > -       vma->pages = NULL;
> > -}
> > -
> >  static void pd_vma_bind(struct i915_address_space *vm,
> >                         struct i915_vm_pt_stash *stash,
> >                         struct i915_vma *vma,
> > @@ -322,8 +309,6 @@ static void pd_vma_unbind(struct i915_address_space *vm, struct i915_vma *vma)
> >  }
> >
> >  static const struct i915_vma_ops pd_vma_ops = {
> > -       .set_pages = pd_vma_set_pages,
> > -       .clear_pages = pd_vma_clear_pages,
> >         .bind_vma = pd_vma_bind,
> >         .unbind_vma = pd_vma_unbind,
> >  };
> > diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
> > index f17383e76eb7..6da57199bb33 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
> > +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
> > @@ -20,9 +20,6 @@
> >  #include "intel_gtt.h"
> >  #include "gen8_ppgtt.h"
> >
> > -static int
> > -i915_get_ggtt_vma_pages(struct i915_vma *vma);
> > -
> >  static void i915_ggtt_color_adjust(const struct drm_mm_node *node,
> >                                    unsigned long color,
> >                                    u64 *start,
> > @@ -875,21 +872,6 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, u64 size)
> >         return 0;
> >  }
> >
> > -int ggtt_set_pages(struct i915_vma *vma)
> > -{
> > -       int ret;
> > -
> > -       GEM_BUG_ON(vma->pages);
> > -
> > -       ret = i915_get_ggtt_vma_pages(vma);
> > -       if (ret)
> > -               return ret;
> > -
> > -       vma->page_sizes = vma->obj->mm.page_sizes;
> > -
> > -       return 0;
> > -}
> > -
> >  static void gen6_gmch_remove(struct i915_address_space *vm)
> >  {
> >         struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
> > @@ -950,8 +932,6 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
> >
> >         ggtt->vm.vma_ops.bind_vma    = ggtt_bind_vma;
> >         ggtt->vm.vma_ops.unbind_vma  = ggtt_unbind_vma;
> > -       ggtt->vm.vma_ops.set_pages   = ggtt_set_pages;
> > -       ggtt->vm.vma_ops.clear_pages = clear_pages;
> >
> >         ggtt->vm.pte_encode = gen8_ggtt_pte_encode;
> >
> > @@ -1100,8 +1080,6 @@ static int gen6_gmch_probe(struct i915_ggtt *ggtt)
> >
> >         ggtt->vm.vma_ops.bind_vma    = ggtt_bind_vma;
> >         ggtt->vm.vma_ops.unbind_vma  = ggtt_unbind_vma;
> > -       ggtt->vm.vma_ops.set_pages   = ggtt_set_pages;
> > -       ggtt->vm.vma_ops.clear_pages = clear_pages;
> >
> >         return ggtt_probe_common(ggtt, size);
> >  }
> > @@ -1145,8 +1123,6 @@ static int i915_gmch_probe(struct i915_ggtt *ggtt)
> >
> >         ggtt->vm.vma_ops.bind_vma    = ggtt_bind_vma;
> >         ggtt->vm.vma_ops.unbind_vma  = ggtt_unbind_vma;
> > -       ggtt->vm.vma_ops.set_pages   = ggtt_set_pages;
> > -       ggtt->vm.vma_ops.clear_pages = clear_pages;
> >
> >         if (unlikely(ggtt->do_idle_maps))
> >                 drm_notice(&i915->drm,
> > @@ -1294,324 +1270,3 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
> >
> >         intel_ggtt_restore_fences(ggtt);
> >  }
> > -
> > -static struct scatterlist *
> > -rotate_pages(struct drm_i915_gem_object *obj, unsigned int offset,
> > -            unsigned int width, unsigned int height,
> > -            unsigned int src_stride, unsigned int dst_stride,
> > -            struct sg_table *st, struct scatterlist *sg)
> > -{
> > -       unsigned int column, row;
> > -       unsigned int src_idx;
> > -
> > -       for (column = 0; column < width; column++) {
> > -               unsigned int left;
> > -
> > -               src_idx = src_stride * (height - 1) + column + offset;
> > -               for (row = 0; row < height; row++) {
> > -                       st->nents++;
> > -                       /*
> > -                        * We don't need the pages, but need to initialize
> > -                        * the entries so the sg list can be happily traversed.
> > -                        * The only thing we need are DMA addresses.
> > -                        */
> > -                       sg_set_page(sg, NULL, I915_GTT_PAGE_SIZE, 0);
> > -                       sg_dma_address(sg) =
> > -                               i915_gem_object_get_dma_address(obj, src_idx);
> > -                       sg_dma_len(sg) = I915_GTT_PAGE_SIZE;
> > -                       sg = sg_next(sg);
> > -                       src_idx -= src_stride;
> > -               }
> > -
> > -               left = (dst_stride - height) * I915_GTT_PAGE_SIZE;
> > -
> > -               if (!left)
> > -                       continue;
> > -
> > -               st->nents++;
> > -
> > -               /*
> > -                * The DE ignores the PTEs for the padding tiles, the sg entry
> > -                * here is just a conenience to indicate how many padding PTEs
> > -                * to insert at this spot.
> > -                */
> > -               sg_set_page(sg, NULL, left, 0);
> > -               sg_dma_address(sg) = 0;
> > -               sg_dma_len(sg) = left;
> > -               sg = sg_next(sg);
> > -       }
> > -
> > -       return sg;
> > -}
> > -
> > -static noinline struct sg_table *
> > -intel_rotate_pages(struct intel_rotation_info *rot_info,
> > -                  struct drm_i915_gem_object *obj)
> > -{
> > -       unsigned int size = intel_rotation_info_size(rot_info);
> > -       struct drm_i915_private *i915 = to_i915(obj->base.dev);
> > -       struct sg_table *st;
> > -       struct scatterlist *sg;
> > -       int ret = -ENOMEM;
> > -       int i;
> > -
> > -       /* Allocate target SG list. */
> > -       st = kmalloc(sizeof(*st), GFP_KERNEL);
> > -       if (!st)
> > -               goto err_st_alloc;
> > -
> > -       ret = sg_alloc_table(st, size, GFP_KERNEL);
> > -       if (ret)
> > -               goto err_sg_alloc;
> > -
> > -       st->nents = 0;
> > -       sg = st->sgl;
> > -
> > -       for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++)
> > -               sg = rotate_pages(obj, rot_info->plane[i].offset,
> > -                                 rot_info->plane[i].width, rot_info->plane[i].height,
> > -                                 rot_info->plane[i].src_stride,
> > -                                 rot_info->plane[i].dst_stride,
> > -                                 st, sg);
> > -
> > -       return st;
> > -
> > -err_sg_alloc:
> > -       kfree(st);
> > -err_st_alloc:
> > -
> > -       drm_dbg(&i915->drm, "Failed to create rotated mapping for object size %zu! (%ux%u tiles, %u pages)\n",
> > -               obj->base.size, rot_info->plane[0].width,
> > -               rot_info->plane[0].height, size);
> > -
> > -       return ERR_PTR(ret);
> > -}
> > -
> > -static struct scatterlist *
> > -remap_pages(struct drm_i915_gem_object *obj,
> > -           unsigned int offset, unsigned int alignment_pad,
> > -           unsigned int width, unsigned int height,
> > -           unsigned int src_stride, unsigned int dst_stride,
> > -           struct sg_table *st, struct scatterlist *sg)
> > -{
> > -       unsigned int row;
> > -
> > -       if (alignment_pad) {
> > -               st->nents++;
> > -
> > -               /*
> > -                * The DE ignores the PTEs for the padding tiles, the sg entry
> > -                * here is just a convenience to indicate how many padding PTEs
> > -                * to insert at this spot.
> > -                */
> > -               sg_set_page(sg, NULL, alignment_pad * 4096, 0);
> > -               sg_dma_address(sg) = 0;
> > -               sg_dma_len(sg) = alignment_pad * 4096;
> > -               sg = sg_next(sg);
> > -       }
> > -
> > -       for (row = 0; row < height; row++) {
> > -               unsigned int left = width * I915_GTT_PAGE_SIZE;
> > -
> > -               while (left) {
> > -                       dma_addr_t addr;
> > -                       unsigned int length;
> > -
> > -                       /*
> > -                        * We don't need the pages, but need to initialize
> > -                        * the entries so the sg list can be happily traversed.
> > -                        * The only thing we need are DMA addresses.
> > -                        */
> > -
> > -                       addr = i915_gem_object_get_dma_address_len(obj, offset, &length);
> > -
> > -                       length = min(left, length);
> > -
> > -                       st->nents++;
> > -
> > -                       sg_set_page(sg, NULL, length, 0);
> > -                       sg_dma_address(sg) = addr;
> > -                       sg_dma_len(sg) = length;
> > -                       sg = sg_next(sg);
> > -
> > -                       offset += length / I915_GTT_PAGE_SIZE;
> > -                       left -= length;
> > -               }
> > -
> > -               offset += src_stride - width;
> > -
> > -               left = (dst_stride - width) * I915_GTT_PAGE_SIZE;
> > -
> > -               if (!left)
> > -                       continue;
> > -
> > -               st->nents++;
> > -
> > -               /*
> > -                * The DE ignores the PTEs for the padding tiles, the sg entry
> > -                * here is just a conenience to indicate how many padding PTEs
> > -                * to insert at this spot.
> > -                */
> > -               sg_set_page(sg, NULL, left, 0);
> > -               sg_dma_address(sg) = 0;
> > -               sg_dma_len(sg) = left;
> > -               sg = sg_next(sg);
> > -       }
> > -
> > -       return sg;
> > -}
> > -
> > -static noinline struct sg_table *
> > -intel_remap_pages(struct intel_remapped_info *rem_info,
> > -                 struct drm_i915_gem_object *obj)
> > -{
> > -       unsigned int size = intel_remapped_info_size(rem_info);
> > -       struct drm_i915_private *i915 = to_i915(obj->base.dev);
> > -       struct sg_table *st;
> > -       struct scatterlist *sg;
> > -       unsigned int gtt_offset = 0;
> > -       int ret = -ENOMEM;
> > -       int i;
> > -
> > -       /* Allocate target SG list. */
> > -       st = kmalloc(sizeof(*st), GFP_KERNEL);
> > -       if (!st)
> > -               goto err_st_alloc;
> > -
> > -       ret = sg_alloc_table(st, size, GFP_KERNEL);
> > -       if (ret)
> > -               goto err_sg_alloc;
> > -
> > -       st->nents = 0;
> > -       sg = st->sgl;
> > -
> > -       for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
> > -               unsigned int alignment_pad = 0;
> > -
> > -               if (rem_info->plane_alignment)
> > -                       alignment_pad = ALIGN(gtt_offset, rem_info->plane_alignment) - gtt_offset;
> > -
> > -               sg = remap_pages(obj,
> > -                                rem_info->plane[i].offset, alignment_pad,
> > -                                rem_info->plane[i].width, rem_info->plane[i].height,
> > -                                rem_info->plane[i].src_stride, rem_info->plane[i].dst_stride,
> > -                                st, sg);
> > -
> > -               gtt_offset += alignment_pad +
> > -                             rem_info->plane[i].dst_stride * rem_info->plane[i].height;
> > -       }
> > -
> > -       i915_sg_trim(st);
> > -
> > -       return st;
> > -
> > -err_sg_alloc:
> > -       kfree(st);
> > -err_st_alloc:
> > -
> > -       drm_dbg(&i915->drm, "Failed to create remapped mapping for object size %zu! (%ux%u tiles, %u pages)\n",
> > -               obj->base.size, rem_info->plane[0].width,
> > -               rem_info->plane[0].height, size);
> > -
> > -       return ERR_PTR(ret);
> > -}
> > -
> > -static noinline struct sg_table *
> > -intel_partial_pages(const struct i915_ggtt_view *view,
> > -                   struct drm_i915_gem_object *obj)
> > -{
> > -       struct sg_table *st;
> > -       struct scatterlist *sg, *iter;
> > -       unsigned int count = view->partial.size;
> > -       unsigned int offset;
> > -       int ret = -ENOMEM;
> > -
> > -       st = kmalloc(sizeof(*st), GFP_KERNEL);
> > -       if (!st)
> > -               goto err_st_alloc;
> > -
> > -       ret = sg_alloc_table(st, count, GFP_KERNEL);
> > -       if (ret)
> > -               goto err_sg_alloc;
> > -
> > -       iter = i915_gem_object_get_sg_dma(obj, view->partial.offset, &offset);
> > -       GEM_BUG_ON(!iter);
> > -
> > -       sg = st->sgl;
> > -       st->nents = 0;
> > -       do {
> > -               unsigned int len;
> > -
> > -               len = min(sg_dma_len(iter) - (offset << PAGE_SHIFT),
> > -                         count << PAGE_SHIFT);
> > -               sg_set_page(sg, NULL, len, 0);
> > -               sg_dma_address(sg) =
> > -                       sg_dma_address(iter) + (offset << PAGE_SHIFT);
> > -               sg_dma_len(sg) = len;
> > -
> > -               st->nents++;
> > -               count -= len >> PAGE_SHIFT;
> > -               if (count == 0) {
> > -                       sg_mark_end(sg);
> > -                       i915_sg_trim(st); /* Drop any unused tail entries. */
> > -
> > -                       return st;
> > -               }
> > -
> > -               sg = __sg_next(sg);
> > -               iter = __sg_next(iter);
> > -               offset = 0;
> > -       } while (1);
> > -
> > -err_sg_alloc:
> > -       kfree(st);
> > -err_st_alloc:
> > -       return ERR_PTR(ret);
> > -}
> > -
> > -static int
> > -i915_get_ggtt_vma_pages(struct i915_vma *vma)
> > -{
> > -       int ret;
> > -
> > -       /*
> > -        * The vma->pages are only valid within the lifespan of the borrowed
> > -        * obj->mm.pages. When the obj->mm.pages sg_table is regenerated, so
> > -        * must be the vma->pages. A simple rule is that vma->pages must only
> > -        * be accessed when the obj->mm.pages are pinned.
> > -        */
> > -       GEM_BUG_ON(!i915_gem_object_has_pinned_pages(vma->obj));
> > -
> > -       switch (vma->ggtt_view.type) {
> > -       default:
> > -               GEM_BUG_ON(vma->ggtt_view.type);
> > -               fallthrough;
> > -       case I915_GGTT_VIEW_NORMAL:
> > -               vma->pages = vma->obj->mm.pages;
> > -               return 0;
> > -
> > -       case I915_GGTT_VIEW_ROTATED:
> > -               vma->pages =
> > -                       intel_rotate_pages(&vma->ggtt_view.rotated, vma->obj);
> > -               break;
> > -
> > -       case I915_GGTT_VIEW_REMAPPED:
> > -               vma->pages =
> > -                       intel_remap_pages(&vma->ggtt_view.remapped, vma->obj);
> > -               break;
> > -
> > -       case I915_GGTT_VIEW_PARTIAL:
> > -               vma->pages = intel_partial_pages(&vma->ggtt_view, vma->obj);
> > -               break;
> > -       }
> > -
> > -       ret = 0;
> > -       if (IS_ERR(vma->pages)) {
> > -               ret = PTR_ERR(vma->pages);
> > -               vma->pages = NULL;
> > -               drm_err(&vma->vm->i915->drm,
> > -                       "Failed to get pages for VMA view type %u (%d)!\n",
> > -                       vma->ggtt_view.type, ret);
> > -       }
> > -       return ret;
> > -}
> > diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c b/drivers/gpu/drm/i915/gt/intel_gtt.c
> > index 67d14afa6623..12eed5fcb17a 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_gtt.c
> > +++ b/drivers/gpu/drm/i915/gt/intel_gtt.c
> > @@ -221,19 +221,6 @@ void i915_address_space_init(struct i915_address_space *vm, int subclass)
> >         INIT_LIST_HEAD(&vm->bound_list);
> >  }
> >
> > -void clear_pages(struct i915_vma *vma)
> > -{
> > -       GEM_BUG_ON(!vma->pages);
> > -
> > -       if (vma->pages != vma->obj->mm.pages) {
> > -               sg_free_table(vma->pages);
> > -               kfree(vma->pages);
> > -       }
> > -       vma->pages = NULL;
> > -
> > -       memset(&vma->page_sizes, 0, sizeof(vma->page_sizes));
> > -}
> > -
> >  void *__px_vaddr(struct drm_i915_gem_object *p)
> >  {
> >         enum i915_map_type type;
> > diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.h b/drivers/gpu/drm/i915/gt/intel_gtt.h
> > index bc6750263359..306e7645fdc5 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_gtt.h
> > +++ b/drivers/gpu/drm/i915/gt/intel_gtt.h
> > @@ -206,9 +206,6 @@ struct i915_vma_ops {
> >          */
> >         void (*unbind_vma)(struct i915_address_space *vm,
> >                            struct i915_vma *vma);
> > -
> > -       int (*set_pages)(struct i915_vma *vma);
> > -       void (*clear_pages)(struct i915_vma *vma);
> >  };
> >
> >  struct i915_address_space {
> > @@ -594,10 +591,6 @@ release_pd_entry(struct i915_page_directory * const pd,
> >                  const struct drm_i915_gem_object * const scratch);
> >  void gen6_ggtt_invalidate(struct i915_ggtt *ggtt);
> >
> > -int ggtt_set_pages(struct i915_vma *vma);
> > -int ppgtt_set_pages(struct i915_vma *vma);
> > -void clear_pages(struct i915_vma *vma);
> > -
> >  void ppgtt_bind_vma(struct i915_address_space *vm,
> >                     struct i915_vm_pt_stash *stash,
> >                     struct i915_vma *vma,
> > diff --git a/drivers/gpu/drm/i915/gt/intel_ppgtt.c b/drivers/gpu/drm/i915/gt/intel_ppgtt.c
> > index 4396bfd630d8..083b3090c69c 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_ppgtt.c
> > +++ b/drivers/gpu/drm/i915/gt/intel_ppgtt.c
> > @@ -289,16 +289,6 @@ void i915_vm_free_pt_stash(struct i915_address_space *vm,
> >         }
> >  }
> >
> > -int ppgtt_set_pages(struct i915_vma *vma)
> > -{
> > -       GEM_BUG_ON(vma->pages);
> > -
> > -       vma->pages = vma->obj->mm.pages;
> > -       vma->page_sizes = vma->obj->mm.page_sizes;
> > -
> > -       return 0;
> > -}
> > -
> >  void ppgtt_init(struct i915_ppgtt *ppgtt, struct intel_gt *gt,
> >                 unsigned long lmem_pt_obj_flags)
> >  {
> > @@ -315,6 +305,4 @@ void ppgtt_init(struct i915_ppgtt *ppgtt, struct intel_gt *gt,
> >
> >         ppgtt->vm.vma_ops.bind_vma    = ppgtt_bind_vma;
> >         ppgtt->vm.vma_ops.unbind_vma  = ppgtt_unbind_vma;
> > -       ppgtt->vm.vma_ops.set_pages   = ppgtt_set_pages;
> > -       ppgtt->vm.vma_ops.clear_pages = clear_pages;
> >  }
> > diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
> > index ac09b685678a..bacc8d68e495 100644
> > --- a/drivers/gpu/drm/i915/i915_vma.c
> > +++ b/drivers/gpu/drm/i915/i915_vma.c
> > @@ -112,7 +112,6 @@ vma_create(struct drm_i915_gem_object *obj,
> >                 return ERR_PTR(-ENOMEM);
> >
> >         kref_init(&vma->ref);
> > -       mutex_init(&vma->pages_mutex);
> >         vma->vm = i915_vm_get(vm);
> >         vma->ops = &vm->vma_ops;
> >         vma->obj = obj;
> > @@ -789,10 +788,343 @@ static bool try_qad_pin(struct i915_vma *vma, unsigned int flags)
> >         return pinned;
> >  }
> >
> > -static int vma_get_pages(struct i915_vma *vma)
> > +
> > +
> > +static struct scatterlist *
> > +rotate_pages(struct drm_i915_gem_object *obj, unsigned int offset,
> > +            unsigned int width, unsigned int height,
> > +            unsigned int src_stride, unsigned int dst_stride,
> > +            struct sg_table *st, struct scatterlist *sg)
> >  {
> > -       int err = 0;
> > -       bool pinned_pages = true;
> > +       unsigned int column, row;
> > +       unsigned int src_idx;
> > +
> > +       for (column = 0; column < width; column++) {
> > +               unsigned int left;
> > +
> > +               src_idx = src_stride * (height - 1) + column + offset;
> > +               for (row = 0; row < height; row++) {
> > +                       st->nents++;
> > +                       /*
> > +                        * We don't need the pages, but need to initialize
> > +                        * the entries so the sg list can be happily traversed.
> > +                        * The only thing we need are DMA addresses.
> > +                        */
> > +                       sg_set_page(sg, NULL, I915_GTT_PAGE_SIZE, 0);
> > +                       sg_dma_address(sg) =
> > +                               i915_gem_object_get_dma_address(obj, src_idx);
> > +                       sg_dma_len(sg) = I915_GTT_PAGE_SIZE;
> > +                       sg = sg_next(sg);
> > +                       src_idx -= src_stride;
> > +               }
> > +
> > +               left = (dst_stride - height) * I915_GTT_PAGE_SIZE;
> > +
> > +               if (!left)
> > +                       continue;
> > +
> > +               st->nents++;
> > +
> > +               /*
> > +                * The DE ignores the PTEs for the padding tiles, the sg entry
> > +                * here is just a conenience to indicate how many padding PTEs
> > +                * to insert at this spot.
> > +                */
> > +               sg_set_page(sg, NULL, left, 0);
> > +               sg_dma_address(sg) = 0;
> > +               sg_dma_len(sg) = left;
> > +               sg = sg_next(sg);
> > +       }
> > +
> > +       return sg;
> > +}
> > +
> > +static noinline struct sg_table *
> > +intel_rotate_pages(struct intel_rotation_info *rot_info,
> > +                  struct drm_i915_gem_object *obj)
> > +{
> > +       unsigned int size = intel_rotation_info_size(rot_info);
> > +       struct drm_i915_private *i915 = to_i915(obj->base.dev);
> > +       struct sg_table *st;
> > +       struct scatterlist *sg;
> > +       int ret = -ENOMEM;
> > +       int i;
> > +
> > +       /* Allocate target SG list. */
> > +       st = kmalloc(sizeof(*st), GFP_KERNEL);
> > +       if (!st)
> > +               goto err_st_alloc;
> > +
> > +       ret = sg_alloc_table(st, size, GFP_KERNEL);
> > +       if (ret)
> > +               goto err_sg_alloc;
> > +
> > +       st->nents = 0;
> > +       sg = st->sgl;
> > +
> > +       for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++)
> > +               sg = rotate_pages(obj, rot_info->plane[i].offset,
> > +                                 rot_info->plane[i].width, rot_info->plane[i].height,
> > +                                 rot_info->plane[i].src_stride,
> > +                                 rot_info->plane[i].dst_stride,
> > +                                 st, sg);
> > +
> > +       return st;
> > +
> > +err_sg_alloc:
> > +       kfree(st);
> > +err_st_alloc:
> > +
> > +       drm_dbg(&i915->drm, "Failed to create rotated mapping for object size %zu! (%ux%u tiles, %u pages)\n",
> > +               obj->base.size, rot_info->plane[0].width,
> > +               rot_info->plane[0].height, size);
> > +
> > +       return ERR_PTR(ret);
> > +}
> > +
> > +static struct scatterlist *
> > +remap_pages(struct drm_i915_gem_object *obj,
> > +           unsigned int offset, unsigned int alignment_pad,
> > +           unsigned int width, unsigned int height,
> > +           unsigned int src_stride, unsigned int dst_stride,
> > +           struct sg_table *st, struct scatterlist *sg)
> > +{
> > +       unsigned int row;
> > +
> > +       if (alignment_pad) {
> > +               st->nents++;
> > +
> > +               /*
> > +                * The DE ignores the PTEs for the padding tiles, the sg entry
> > +                * here is just a convenience to indicate how many padding PTEs
> > +                * to insert at this spot.
> > +                */
> > +               sg_set_page(sg, NULL, alignment_pad * 4096, 0);
> > +               sg_dma_address(sg) = 0;
> > +               sg_dma_len(sg) = alignment_pad * 4096;
> > +               sg = sg_next(sg);
> > +       }
> > +
> > +       for (row = 0; row < height; row++) {
> > +               unsigned int left = width * I915_GTT_PAGE_SIZE;
> > +
> > +               while (left) {
> > +                       dma_addr_t addr;
> > +                       unsigned int length;
> > +
> > +                       /*
> > +                        * We don't need the pages, but need to initialize
> > +                        * the entries so the sg list can be happily traversed.
> > +                        * The only thing we need are DMA addresses.
> > +                        */
> > +
> > +                       addr = i915_gem_object_get_dma_address_len(obj, offset, &length);
> > +
> > +                       length = min(left, length);
> > +
> > +                       st->nents++;
> > +
> > +                       sg_set_page(sg, NULL, length, 0);
> > +                       sg_dma_address(sg) = addr;
> > +                       sg_dma_len(sg) = length;
> > +                       sg = sg_next(sg);
> > +
> > +                       offset += length / I915_GTT_PAGE_SIZE;
> > +                       left -= length;
> > +               }
> > +
> > +               offset += src_stride - width;
> > +
> > +               left = (dst_stride - width) * I915_GTT_PAGE_SIZE;
> > +
> > +               if (!left)
> > +                       continue;
> > +
> > +               st->nents++;
> > +
> > +               /*
> > +                * The DE ignores the PTEs for the padding tiles, the sg entry
> > +                * here is just a conenience to indicate how many padding PTEs
> > +                * to insert at this spot.
> > +                */
> > +               sg_set_page(sg, NULL, left, 0);
> > +               sg_dma_address(sg) = 0;
> > +               sg_dma_len(sg) = left;
> > +               sg = sg_next(sg);
> > +       }
> > +
> > +       return sg;
> > +}
> > +
> > +static noinline struct sg_table *
> > +intel_remap_pages(struct intel_remapped_info *rem_info,
> > +                 struct drm_i915_gem_object *obj)
> > +{
> > +       unsigned int size = intel_remapped_info_size(rem_info);
> > +       struct drm_i915_private *i915 = to_i915(obj->base.dev);
> > +       struct sg_table *st;
> > +       struct scatterlist *sg;
> > +       unsigned int gtt_offset = 0;
> > +       int ret = -ENOMEM;
> > +       int i;
> > +
> > +       /* Allocate target SG list. */
> > +       st = kmalloc(sizeof(*st), GFP_KERNEL);
> > +       if (!st)
> > +               goto err_st_alloc;
> > +
> > +       ret = sg_alloc_table(st, size, GFP_KERNEL);
> > +       if (ret)
> > +               goto err_sg_alloc;
> > +
> > +       st->nents = 0;
> > +       sg = st->sgl;
> > +
> > +       for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
> > +               unsigned int alignment_pad = 0;
> > +
> > +               if (rem_info->plane_alignment)
> > +                       alignment_pad = ALIGN(gtt_offset, rem_info->plane_alignment) - gtt_offset;
> > +
> > +               sg = remap_pages(obj,
> > +                                rem_info->plane[i].offset, alignment_pad,
> > +                                rem_info->plane[i].width, rem_info->plane[i].height,
> > +                                rem_info->plane[i].src_stride, rem_info->plane[i].dst_stride,
> > +                                st, sg);
> > +
> > +               gtt_offset += alignment_pad +
> > +                             rem_info->plane[i].dst_stride * rem_info->plane[i].height;
> > +       }
> > +
> > +       i915_sg_trim(st);
> > +
> > +       return st;
> > +
> > +err_sg_alloc:
> > +       kfree(st);
> > +err_st_alloc:
> > +
> > +       drm_dbg(&i915->drm, "Failed to create remapped mapping for object size %zu! (%ux%u tiles, %u pages)\n",
> > +               obj->base.size, rem_info->plane[0].width,
> > +               rem_info->plane[0].height, size);
> > +
> > +       return ERR_PTR(ret);
> > +}
> > +
> > +static noinline struct sg_table *
> > +intel_partial_pages(const struct i915_ggtt_view *view,
> > +                   struct drm_i915_gem_object *obj)
> > +{
> > +       struct sg_table *st;
> > +       struct scatterlist *sg, *iter;
> > +       unsigned int count = view->partial.size;
> > +       unsigned int offset;
> > +       int ret = -ENOMEM;
> > +
> > +       st = kmalloc(sizeof(*st), GFP_KERNEL);
> > +       if (!st)
> > +               goto err_st_alloc;
> > +
> > +       ret = sg_alloc_table(st, count, GFP_KERNEL);
> > +       if (ret)
> > +               goto err_sg_alloc;
> > +
> > +       iter = i915_gem_object_get_sg_dma(obj, view->partial.offset, &offset);
> > +       GEM_BUG_ON(!iter);
> > +
> > +       sg = st->sgl;
> > +       st->nents = 0;
> > +       do {
> > +               unsigned int len;
> > +
> > +               len = min(sg_dma_len(iter) - (offset << PAGE_SHIFT),
> > +                         count << PAGE_SHIFT);
> > +               sg_set_page(sg, NULL, len, 0);
> > +               sg_dma_address(sg) =
> > +                       sg_dma_address(iter) + (offset << PAGE_SHIFT);
> > +               sg_dma_len(sg) = len;
> > +
> > +               st->nents++;
> > +               count -= len >> PAGE_SHIFT;
> > +               if (count == 0) {
> > +                       sg_mark_end(sg);
> > +                       i915_sg_trim(st); /* Drop any unused tail entries. */
> > +
> > +                       return st;
> > +               }
> > +
> > +               sg = __sg_next(sg);
> > +               iter = __sg_next(iter);
> > +               offset = 0;
> > +       } while (1);
> > +
> > +err_sg_alloc:
> > +       kfree(st);
> > +err_st_alloc:
> > +       return ERR_PTR(ret);
> > +}
> > +
> > +static int
> > +__i915_vma_get_pages(struct i915_vma *vma)
> > +{
> > +       struct sg_table *pages;
> > +       int ret;
> > +
> > +       /*
> > +        * The vma->pages are only valid within the lifespan of the borrowed
> > +        * obj->mm.pages. When the obj->mm.pages sg_table is regenerated, so
> > +        * must be the vma->pages. A simple rule is that vma->pages must only
> > +        * be accessed when the obj->mm.pages are pinned.
> > +        */
> > +       GEM_BUG_ON(!i915_gem_object_has_pinned_pages(vma->obj));
> > +
> > +       switch (vma->ggtt_view.type) {
> > +       default:
> > +               GEM_BUG_ON(vma->ggtt_view.type);
> > +               fallthrough;
> > +       case I915_GGTT_VIEW_NORMAL:
> > +               pages = vma->obj->mm.pages;
> > +               break;
> > +
> > +       case I915_GGTT_VIEW_ROTATED:
> > +               pages =
> > +                       intel_rotate_pages(&vma->ggtt_view.rotated, vma->obj);
> > +               break;
> > +
> > +       case I915_GGTT_VIEW_REMAPPED:
> > +               pages =
> > +                       intel_remap_pages(&vma->ggtt_view.remapped, vma->obj);
> > +               break;
> > +
> > +       case I915_GGTT_VIEW_PARTIAL:
> > +               pages = intel_partial_pages(&vma->ggtt_view, vma->obj);
> > +               break;
> > +       }
> > +
> > +       ret = 0;
> > +       /* gen6 ppgtt doesn't have backing pages, special-case it */
> > +       if (IS_ERR(pages) && pages != ERR_PTR(-ENODEV)) {
>
> Where does this -ENODEV come from? AFAIK for the gen6 thing mm.pages =
> ZERO_SIZE_PTR. Also, just checking, I assume we always hit the
> VIEW_NORMAL for that?
>
> > +               ret = PTR_ERR(pages);
> > +               pages = NULL;
> > +               drm_err(&vma->vm->i915->drm,
> > +                       "Failed to get pages for VMA view type %u (%d)!\n",
> > +                       vma->ggtt_view.type, ret);
>
> Can we just return here?
>
> > +       }
> > +
> > +       pages = xchg(&vma->pages, pages);
> > +
> > +       /* did we race against a put_pages? */
> > +       if (pages && pages != vma->obj->mm.pages) {
> > +               sg_free_table(vma->pages);
> > +               kfree(vma->pages);
> > +       }
>
> What is this race exactly, can we add some more details here please?
> So we can more easily evaluate the lockless trickery here.

Ok, the lockless stuff just gets removed by the end of the series.

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [PATCH 08/28] drm/i915: Create a full object for mock_ring, v2.
  2021-10-21 15:57     ` [Intel-gfx] " Matthew Auld
@ 2021-10-22 11:03       ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-22 11:03 UTC (permalink / raw)
  To: Matthew Auld; +Cc: Intel Graphics Development, ML dri-devel

Op 21-10-2021 om 17:57 schreef Matthew Auld:
> On Thu, 21 Oct 2021 at 11:36, Maarten Lankhorst
> <maarten.lankhorst@linux.intel.com> wrote:
>> This allows us to finally get rid of all the assumptions that vma->obj is NULL.
>>
>> Changes since v1:
>> - Ensure the mock_ring vma is pinned to prevent a fault.
>> - Pin it high to avoid failure in evict_for_vma selftest.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/gt/mock_engine.c | 38 ++++++++++++++++++++-------
>>  1 file changed, 28 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gt/mock_engine.c b/drivers/gpu/drm/i915/gt/mock_engine.c
>> index 8b89215afe46..bb99fc03f503 100644
>> --- a/drivers/gpu/drm/i915/gt/mock_engine.c
>> +++ b/drivers/gpu/drm/i915/gt/mock_engine.c
>> @@ -35,9 +35,31 @@ static void mock_timeline_unpin(struct intel_timeline *tl)
>>         atomic_dec(&tl->pin_count);
>>  }
>>
>> +static struct i915_vma *create_ring_vma(struct i915_ggtt *ggtt, int size)
>> +{
>> +       struct i915_address_space *vm = &ggtt->vm;
>> +       struct drm_i915_private *i915 = vm->i915;
>> +       struct drm_i915_gem_object *obj;
>> +       struct i915_vma *vma;
>> +
>> +       obj = i915_gem_object_create_internal(i915, size);
>> +       if (IS_ERR(obj))
>> +               return ERR_CAST(obj);
> We didn't want to use the dummy object here also? I guess meh?
>
>> +
>> +       vma = i915_vma_instance(obj, vm, NULL);
>> +       if (IS_ERR(vma))
>> +               goto err;
>> +
>> +       return vma;
>> +
>> +err:
>> +       i915_gem_object_put(obj);
>> +       return vma;
>> +}
>> +
>>  static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
>>  {
>> -       const unsigned long sz = PAGE_SIZE / 2;
>> +       const unsigned long sz = PAGE_SIZE;
> Is that significant?
>
> Reviewed-by: Matthew Auld <matthew.auld@intel.com>
>

vma->node.size has to be page aligned, since we create an actual vma, it was required to bump the size.

~Maarten

>>         struct intel_ring *ring;
>>
>>         ring = kzalloc(sizeof(*ring) + sz, GFP_KERNEL);
>> @@ -50,15 +72,11 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
>>         ring->vaddr = (void *)(ring + 1);
>>         atomic_set(&ring->pin_count, 1);
>>
>> -       ring->vma = i915_vma_alloc();
>> -       if (!ring->vma) {
>> +       ring->vma = create_ring_vma(engine->gt->ggtt, PAGE_SIZE);
>> +       if (IS_ERR(ring->vma)) {
>>                 kfree(ring);
>>                 return NULL;
>>         }
>> -       i915_active_init(&ring->vma->active, NULL, NULL, 0);
>> -       __set_bit(I915_VMA_GGTT_BIT, __i915_vma_flags(ring->vma));
>> -       __set_bit(DRM_MM_NODE_ALLOCATED_BIT, &ring->vma->node.flags);
>> -       ring->vma->node.size = sz;
>>
>>         intel_ring_update_space(ring);
>>
>> @@ -67,8 +85,7 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
>>
>>  static void mock_ring_free(struct intel_ring *ring)
>>  {
>> -       i915_active_fini(&ring->vma->active);
>> -       i915_vma_free(ring->vma);
>> +       i915_vma_put(ring->vma);
>>
>>         kfree(ring);
>>  }
>> @@ -125,6 +142,7 @@ static void mock_context_unpin(struct intel_context *ce)
>>
>>  static void mock_context_post_unpin(struct intel_context *ce)
>>  {
>> +       i915_vma_unpin(ce->ring->vma);
>>  }
>>
>>  static void mock_context_destroy(struct kref *ref)
>> @@ -169,7 +187,7 @@ static int mock_context_alloc(struct intel_context *ce)
>>  static int mock_context_pre_pin(struct intel_context *ce,
>>                                 struct i915_gem_ww_ctx *ww, void **unused)
>>  {
>> -       return 0;
>> +       return i915_vma_pin_ww(ce->ring->vma, ww, 0, 0, PIN_GLOBAL | PIN_HIGH);
>>  }
>>
>>  static int mock_context_pin(struct intel_context *ce, void *unused)
>> --
>> 2.33.0
>>


^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 08/28] drm/i915: Create a full object for mock_ring, v2.
@ 2021-10-22 11:03       ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-22 11:03 UTC (permalink / raw)
  To: Matthew Auld; +Cc: Intel Graphics Development, ML dri-devel

Op 21-10-2021 om 17:57 schreef Matthew Auld:
> On Thu, 21 Oct 2021 at 11:36, Maarten Lankhorst
> <maarten.lankhorst@linux.intel.com> wrote:
>> This allows us to finally get rid of all the assumptions that vma->obj is NULL.
>>
>> Changes since v1:
>> - Ensure the mock_ring vma is pinned to prevent a fault.
>> - Pin it high to avoid failure in evict_for_vma selftest.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/gt/mock_engine.c | 38 ++++++++++++++++++++-------
>>  1 file changed, 28 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gt/mock_engine.c b/drivers/gpu/drm/i915/gt/mock_engine.c
>> index 8b89215afe46..bb99fc03f503 100644
>> --- a/drivers/gpu/drm/i915/gt/mock_engine.c
>> +++ b/drivers/gpu/drm/i915/gt/mock_engine.c
>> @@ -35,9 +35,31 @@ static void mock_timeline_unpin(struct intel_timeline *tl)
>>         atomic_dec(&tl->pin_count);
>>  }
>>
>> +static struct i915_vma *create_ring_vma(struct i915_ggtt *ggtt, int size)
>> +{
>> +       struct i915_address_space *vm = &ggtt->vm;
>> +       struct drm_i915_private *i915 = vm->i915;
>> +       struct drm_i915_gem_object *obj;
>> +       struct i915_vma *vma;
>> +
>> +       obj = i915_gem_object_create_internal(i915, size);
>> +       if (IS_ERR(obj))
>> +               return ERR_CAST(obj);
> We didn't want to use the dummy object here also? I guess meh?
>
>> +
>> +       vma = i915_vma_instance(obj, vm, NULL);
>> +       if (IS_ERR(vma))
>> +               goto err;
>> +
>> +       return vma;
>> +
>> +err:
>> +       i915_gem_object_put(obj);
>> +       return vma;
>> +}
>> +
>>  static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
>>  {
>> -       const unsigned long sz = PAGE_SIZE / 2;
>> +       const unsigned long sz = PAGE_SIZE;
> Is that significant?
>
> Reviewed-by: Matthew Auld <matthew.auld@intel.com>
>

vma->node.size has to be page aligned, since we create an actual vma, it was required to bump the size.

~Maarten

>>         struct intel_ring *ring;
>>
>>         ring = kzalloc(sizeof(*ring) + sz, GFP_KERNEL);
>> @@ -50,15 +72,11 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
>>         ring->vaddr = (void *)(ring + 1);
>>         atomic_set(&ring->pin_count, 1);
>>
>> -       ring->vma = i915_vma_alloc();
>> -       if (!ring->vma) {
>> +       ring->vma = create_ring_vma(engine->gt->ggtt, PAGE_SIZE);
>> +       if (IS_ERR(ring->vma)) {
>>                 kfree(ring);
>>                 return NULL;
>>         }
>> -       i915_active_init(&ring->vma->active, NULL, NULL, 0);
>> -       __set_bit(I915_VMA_GGTT_BIT, __i915_vma_flags(ring->vma));
>> -       __set_bit(DRM_MM_NODE_ALLOCATED_BIT, &ring->vma->node.flags);
>> -       ring->vma->node.size = sz;
>>
>>         intel_ring_update_space(ring);
>>
>> @@ -67,8 +85,7 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
>>
>>  static void mock_ring_free(struct intel_ring *ring)
>>  {
>> -       i915_active_fini(&ring->vma->active);
>> -       i915_vma_free(ring->vma);
>> +       i915_vma_put(ring->vma);
>>
>>         kfree(ring);
>>  }
>> @@ -125,6 +142,7 @@ static void mock_context_unpin(struct intel_context *ce)
>>
>>  static void mock_context_post_unpin(struct intel_context *ce)
>>  {
>> +       i915_vma_unpin(ce->ring->vma);
>>  }
>>
>>  static void mock_context_destroy(struct kref *ref)
>> @@ -169,7 +187,7 @@ static int mock_context_alloc(struct intel_context *ce)
>>  static int mock_context_pre_pin(struct intel_context *ce,
>>                                 struct i915_gem_ww_ctx *ww, void **unused)
>>  {
>> -       return 0;
>> +       return i915_vma_pin_ww(ce->ring->vma, ww, 0, 0, PIN_GLOBAL | PIN_HIGH);
>>  }
>>
>>  static int mock_context_pin(struct intel_context *ce, void *unused)
>> --
>> 2.33.0
>>


^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 10/28] drm/i915: Change shrink ordering to use locking around unbinding.
  2021-10-21 16:12   ` [Intel-gfx] " Matthew Auld
@ 2021-10-22 11:04     ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-22 11:04 UTC (permalink / raw)
  To: Matthew Auld
  Cc: Intel Graphics Development, ML dri-devel, Niranjana Vishwanathapura

Op 21-10-2021 om 18:12 schreef Matthew Auld:
> On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
> <maarten.lankhorst@linux.intel.com> wrote:
>> Call drop_pages with the gem object lock held, instead of the other
>> way around. This will allow us to drop the vma bindings with the
>> gem object lock held.
>>
>> We plan to require the object lock for unpinning in the future,
>> and this is an easy target.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> Reviewed-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
>> ---
>>  drivers/gpu/drm/i915/gem/i915_gem_shrinker.c | 42 ++++++++++----------
>>  1 file changed, 22 insertions(+), 20 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
>> index af3eb7fd951d..d3f29a66cb36 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
>> @@ -36,8 +36,8 @@ static bool can_release_pages(struct drm_i915_gem_object *obj)
>>         return swap_available() || obj->mm.madv == I915_MADV_DONTNEED;
>>  }
>>
>> -static bool unsafe_drop_pages(struct drm_i915_gem_object *obj,
>> -                             unsigned long shrink, bool trylock_vm)
>> +static int drop_pages(struct drm_i915_gem_object *obj,
>> +                      unsigned long shrink, bool trylock_vm)
>>  {
>>         unsigned long flags;
>>
>> @@ -208,26 +208,28 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww,
>>
>>                         spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
>>
>> -                       err = 0;
>> -                       if (unsafe_drop_pages(obj, shrink, trylock_vm)) {
>> -                               /* May arrive from get_pages on another bo */
>> -                               if (!ww) {
>> -                                       if (!i915_gem_object_trylock(obj))
>> -                                               goto skip;
>> -                               } else {
>> -                                       err = i915_gem_object_lock(obj, ww);
>> -                                       if (err)
>> -                                               goto skip;
>> -                               }
>> -
>> -                               if (!__i915_gem_object_put_pages(obj)) {
>> -                                       try_to_writeback(obj, shrink);
>> -                                       count += obj->base.size >> PAGE_SHIFT;
>> -                               }
>> -                               if (!ww)
>> -                                       i915_gem_object_unlock(obj);
>> +                       /* May arrive from get_pages on another bo */
>> +                       if (!ww) {
>> +                               if (!i915_gem_object_trylock(obj))
>> +                                       goto skip;
>> +                       } else {
>> +                               err = i915_gem_object_lock(obj, ww);
>> +                               if (err)
>> +                                       goto skip;
>>                         }
>>
>> +                       if (drop_pages(obj, shrink, trylock_vm) &&
>> +                           !__i915_gem_object_put_pages(obj)) {
>> +                               try_to_writeback(obj, shrink);
>> +                               count += obj->base.size >> PAGE_SHIFT;
>> +                       }
>> +
>> +                       if (dma_resv_test_signaled(obj->base.resv, true))
>> +                               dma_resv_add_excl_fence(obj->base.resv, NULL);
> I assume we want to rip out resv_prune here in the series, or
> something? Instead of randomly adding this back here.
Oh yeah, this hunk can be removed safely. It's stale and shouldn't be here. :)
>> +
>> +                       if (!ww)
>> +                               i915_gem_object_unlock(obj);
>> +
>>                         scanned += obj->base.size >> PAGE_SHIFT;
>>  skip:
>>                         i915_gem_object_put(obj);
>> --
>> 2.33.0
>>


^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 25/28] drm/i915: Require object lock when freeing pages during destruction
  2021-10-21 10:36   ` [Intel-gfx] " Maarten Lankhorst
  (?)
@ 2021-10-22 11:10   ` Matthew Auld
  -1 siblings, 0 replies; 114+ messages in thread
From: Matthew Auld @ 2021-10-22 11:10 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Intel Graphics Development, ML dri-devel

On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
>
> TTM already requires this, and we require it for delayed destroy.
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx]  ✗ Fi.CI.IGT: failure for series starting with [01/28] drm/i915: Fix i915_request fence wait semantics
  2021-10-21 12:57 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork
@ 2021-10-22 11:24   ` Matthew Auld
  2021-10-22 13:17     ` Maarten Lankhorst
  0 siblings, 1 reply; 114+ messages in thread
From: Matthew Auld @ 2021-10-22 11:24 UTC (permalink / raw)
  To: Intel Graphics Development; +Cc: Maarten Lankhorst

[-- Attachment #1: Type: text/plain, Size: 30770 bytes --]

On Thu, 21 Oct 2021 at 13:57, Patchwork <patchwork@emeril.freedesktop.org>
wrote:

> *Patch Details*
> *Series:* series starting with [01/28] drm/i915: Fix i915_request fence
> wait semantics
> *URL:* https://patchwork.freedesktop.org/series/96115/
> *State:* failure
> *Details:*
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/index.html CI
> Bug Log - changes from CI_DRM_10768_full -> Patchwork_21402_full Summary
>
> *FAILURE*
>
> Serious unknown changes coming with Patchwork_21402_full absolutely need
> to be
> verified manually.
>
> If you think the reported changes have nothing to do with the changes
> introduced in Patchwork_21402_full, please notify your bug team to allow
> them
> to document this new failure mode, which will reduce false positives in CI.
> Possible new issues
>
> Here are the unknown changes that may have been introduced in
> Patchwork_21402_full:
> IGT changes Possible regressions
>
>    -
>
>    igt@gem_linear_blits@normal:
>    - shard-glk: PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-glk4/igt@gem_linear_blits@normal.html>
>       -> FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-glk4/igt@gem_linear_blits@normal.html>
>    -
>
>    igt@gem_mmap_gtt@cpuset-big-copy-xy:
>    - shard-iclb: NOTRUN -> INCOMPLETE
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb3/igt@gem_mmap_gtt@cpuset-big-copy-xy.html>
>    -
>
>    igt@gem_ppgtt@blt-vs-render-ctxn:
>    - shard-tglb: PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-tglb5/igt@gem_ppgtt@blt-vs-render-ctxn.html>
>       -> FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb8/igt@gem_ppgtt@blt-vs-render-ctxn.html>
>       +1 similar issue
>
>
Maarten, do you know if these failures are related to this series? Perhaps
the last one?


>
>    -
>
> Known issues
>
> Here are the changes found in Patchwork_21402_full that come from known
> issues:
> IGT changes Issues hit
>
>    -
>
>    igt@feature_discovery@display-2x:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb1/igt@feature_discovery@display-2x.html>
>       ([i915#1839])
>    -
>
>    igt@gem_create@create-massive:
>    - shard-snb: NOTRUN -> DMESG-WARN
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-snb2/igt@gem_create@create-massive.html>
>       ([i915#3002])
>    -
>
>    igt@gem_ctx_isolation@preservation-s3@rcs0:
>    - shard-tglb: PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-tglb8/igt@gem_ctx_isolation@preservation-s3@rcs0.html>
>       -> INCOMPLETE
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb7/igt@gem_ctx_isolation@preservation-s3@rcs0.html>
>       ([i915#1373])
>    -
>
>    igt@gem_ctx_isolation@preservation-s3@vcs0:
>    - shard-kbl: PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-kbl7/igt@gem_ctx_isolation@preservation-s3@vcs0.html>
>       -> DMESG-WARN
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@gem_ctx_isolation@preservation-s3@vcs0.html>
>       ([i915#180]) +3 similar issues
>    -
>
>    igt@gem_ctx_isolation@preservation-s3@vecs0:
>    - shard-skl: PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl3/igt@gem_ctx_isolation@preservation-s3@vecs0.html>
>       -> INCOMPLETE
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl1/igt@gem_ctx_isolation@preservation-s3@vecs0.html>
>       ([i915#198])
>    -
>
>    igt@gem_ctx_persistence@idempotent:
>    - shard-snb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-snb2/igt@gem_ctx_persistence@idempotent.html>
>       ([fdo#109271] / [i915#1099]) +4 similar issues
>    -
>
>    igt@gem_exec_fair@basic-none-solo@rcs0:
>    - shard-glk: PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-glk5/igt@gem_exec_fair@basic-none-solo@rcs0.html>
>       -> FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-glk7/igt@gem_exec_fair@basic-none-solo@rcs0.html>
>       ([i915#2842])
>    -
>
>    igt@gem_exec_fair@basic-pace@bcs0:
>    - shard-tglb: PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-tglb1/igt@gem_exec_fair@basic-pace@bcs0.html>
>       -> FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb2/igt@gem_exec_fair@basic-pace@bcs0.html>
>       ([i915#2842]) +2 similar issues
>    -
>
>    igt@gem_exec_fair@basic-pace@vecs0:
>    - shard-kbl: PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-kbl2/igt@gem_exec_fair@basic-pace@vecs0.html>
>       -> FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl2/igt@gem_exec_fair@basic-pace@vecs0.html>
>       ([i915#2842]) +2 similar issues
>    -
>
>    igt@gem_exec_params@no-vebox:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@gem_exec_params@no-vebox.html>
>       ([fdo#109283])
>    -
>
>    igt@gem_pwrite@basic-exhaustion:
>    - shard-kbl: NOTRUN -> WARN
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@gem_pwrite@basic-exhaustion.html>
>       ([i915#2658])
>    -
>
>    igt@gem_pxp@dmabuf-shared-protected-dst-is-context-refcounted:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@gem_pxp@dmabuf-shared-protected-dst-is-context-refcounted.html>
>       ([i915#4270])
>    -
>
>    igt@gem_userptr_blits@readonly-unsync:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@gem_userptr_blits@readonly-unsync.html>
>       ([i915#3297])
>    -
>
>    igt@gen7_exec_parse@basic-rejected:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@gen7_exec_parse@basic-rejected.html>
>       ([fdo#109289]) +2 similar issues
>    -
>
>    igt@gen9_exec_parse@cmd-crossing-page:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@gen9_exec_parse@cmd-crossing-page.html>
>       ([i915#2856]) +2 similar issues
>    -
>
>    igt@i915_pm_dc@dc6-psr:
>    - shard-iclb: PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb1/igt@i915_pm_dc@dc6-psr.html>
>       -> FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb3/igt@i915_pm_dc@dc6-psr.html>
>       ([i915#454])
>    -
>
>    igt@i915_pm_lpsp@kms-lpsp@kms-lpsp-dp:
>    - shard-kbl: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@i915_pm_lpsp@kms-lpsp@kms-lpsp-dp.html>
>       ([fdo#109271] / [i915#1937])
>    -
>
>    igt@i915_pm_rpm@dpms-non-lpsp:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@i915_pm_rpm@dpms-non-lpsp.html>
>       ([fdo#111644] / [i915#1397] / [i915#2411])
>    -
>
>    igt@i915_pm_rpm@gem-execbuf-stress-pc8:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@i915_pm_rpm@gem-execbuf-stress-pc8.html>
>       ([fdo#109506] / [i915#2411])
>    -
>
>    igt@i915_suspend@fence-restore-untiled:
>    - shard-apl: PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-apl8/igt@i915_suspend@fence-restore-untiled.html>
>       -> DMESG-WARN
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl1/igt@i915_suspend@fence-restore-untiled.html>
>       ([i915#180]) +1 similar issue
>    -
>
>    igt@kms_big_fb@linear-16bpp-rotate-90:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@kms_big_fb@linear-16bpp-rotate-90.html>
>       ([fdo#111614]) +1 similar issue
>    -
>
>    igt@kms_big_fb@linear-32bpp-rotate-0:
>    - shard-glk: PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-glk7/igt@kms_big_fb@linear-32bpp-rotate-0.html>
>       -> DMESG-WARN
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-glk5/igt@kms_big_fb@linear-32bpp-rotate-0.html>
>       ([i915#118])
>    -
>
>    igt@kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-0-hflip:
>    - shard-kbl: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-0-hflip.html>
>       ([fdo#109271] / [i915#3777])
>    -
>
>    igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-180-hflip:
>    - shard-apl: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl3/igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-180-hflip.html>
>       ([fdo#109271] / [i915#3777])
>    -
>
>    igt@kms_big_fb@yf-tiled-16bpp-rotate-90:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_big_fb@yf-tiled-16bpp-rotate-90.html>
>       ([fdo#111615]) +2 similar issues
>    -
>
>    igt@kms_big_joiner@invalid-modeset:
>    - shard-skl: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl7/igt@kms_big_joiner@invalid-modeset.html>
>       ([fdo#109271]) +19 similar issues
>    -
>
>    igt@kms_ccs@pipe-a-bad-rotation-90-y_tiled_gen12_rc_ccs_cc:
>    - shard-kbl: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_ccs@pipe-a-bad-rotation-90-y_tiled_gen12_rc_ccs_cc.html>
>       ([fdo#109271] / [i915#3886]) +1 similar issue
>    -
>
>    igt@kms_ccs@pipe-a-ccs-on-another-bo-y_tiled_gen12_rc_ccs_cc:
>    - shard-apl: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl7/igt@kms_ccs@pipe-a-ccs-on-another-bo-y_tiled_gen12_rc_ccs_cc.html>
>       ([fdo#109271] / [i915#3886]) +4 similar issues
>    -
>
>    igt@kms_ccs@pipe-a-missing-ccs-buffer-y_tiled_gen12_rc_ccs_cc:
>    - shard-skl: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl7/igt@kms_ccs@pipe-a-missing-ccs-buffer-y_tiled_gen12_rc_ccs_cc.html>
>       ([fdo#109271] / [i915#3886])
>    -
>
>    igt@kms_ccs@pipe-b-bad-rotation-90-y_tiled_ccs:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_ccs@pipe-b-bad-rotation-90-y_tiled_ccs.html>
>       ([i915#3689]) +6 similar issues
>    -
>
>    igt@kms_ccs@pipe-c-bad-rotation-90-y_tiled_gen12_mc_ccs:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_ccs@pipe-c-bad-rotation-90-y_tiled_gen12_mc_ccs.html>
>       ([i915#3689] / [i915#3886]) +1 similar issue
>    -
>
>    igt@kms_ccs@pipe-d-missing-ccs-buffer-y_tiled_gen12_rc_ccs:
>    - shard-kbl: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_ccs@pipe-d-missing-ccs-buffer-y_tiled_gen12_rc_ccs.html>
>       ([fdo#109271]) +33 similar issues
>    -
>
>    igt@kms_chamelium@hdmi-mode-timings:
>    - shard-snb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-snb2/igt@kms_chamelium@hdmi-mode-timings.html>
>       ([fdo#109271] / [fdo#111827]) +13 similar issues
>    -
>
>    igt@kms_color@pipe-a-ctm-0-75:
>    - shard-skl: PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl7/igt@kms_color@pipe-a-ctm-0-75.html>
>       -> DMESG-WARN
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl10/igt@kms_color@pipe-a-ctm-0-75.html>
>       ([i915#1982]) +2 similar issues
>    -
>
>    igt@kms_color_chamelium@pipe-a-ctm-green-to-red:
>    - shard-skl: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl7/igt@kms_color_chamelium@pipe-a-ctm-green-to-red.html>
>       ([fdo#109271] / [fdo#111827])
>    -
>
>    igt@kms_color_chamelium@pipe-b-ctm-limited-range:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_color_chamelium@pipe-b-ctm-limited-range.html>
>       ([fdo#109284] / [fdo#111827]) +5 similar issues
>    -
>
>    igt@kms_color_chamelium@pipe-b-ctm-red-to-blue:
>    - shard-apl: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl3/igt@kms_color_chamelium@pipe-b-ctm-red-to-blue.html>
>       ([fdo#109271] / [fdo#111827]) +10 similar issues
>    -
>
>    igt@kms_color_chamelium@pipe-c-ctm-red-to-blue:
>    - shard-kbl: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_color_chamelium@pipe-c-ctm-red-to-blue.html>
>       ([fdo#109271] / [fdo#111827]) +1 similar issue
>    -
>
>    igt@kms_content_protection@atomic:
>    - shard-apl: NOTRUN -> TIMEOUT
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl7/igt@kms_content_protection@atomic.html>
>       ([i915#1319])
>    -
>
>    igt@kms_content_protection@atomic-dpms:
>    - shard-kbl: NOTRUN -> TIMEOUT
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_content_protection@atomic-dpms.html>
>       ([i915#1319])
>    -
>
>    igt@kms_content_protection@dp-mst-type-0:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_content_protection@dp-mst-type-0.html>
>       ([i915#3116])
>    -
>
>    igt@kms_cursor_crc@pipe-b-cursor-max-size-onscreen:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@kms_cursor_crc@pipe-b-cursor-max-size-onscreen.html>
>       ([i915#3359]) +3 similar issues
>    -
>
>    igt@kms_cursor_crc@pipe-d-cursor-512x170-random:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_cursor_crc@pipe-d-cursor-512x170-random.html>
>       ([fdo#109279] / [i915#3359]) +7 similar issues
>    -
>
>    igt@kms_cursor_edge_walk@pipe-d-128x128-right-edge:
>    - shard-snb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-snb7/igt@kms_cursor_edge_walk@pipe-d-128x128-right-edge.html>
>       ([fdo#109271]) +281 similar issues
>    -
>
>    igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy:
>    - shard-iclb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb3/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy.html>
>       ([fdo#109274] / [fdo#109278])
>    -
>
>    igt@kms_cursor_legacy@pipe-d-torture-bo:
>    - shard-apl: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl7/igt@kms_cursor_legacy@pipe-d-torture-bo.html>
>       ([fdo#109271] / [i915#533])
>    -
>
>    igt@kms_cursor_legacy
>    @short-busy-flip-before-cursor-atomic-transitions-varying-size:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_cursor_legacy@short-busy-flip-before-cursor-atomic-transitions-varying-size.html>
>       ([i915#4103])
>    -
>
>    igt@kms_dp_tiled_display@basic-test-pattern-with-chamelium:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb1/igt@kms_dp_tiled_display@basic-test-pattern-with-chamelium.html>
>       ([i915#3528])
>    -
>
>    igt@kms_flip@2x-flip-vs-expired-vblank-interruptible@bc-hdmi-a1-hdmi-a2
>    :
>    - shard-glk: PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-glk5/igt@kms_flip@2x-flip-vs-expired-vblank-interruptible@bc-hdmi-a1-hdmi-a2.html>
>       -> FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-glk7/igt@kms_flip@2x-flip-vs-expired-vblank-interruptible@bc-hdmi-a1-hdmi-a2.html>
>       ([i915#79]) +1 similar issue
>    -
>
>    igt@kms_flip@flip-vs-suspend-interruptible@c-dp1:
>    - shard-kbl: NOTRUN -> DMESG-WARN
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_flip@flip-vs-suspend-interruptible@c-dp1.html>
>       ([i915#180]) +1 similar issue
>    -
>
>    igt@kms_flip@flip-vs-suspend@a-dp1:
>    - shard-apl: NOTRUN -> DMESG-WARN
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl3/igt@kms_flip@flip-vs-suspend@a-dp1.html>
>       ([i915#180])
>    -
>
>    igt@kms_flip@plain-flip-ts-check-interruptible@b-edp1:
>    - shard-skl: PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl9/igt@kms_flip@plain-flip-ts-check-interruptible@b-edp1.html>
>       -> FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl5/igt@kms_flip@plain-flip-ts-check-interruptible@b-edp1.html>
>       ([i915#2122])
>    -
>
>    igt@kms_frontbuffer_tracking
>    @fbcpsr-2p-primscrn-spr-indfb-draw-mmap-gtt:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-spr-indfb-draw-mmap-gtt.html>
>       ([fdo#111825]) +26 similar issues
>    -
>
>    igt@kms_pipe_crc_basic@suspend-read-crc-pipe-c:
>    - shard-tglb: PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-tglb3/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-c.html>
>       -> INCOMPLETE
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb7/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-c.html>
>       ([i915#2828] / [i915#456])
>    -
>
>    igt@kms_plane_alpha_blend@pipe-a-alpha-7efc:
>    - shard-skl: NOTRUN -> FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl7/igt@kms_plane_alpha_blend@pipe-a-alpha-7efc.html>
>       ([fdo#108145] / [i915#265])
>    -
>
>    igt@kms_plane_alpha_blend@pipe-a-alpha-transparent-fb:
>    - shard-apl: NOTRUN -> FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl7/igt@kms_plane_alpha_blend@pipe-a-alpha-transparent-fb.html>
>       ([i915#265])
>    -
>
>    igt@kms_plane_alpha_blend@pipe-c-alpha-basic:
>    - shard-kbl: NOTRUN -> FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_plane_alpha_blend@pipe-c-alpha-basic.html>
>       ([fdo#108145] / [i915#265]) +1 similar issue
>    -
>
>    igt@kms_plane_alpha_blend@pipe-c-coverage-7efc:
>    - shard-skl: PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl10/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html>
>       -> FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl3/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html>
>       ([fdo#108145] / [i915#265]) +1 similar issue
>    -
>
>    igt@kms_plane_lowres@pipe-b-tiling-y:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_plane_lowres@pipe-b-tiling-y.html>
>       ([i915#3536])
>    -
>
>    igt@kms_plane_lowres@pipe-d-tiling-yf:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_plane_lowres@pipe-d-tiling-yf.html>
>       ([fdo#112054]) +1 similar issue
>    -
>
>    igt@kms_psr2_sf@plane-move-sf-dmg-area-1:
>    - shard-kbl: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_psr2_sf@plane-move-sf-dmg-area-1.html>
>       ([fdo#109271] / [i915#658]) +1 similar issue
>    -
>
>    igt@kms_psr2_sf@plane-move-sf-dmg-area-2:
>    - shard-apl: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl3/igt@kms_psr2_sf@plane-move-sf-dmg-area-2.html>
>       ([fdo#109271] / [i915#658]) +3 similar issues
>    -
>
>    igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-1:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-1.html>
>       ([i915#2920]) +2 similar issues
>    -
>
>    igt@kms_psr2_su@page_flip:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb1/igt@kms_psr2_su@page_flip.html>
>       ([i915#1911])
>    -
>
>    igt@kms_psr@psr2_suspend:
>    -
>
>       shard-iclb: PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb2/igt@kms_psr@psr2_suspend.html>
>       -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb7/igt@kms_psr@psr2_suspend.html>
>       ([fdo#109441])
>       -
>
>       shard-tglb: NOTRUN -> FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@kms_psr@psr2_suspend.html>
>       ([i915#132] / [i915#3467])
>       -
>
>    igt@kms_vblank@pipe-b-ts-continuation-dpms-suspend:
>    - shard-skl: PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl5/igt@kms_vblank@pipe-b-ts-continuation-dpms-suspend.html>
>       -> INCOMPLETE
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl5/igt@kms_vblank@pipe-b-ts-continuation-dpms-suspend.html>
>       ([i915#198] / [i915#2828])
>    -
>
>    igt@kms_vblank@pipe-d-ts-continuation-idle:
>    - shard-apl: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl3/igt@kms_vblank@pipe-d-ts-continuation-idle.html>
>       ([fdo#109271]) +93 similar issues
>    -
>
>    igt@nouveau_crc@pipe-a-ctx-flip-detection:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@nouveau_crc@pipe-a-ctx-flip-detection.html>
>       ([i915#2530]) +2 similar issues
>    -
>
>    igt@perf_pmu@event-wait@rcs0:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@perf_pmu@event-wait@rcs0.html>
>       ([fdo#112283])
>    -
>
>    igt@prime_nv_pcopy@test3_5:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@prime_nv_pcopy@test3_5.html>
>       ([fdo#109291])
>    -
>
>    igt@prime_vgem@fence-write-hang:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@prime_vgem@fence-write-hang.html>
>       ([fdo#109295])
>    -
>
>    igt@sysfs_clients@create:
>    - shard-apl: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl7/igt@sysfs_clients@create.html>
>       ([fdo#109271] / [i915#2994]) +1 similar issue
>    -
>
>    igt@sysfs_clients@fair-0:
>    - shard-tglb: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb1/igt@sysfs_clients@fair-0.html>
>       ([i915#2994])
>    -
>
>    igt@sysfs_clients@sema-10:
>    - shard-skl: NOTRUN -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl7/igt@sysfs_clients@sema-10.html>
>       ([fdo#109271] / [i915#2994])
>
> Possible fixes
>
>    -
>
>    igt@drm_mm@all@evict:
>    - shard-skl: INCOMPLETE
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl2/igt@drm_mm@all@evict.html>
>       ([i915#198]) -> PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl4/igt@drm_mm@all@evict.html>
>    -
>
>    igt@gem_exec_fair@basic-none@vecs0:
>    - shard-kbl: FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-kbl4/igt@gem_exec_fair@basic-none@vecs0.html>
>       ([i915#2842]) -> PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl1/igt@gem_exec_fair@basic-none@vecs0.html>
>    -
>
>    igt@gem_exec_fair@basic-pace@bcs0:
>    - shard-iclb: FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb3/igt@gem_exec_fair@basic-pace@bcs0.html>
>       ([i915#2842]) -> PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb8/igt@gem_exec_fair@basic-pace@bcs0.html>
>    -
>
>    igt@gem_exec_fair@basic-pace@vcs1:
>    - shard-tglb: FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-tglb1/igt@gem_exec_fair@basic-pace@vcs1.html>
>       ([i915#2842]) -> PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb2/igt@gem_exec_fair@basic-pace@vcs1.html>
>    -
>
>    igt@gem_softpin@noreloc-s3:
>    - shard-apl: DMESG-WARN
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-apl8/igt@gem_softpin@noreloc-s3.html>
>       ([i915#180]) -> PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl3/igt@gem_softpin@noreloc-s3.html>
>    -
>
>    igt@i915_pm_dc@dc6-dpms:
>    - shard-iclb: FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb3/igt@i915_pm_dc@dc6-dpms.html>
>       ([i915#454]) -> PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb1/igt@i915_pm_dc@dc6-dpms.html>
>    -
>
>    igt@i915_suspend@forcewake:
>    - shard-skl: INCOMPLETE
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl2/igt@i915_suspend@forcewake.html>
>       ([i915#636]) -> PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl7/igt@i915_suspend@forcewake.html>
>    -
>
>    igt@kms_color@pipe-b-ctm-0-75:
>    - shard-skl: DMESG-WARN
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl7/igt@kms_color@pipe-b-ctm-0-75.html>
>       ([i915#1982]) -> PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl10/igt@kms_color@pipe-b-ctm-0-75.html>
>    -
>
>    igt@kms_cursor_crc@pipe-a-cursor-suspend:
>    - shard-tglb: INCOMPLETE
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-tglb7/igt@kms_cursor_crc@pipe-a-cursor-suspend.html>
>       ([i915#2828] / [i915#456]) -> PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@kms_cursor_crc@pipe-a-cursor-suspend.html>
>    -
>
>    igt@kms_flip@flip-vs-expired-vblank-interruptible@b-dp1:
>    - shard-kbl: FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-kbl7/igt@kms_flip@flip-vs-expired-vblank-interruptible@b-dp1.html>
>       ([i915#79]) -> PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_flip@flip-vs-expired-vblank-interruptible@b-dp1.html>
>    -
>
>    igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs:
>    - shard-iclb: SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb2/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs.html>
>       ([i915#3701]) -> PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb1/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs.html>
>    -
>
>    igt@kms_plane_alpha_blend@pipe-a-coverage-7efc:
>    - shard-skl: FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl10/igt@kms_plane_alpha_blend@pipe-a-coverage-7efc.html>
>       ([fdo#108145] / [i915#265]) -> PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl3/igt@kms_plane_alpha_blend@pipe-a-coverage-7efc.html>
>    -
>
>    igt@kms_psr@psr2_cursor_plane_move:
>    - shard-iclb: SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb4/igt@kms_psr@psr2_cursor_plane_move.html>
>       ([fdo#109441]) -> PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb2/igt@kms_psr@psr2_cursor_plane_move.html>
>    -
>
>    igt@kms_vblank@pipe-a-ts-continuation-suspend:
>    - shard-tglb: INCOMPLETE
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-tglb7/igt@kms_vblank@pipe-a-ts-continuation-suspend.html>
>       ([i915#456]) -> PASS
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_vblank@pipe-a-ts-continuation-suspend.html>
>       +1 similar issue
>
> Warnings
>
>    -
>
>    igt@i915_pm_rc6_residency@rc6-fence:
>    - shard-iclb: WARN
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb1/igt@i915_pm_rc6_residency@rc6-fence.html>
>       ([i915#2684]) -> WARN
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb3/igt@i915_pm_rc6_residency@rc6-fence.html>
>       ([i915#1804] / [i915#2684])
>    -
>
>    igt@kms_psr2_sf@plane-move-sf-dmg-area-0:
>    - shard-iclb: SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb5/igt@kms_psr2_sf@plane-move-sf-dmg-area-0.html>
>       ([i915#658]) -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb2/igt@kms_psr2_sf@plane-move-sf-dmg-area-0.html>
>       ([i915#2920])
>    -
>
>    igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-1:
>    - shard-iclb: SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb2/igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-1.html>
>       ([i915#2920]) -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb7/igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-1.html>
>       ([i915#658]) +2 similar issues
>    -
>
>    igt@kms_psr2_su@page_flip:
>    - shard-iclb: FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb2/igt@kms_psr2_su@page_flip.html>
>       ([i915#4148]) -> SKIP
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb7/igt@kms_psr2_su@page_flip.html>
>       ([fdo#109642] / [fdo#111068] / [i915#658])
>    -
>
>    igt@runner@aborted:
>    -
>
>       shard-kbl: (FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-kbl7/igt@runner@aborted.html>,
>       FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-kbl1/igt@runner@aborted.html>)
>       ([i915#3002] / [i915#3363] / [i915#4312]) -> (FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl3/igt@runner@aborted.html>,
>       FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@runner@aborted.html>,
>       FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@runner@aborted.html>)
>       ([i915#1436] / [i915#180] / [i915#3002] / [i915#3363] / [i915#4312])
>       -
>
>       shard-apl: (FAIL
>       <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-apl6/igt@runner@aborted.html>,
>       FAIL <http://ht>, [FAIL][140]) ([i915#180] / [i915#1814] /
>       [i915#3002] / [i915#3363] / [i915#4312]) -> ([FAIL][141], [FAIL][142],
>       [FAIL][143], [FAIL][144]) ([i915#180] / [i915#3002] / [i915#3363] /
>       [i915#4312])
>
>

[-- Attachment #2: Type: text/html, Size: 37039 bytes --]

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx]  ✗ Fi.CI.IGT: failure for series starting with [01/28] drm/i915: Fix i915_request fence wait semantics
  2021-10-22 11:24   ` Matthew Auld
@ 2021-10-22 13:17     ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-10-22 13:17 UTC (permalink / raw)
  To: Matthew Auld, Intel Graphics Development

[-- Attachment #1: Type: text/plain, Size: 31531 bytes --]

Op 22-10-2021 om 13:24 schreef Matthew Auld:
> On Thu, 21 Oct 2021 at 13:57, Patchwork <patchwork@emeril.freedesktop.org <mailto:patchwork@emeril.freedesktop.org>> wrote:
>
>     *Patch Details*
>     *Series:* 	series starting with [01/28] drm/i915: Fix i915_request fence wait semantics
>     *URL:* 	https://patchwork.freedesktop.org/series/96115/ <https://patchwork.freedesktop.org/series/96115/>
>     *State:* 	failure
>     *Details:* 	https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/index.html <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/index.html>
>
>
>       CI Bug Log - changes from CI_DRM_10768_full -> Patchwork_21402_full
>
>
>         Summary
>
>     *FAILURE*
>
>     Serious unknown changes coming with Patchwork_21402_full absolutely need to be
>     verified manually.
>
>     If you think the reported changes have nothing to do with the changes
>     introduced in Patchwork_21402_full, please notify your bug team to allow them
>     to document this new failure mode, which will reduce false positives in CI.
>
>
>         Possible new issues
>
>     Here are the unknown changes that may have been introduced in Patchwork_21402_full:
>
>
>           IGT changes
>
>
>             Possible regressions
>
>      *
>
>         igt@gem_linear_blits@normal:
>
>           o shard-glk: PASS <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-glk4/igt@gem_linear_blits@normal.html> -> FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-glk4/igt@gem_linear_blits@normal.html>
>      *
>
>         igt@gem_mmap_gtt@cpuset-big-copy-xy:
>
>           o shard-iclb: NOTRUN -> INCOMPLETE <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb3/igt@gem_mmap_gtt@cpuset-big-copy-xy.html>
>      *
>
>         igt@gem_ppgtt@blt-vs-render-ctxn:
>
>           o shard-tglb: PASS <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-tglb5/igt@gem_ppgtt@blt-vs-render-ctxn.html> -> FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb8/igt@gem_ppgtt@blt-vs-render-ctxn.html> +1 similar issue
>
>
> Maarten, do you know if these failures are related to this series? Perhaps the last one?

Yeah, unfortunately they are. In general, I think the last patch is fine, but we hit more ENOSPC errors because of the extra locking requirements around eviction.

Most of these issues don't happen when we remove the pinning in execbuf, but already earlier in the series, usuallly with locking in eviction paths.

I added some fixes in case it affects the object we are currently trying to pin, like calling i915_gem_evict_vm() in vm_fault_gtt that already fix a lot of issues, but each remaining ENOSPC error like the 3 above requires separate debugging to resolve. I've fixed many cases already, it seems those are remaining.

The fix for gem_mmap_gtt by calling i915_gem_evict_vm() to evict the current object seems to be insufficient on ICL, but originally other platforms were hit harder by this problem, and there it works as intended. :)

Just a few edge cases remaining, fortunately. The majority of tests now pass.

>  
>
>      *
>
>
>         Known issues
>
>     Here are the changes found in Patchwork_21402_full that come from known issues:
>
>
>           IGT changes
>
>
>             Issues hit
>
>      *
>
>         igt@feature_discovery@display-2x:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb1/igt@feature_discovery@display-2x.html> ([i915#1839])
>      *
>
>         igt@gem_create@create-massive:
>
>           o shard-snb: NOTRUN -> DMESG-WARN <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-snb2/igt@gem_create@create-massive.html> ([i915#3002])
>      *
>
>         igt@gem_ctx_isolation@preservation-s3@rcs0:
>
>           o shard-tglb: PASS <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-tglb8/igt@gem_ctx_isolation@preservation-s3@rcs0.html> -> INCOMPLETE <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb7/igt@gem_ctx_isolation@preservation-s3@rcs0.html> ([i915#1373])
>      *
>
>         igt@gem_ctx_isolation@preservation-s3@vcs0:
>
>           o shard-kbl: PASS <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-kbl7/igt@gem_ctx_isolation@preservation-s3@vcs0.html> -> DMESG-WARN <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@gem_ctx_isolation@preservation-s3@vcs0.html> ([i915#180]) +3 similar issues
>      *
>
>         igt@gem_ctx_isolation@preservation-s3@vecs0:
>
>           o shard-skl: PASS <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl3/igt@gem_ctx_isolation@preservation-s3@vecs0.html> -> INCOMPLETE <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl1/igt@gem_ctx_isolation@preservation-s3@vecs0.html> ([i915#198])
>      *
>
>         igt@gem_ctx_persistence@idempotent:
>
>           o shard-snb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-snb2/igt@gem_ctx_persistence@idempotent.html> ([fdo#109271] / [i915#1099]) +4 similar issues
>      *
>
>         igt@gem_exec_fair@basic-none-solo@rcs0:
>
>           o shard-glk: PASS <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-glk5/igt@gem_exec_fair@basic-none-solo@rcs0.html> -> FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-glk7/igt@gem_exec_fair@basic-none-solo@rcs0.html> ([i915#2842])
>      *
>
>         igt@gem_exec_fair@basic-pace@bcs0:
>
>           o shard-tglb: PASS <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-tglb1/igt@gem_exec_fair@basic-pace@bcs0.html> -> FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb2/igt@gem_exec_fair@basic-pace@bcs0.html> ([i915#2842]) +2 similar issues
>      *
>
>         igt@gem_exec_fair@basic-pace@vecs0:
>
>           o shard-kbl: PASS <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-kbl2/igt@gem_exec_fair@basic-pace@vecs0.html> -> FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl2/igt@gem_exec_fair@basic-pace@vecs0.html> ([i915#2842]) +2 similar issues
>      *
>
>         igt@gem_exec_params@no-vebox:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@gem_exec_params@no-vebox.html> ([fdo#109283])
>      *
>
>         igt@gem_pwrite@basic-exhaustion:
>
>           o shard-kbl: NOTRUN -> WARN <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@gem_pwrite@basic-exhaustion.html> ([i915#2658])
>      *
>
>         igt@gem_pxp@dmabuf-shared-protected-dst-is-context-refcounted:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@gem_pxp@dmabuf-shared-protected-dst-is-context-refcounted.html> ([i915#4270])
>      *
>
>         igt@gem_userptr_blits@readonly-unsync:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@gem_userptr_blits@readonly-unsync.html> ([i915#3297])
>      *
>
>         igt@gen7_exec_parse@basic-rejected:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@gen7_exec_parse@basic-rejected.html> ([fdo#109289]) +2 similar issues
>      *
>
>         igt@gen9_exec_parse@cmd-crossing-page:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@gen9_exec_parse@cmd-crossing-page.html> ([i915#2856]) +2 similar issues
>      *
>
>         igt@i915_pm_dc@dc6-psr:
>
>           o shard-iclb: PASS <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb1/igt@i915_pm_dc@dc6-psr.html> -> FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb3/igt@i915_pm_dc@dc6-psr.html> ([i915#454])
>      *
>
>         igt@i915_pm_lpsp@kms-lpsp@kms-lpsp-dp:
>
>           o shard-kbl: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@i915_pm_lpsp@kms-lpsp@kms-lpsp-dp.html> ([fdo#109271] / [i915#1937])
>      *
>
>         igt@i915_pm_rpm@dpms-non-lpsp:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@i915_pm_rpm@dpms-non-lpsp.html> ([fdo#111644] / [i915#1397] / [i915#2411])
>      *
>
>         igt@i915_pm_rpm@gem-execbuf-stress-pc8:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@i915_pm_rpm@gem-execbuf-stress-pc8.html> ([fdo#109506] / [i915#2411])
>      *
>
>         igt@i915_suspend@fence-restore-untiled:
>
>           o shard-apl: PASS <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-apl8/igt@i915_suspend@fence-restore-untiled.html> -> DMESG-WARN <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl1/igt@i915_suspend@fence-restore-untiled.html> ([i915#180]) +1 similar issue
>      *
>
>         igt@kms_big_fb@linear-16bpp-rotate-90:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@kms_big_fb@linear-16bpp-rotate-90.html> ([fdo#111614]) +1 similar issue
>      *
>
>         igt@kms_big_fb@linear-32bpp-rotate-0:
>
>           o shard-glk: PASS <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-glk7/igt@kms_big_fb@linear-32bpp-rotate-0.html> -> DMESG-WARN <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-glk5/igt@kms_big_fb@linear-32bpp-rotate-0.html> ([i915#118])
>      *
>
>         igt@kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-0-hflip:
>
>           o shard-kbl: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-0-hflip.html> ([fdo#109271] / [i915#3777])
>      *
>
>         igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-180-hflip:
>
>           o shard-apl: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl3/igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-180-hflip.html> ([fdo#109271] / [i915#3777])
>      *
>
>         igt@kms_big_fb@yf-tiled-16bpp-rotate-90:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_big_fb@yf-tiled-16bpp-rotate-90.html> ([fdo#111615]) +2 similar issues
>      *
>
>         igt@kms_big_joiner@invalid-modeset:
>
>           o shard-skl: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl7/igt@kms_big_joiner@invalid-modeset.html> ([fdo#109271]) +19 similar issues
>      *
>
>         igt@kms_ccs@pipe-a-bad-rotation-90-y_tiled_gen12_rc_ccs_cc:
>
>           o shard-kbl: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_ccs@pipe-a-bad-rotation-90-y_tiled_gen12_rc_ccs_cc.html> ([fdo#109271] / [i915#3886]) +1 similar issue
>      *
>
>         igt@kms_ccs@pipe-a-ccs-on-another-bo-y_tiled_gen12_rc_ccs_cc:
>
>           o shard-apl: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl7/igt@kms_ccs@pipe-a-ccs-on-another-bo-y_tiled_gen12_rc_ccs_cc.html> ([fdo#109271] / [i915#3886]) +4 similar issues
>      *
>
>         igt@kms_ccs@pipe-a-missing-ccs-buffer-y_tiled_gen12_rc_ccs_cc:
>
>           o shard-skl: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl7/igt@kms_ccs@pipe-a-missing-ccs-buffer-y_tiled_gen12_rc_ccs_cc.html> ([fdo#109271] / [i915#3886])
>      *
>
>         igt@kms_ccs@pipe-b-bad-rotation-90-y_tiled_ccs:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_ccs@pipe-b-bad-rotation-90-y_tiled_ccs.html> ([i915#3689]) +6 similar issues
>      *
>
>         igt@kms_ccs@pipe-c-bad-rotation-90-y_tiled_gen12_mc_ccs:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_ccs@pipe-c-bad-rotation-90-y_tiled_gen12_mc_ccs.html> ([i915#3689] / [i915#3886]) +1 similar issue
>      *
>
>         igt@kms_ccs@pipe-d-missing-ccs-buffer-y_tiled_gen12_rc_ccs:
>
>           o shard-kbl: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_ccs@pipe-d-missing-ccs-buffer-y_tiled_gen12_rc_ccs.html> ([fdo#109271]) +33 similar issues
>      *
>
>         igt@kms_chamelium@hdmi-mode-timings:
>
>           o shard-snb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-snb2/igt@kms_chamelium@hdmi-mode-timings.html> ([fdo#109271] / [fdo#111827]) +13 similar issues
>      *
>
>         igt@kms_color@pipe-a-ctm-0-75:
>
>           o shard-skl: PASS <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl7/igt@kms_color@pipe-a-ctm-0-75.html> -> DMESG-WARN <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl10/igt@kms_color@pipe-a-ctm-0-75.html> ([i915#1982]) +2 similar issues
>      *
>
>         igt@kms_color_chamelium@pipe-a-ctm-green-to-red:
>
>           o shard-skl: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl7/igt@kms_color_chamelium@pipe-a-ctm-green-to-red.html> ([fdo#109271] / [fdo#111827])
>      *
>
>         igt@kms_color_chamelium@pipe-b-ctm-limited-range:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_color_chamelium@pipe-b-ctm-limited-range.html> ([fdo#109284] / [fdo#111827]) +5 similar issues
>      *
>
>         igt@kms_color_chamelium@pipe-b-ctm-red-to-blue:
>
>           o shard-apl: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl3/igt@kms_color_chamelium@pipe-b-ctm-red-to-blue.html> ([fdo#109271] / [fdo#111827]) +10 similar issues
>      *
>
>         igt@kms_color_chamelium@pipe-c-ctm-red-to-blue:
>
>           o shard-kbl: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_color_chamelium@pipe-c-ctm-red-to-blue.html> ([fdo#109271] / [fdo#111827]) +1 similar issue
>      *
>
>         igt@kms_content_protection@atomic:
>
>           o shard-apl: NOTRUN -> TIMEOUT <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl7/igt@kms_content_protection@atomic.html> ([i915#1319])
>      *
>
>         igt@kms_content_protection@atomic-dpms:
>
>           o shard-kbl: NOTRUN -> TIMEOUT <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_content_protection@atomic-dpms.html> ([i915#1319])
>      *
>
>         igt@kms_content_protection@dp-mst-type-0:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_content_protection@dp-mst-type-0.html> ([i915#3116])
>      *
>
>         igt@kms_cursor_crc@pipe-b-cursor-max-size-onscreen:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@kms_cursor_crc@pipe-b-cursor-max-size-onscreen.html> ([i915#3359]) +3 similar issues
>      *
>
>         igt@kms_cursor_crc@pipe-d-cursor-512x170-random:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_cursor_crc@pipe-d-cursor-512x170-random.html> ([fdo#109279] / [i915#3359]) +7 similar issues
>      *
>
>         igt@kms_cursor_edge_walk@pipe-d-128x128-right-edge:
>
>           o shard-snb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-snb7/igt@kms_cursor_edge_walk@pipe-d-128x128-right-edge.html> ([fdo#109271]) +281 similar issues
>      *
>
>         igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy:
>
>           o shard-iclb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb3/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy.html> ([fdo#109274] / [fdo#109278])
>      *
>
>         igt@kms_cursor_legacy@pipe-d-torture-bo:
>
>           o shard-apl: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl7/igt@kms_cursor_legacy@pipe-d-torture-bo.html> ([fdo#109271] / [i915#533])
>      *
>
>         igt@kms_cursor_legacy@short-busy-flip-before-cursor-atomic-transitions-varying-size:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_cursor_legacy@short-busy-flip-before-cursor-atomic-transitions-varying-size.html> ([i915#4103])
>      *
>
>         igt@kms_dp_tiled_display@basic-test-pattern-with-chamelium:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb1/igt@kms_dp_tiled_display@basic-test-pattern-with-chamelium.html> ([i915#3528])
>      *
>
>         igt@kms_flip@2x-flip-vs-expired-vblank-interruptible@bc-hdmi-a1-hdmi-a2:
>
>           o shard-glk: PASS <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-glk5/igt@kms_flip@2x-flip-vs-expired-vblank-interruptible@bc-hdmi-a1-hdmi-a2.html> -> FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-glk7/igt@kms_flip@2x-flip-vs-expired-vblank-interruptible@bc-hdmi-a1-hdmi-a2.html> ([i915#79]) +1 similar issue
>      *
>
>         igt@kms_flip@flip-vs-suspend-interruptible@c-dp1:
>
>           o shard-kbl: NOTRUN -> DMESG-WARN <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_flip@flip-vs-suspend-interruptible@c-dp1.html> ([i915#180]) +1 similar issue
>      *
>
>         igt@kms_flip@flip-vs-suspend@a-dp1:
>
>           o shard-apl: NOTRUN -> DMESG-WARN <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl3/igt@kms_flip@flip-vs-suspend@a-dp1.html> ([i915#180])
>      *
>
>         igt@kms_flip@plain-flip-ts-check-interruptible@b-edp1:
>
>           o shard-skl: PASS <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl9/igt@kms_flip@plain-flip-ts-check-interruptible@b-edp1.html> -> FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl5/igt@kms_flip@plain-flip-ts-check-interruptible@b-edp1.html> ([i915#2122])
>      *
>
>         igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-spr-indfb-draw-mmap-gtt:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@kms_frontbuffer_tracking@fbcpsr-2p-primscrn-spr-indfb-draw-mmap-gtt.html> ([fdo#111825]) +26 similar issues
>      *
>
>         igt@kms_pipe_crc_basic@suspend-read-crc-pipe-c:
>
>           o shard-tglb: PASS <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-tglb3/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-c.html> -> INCOMPLETE <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb7/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-c.html> ([i915#2828] / [i915#456])
>      *
>
>         igt@kms_plane_alpha_blend@pipe-a-alpha-7efc:
>
>           o shard-skl: NOTRUN -> FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl7/igt@kms_plane_alpha_blend@pipe-a-alpha-7efc.html> ([fdo#108145] / [i915#265])
>      *
>
>         igt@kms_plane_alpha_blend@pipe-a-alpha-transparent-fb:
>
>           o shard-apl: NOTRUN -> FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl7/igt@kms_plane_alpha_blend@pipe-a-alpha-transparent-fb.html> ([i915#265])
>      *
>
>         igt@kms_plane_alpha_blend@pipe-c-alpha-basic:
>
>           o shard-kbl: NOTRUN -> FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_plane_alpha_blend@pipe-c-alpha-basic.html> ([fdo#108145] / [i915#265]) +1 similar issue
>      *
>
>         igt@kms_plane_alpha_blend@pipe-c-coverage-7efc:
>
>           o shard-skl: PASS <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl10/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html> -> FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl3/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html> ([fdo#108145] / [i915#265]) +1 similar issue
>      *
>
>         igt@kms_plane_lowres@pipe-b-tiling-y:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_plane_lowres@pipe-b-tiling-y.html> ([i915#3536])
>      *
>
>         igt@kms_plane_lowres@pipe-d-tiling-yf:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_plane_lowres@pipe-d-tiling-yf.html> ([fdo#112054]) +1 similar issue
>      *
>
>         igt@kms_psr2_sf@plane-move-sf-dmg-area-1:
>
>           o shard-kbl: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_psr2_sf@plane-move-sf-dmg-area-1.html> ([fdo#109271] / [i915#658]) +1 similar issue
>      *
>
>         igt@kms_psr2_sf@plane-move-sf-dmg-area-2:
>
>           o shard-apl: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl3/igt@kms_psr2_sf@plane-move-sf-dmg-area-2.html> ([fdo#109271] / [i915#658]) +3 similar issues
>      *
>
>         igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-1:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-1.html> ([i915#2920]) +2 similar issues
>      *
>
>         igt@kms_psr2_su@page_flip:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb1/igt@kms_psr2_su@page_flip.html> ([i915#1911])
>      *
>
>         igt@kms_psr@psr2_suspend:
>
>          o
>
>             shard-iclb: PASS <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb2/igt@kms_psr@psr2_suspend.html> -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb7/igt@kms_psr@psr2_suspend.html> ([fdo#109441])
>
>          o
>
>             shard-tglb: NOTRUN -> FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@kms_psr@psr2_suspend.html> ([i915#132] / [i915#3467])
>
>      *
>
>         igt@kms_vblank@pipe-b-ts-continuation-dpms-suspend:
>
>           o shard-skl: PASS <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl5/igt@kms_vblank@pipe-b-ts-continuation-dpms-suspend.html> -> INCOMPLETE <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl5/igt@kms_vblank@pipe-b-ts-continuation-dpms-suspend.html> ([i915#198] / [i915#2828])
>      *
>
>         igt@kms_vblank@pipe-d-ts-continuation-idle:
>
>           o shard-apl: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl3/igt@kms_vblank@pipe-d-ts-continuation-idle.html> ([fdo#109271]) +93 similar issues
>      *
>
>         igt@nouveau_crc@pipe-a-ctx-flip-detection:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@nouveau_crc@pipe-a-ctx-flip-detection.html> ([i915#2530]) +2 similar issues
>      *
>
>         igt@perf_pmu@event-wait@rcs0:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@perf_pmu@event-wait@rcs0.html> ([fdo#112283])
>      *
>
>         igt@prime_nv_pcopy@test3_5:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@prime_nv_pcopy@test3_5.html> ([fdo#109291])
>      *
>
>         igt@prime_vgem@fence-write-hang:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@prime_vgem@fence-write-hang.html> ([fdo#109295])
>      *
>
>         igt@sysfs_clients@create:
>
>           o shard-apl: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl7/igt@sysfs_clients@create.html> ([fdo#109271] / [i915#2994]) +1 similar issue
>      *
>
>         igt@sysfs_clients@fair-0:
>
>           o shard-tglb: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb1/igt@sysfs_clients@fair-0.html> ([i915#2994])
>      *
>
>         igt@sysfs_clients@sema-10:
>
>           o shard-skl: NOTRUN -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl7/igt@sysfs_clients@sema-10.html> ([fdo#109271] / [i915#2994])
>
>
>             Possible fixes
>
>      *
>
>         igt@drm_mm@all@evict:
>
>           o shard-skl: INCOMPLETE <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl2/igt@drm_mm@all@evict.html> ([i915#198]) -> PASS <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl4/igt@drm_mm@all@evict.html>
>      *
>
>         igt@gem_exec_fair@basic-none@vecs0:
>
>           o shard-kbl: FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-kbl4/igt@gem_exec_fair@basic-none@vecs0.html> ([i915#2842]) -> PASS <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl1/igt@gem_exec_fair@basic-none@vecs0.html>
>      *
>
>         igt@gem_exec_fair@basic-pace@bcs0:
>
>           o shard-iclb: FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb3/igt@gem_exec_fair@basic-pace@bcs0.html> ([i915#2842]) -> PASS <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb8/igt@gem_exec_fair@basic-pace@bcs0.html>
>      *
>
>         igt@gem_exec_fair@basic-pace@vcs1:
>
>           o shard-tglb: FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-tglb1/igt@gem_exec_fair@basic-pace@vcs1.html> ([i915#2842]) -> PASS <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb2/igt@gem_exec_fair@basic-pace@vcs1.html>
>      *
>
>         igt@gem_softpin@noreloc-s3:
>
>           o shard-apl: DMESG-WARN <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-apl8/igt@gem_softpin@noreloc-s3.html> ([i915#180]) -> PASS <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-apl3/igt@gem_softpin@noreloc-s3.html>
>      *
>
>         igt@i915_pm_dc@dc6-dpms:
>
>           o shard-iclb: FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb3/igt@i915_pm_dc@dc6-dpms.html> ([i915#454]) -> PASS <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb1/igt@i915_pm_dc@dc6-dpms.html>
>      *
>
>         igt@i915_suspend@forcewake:
>
>           o shard-skl: INCOMPLETE <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl2/igt@i915_suspend@forcewake.html> ([i915#636]) -> PASS <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl7/igt@i915_suspend@forcewake.html>
>      *
>
>         igt@kms_color@pipe-b-ctm-0-75:
>
>           o shard-skl: DMESG-WARN <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl7/igt@kms_color@pipe-b-ctm-0-75.html> ([i915#1982]) -> PASS <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl10/igt@kms_color@pipe-b-ctm-0-75.html>
>      *
>
>         igt@kms_cursor_crc@pipe-a-cursor-suspend:
>
>           o shard-tglb: INCOMPLETE <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-tglb7/igt@kms_cursor_crc@pipe-a-cursor-suspend.html> ([i915#2828] / [i915#456]) -> PASS <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb5/igt@kms_cursor_crc@pipe-a-cursor-suspend.html>
>      *
>
>         igt@kms_flip@flip-vs-expired-vblank-interruptible@b-dp1:
>
>           o shard-kbl: FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-kbl7/igt@kms_flip@flip-vs-expired-vblank-interruptible@b-dp1.html> ([i915#79]) -> PASS <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@kms_flip@flip-vs-expired-vblank-interruptible@b-dp1.html>
>      *
>
>         igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs:
>
>           o shard-iclb: SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb2/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs.html> ([i915#3701]) -> PASS <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb1/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs.html>
>      *
>
>         igt@kms_plane_alpha_blend@pipe-a-coverage-7efc:
>
>           o shard-skl: FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-skl10/igt@kms_plane_alpha_blend@pipe-a-coverage-7efc.html> ([fdo#108145] / [i915#265]) -> PASS <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-skl3/igt@kms_plane_alpha_blend@pipe-a-coverage-7efc.html>
>      *
>
>         igt@kms_psr@psr2_cursor_plane_move:
>
>           o shard-iclb: SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb4/igt@kms_psr@psr2_cursor_plane_move.html> ([fdo#109441]) -> PASS <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb2/igt@kms_psr@psr2_cursor_plane_move.html>
>      *
>
>         igt@kms_vblank@pipe-a-ts-continuation-suspend:
>
>           o shard-tglb: INCOMPLETE <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-tglb7/igt@kms_vblank@pipe-a-ts-continuation-suspend.html> ([i915#456]) -> PASS <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-tglb3/igt@kms_vblank@pipe-a-ts-continuation-suspend.html> +1 similar issue
>
>
>             Warnings
>
>      *
>
>         igt@i915_pm_rc6_residency@rc6-fence:
>
>           o shard-iclb: WARN <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb1/igt@i915_pm_rc6_residency@rc6-fence.html> ([i915#2684]) -> WARN <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb3/igt@i915_pm_rc6_residency@rc6-fence.html> ([i915#1804] / [i915#2684])
>      *
>
>         igt@kms_psr2_sf@plane-move-sf-dmg-area-0:
>
>           o shard-iclb: SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb5/igt@kms_psr2_sf@plane-move-sf-dmg-area-0.html> ([i915#658]) -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb2/igt@kms_psr2_sf@plane-move-sf-dmg-area-0.html> ([i915#2920])
>      *
>
>         igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-1:
>
>           o shard-iclb: SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb2/igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-1.html> ([i915#2920]) -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb7/igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-1.html> ([i915#658]) +2 similar issues
>      *
>
>         igt@kms_psr2_su@page_flip:
>
>           o shard-iclb: FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-iclb2/igt@kms_psr2_su@page_flip.html> ([i915#4148]) -> SKIP <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-iclb7/igt@kms_psr2_su@page_flip.html> ([fdo#109642] / [fdo#111068] / [i915#658])
>      *
>
>         igt@runner@aborted:
>
>          o
>
>             shard-kbl: (FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-kbl7/igt@runner@aborted.html>, FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-kbl1/igt@runner@aborted.html>) ([i915#3002] / [i915#3363] / [i915#4312]) -> (FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl3/igt@runner@aborted.html>, FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@runner@aborted.html>, FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21402/shard-kbl6/igt@runner@aborted.html>) ([i915#1436] / [i915#180] / [i915#3002] / [i915#3363] / [i915#4312])
>
>          o
>
>             shard-apl: (FAIL <https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10768/shard-apl6/igt@runner@aborted.html>, FAIL <http://ht>, [FAIL][140]) ([i915#180] / [i915#1814] / [i915#3002] / [i915#3363] / [i915#4312]) -> ([FAIL][141], [FAIL][142], [FAIL][143], [FAIL][144]) ([i915#180] / [i915#3002] / [i915#3363] / [i915#4312])
>


[-- Attachment #2: Type: text/html, Size: 58198 bytes --]

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [PATCH 28/28] drm/i915: Remove short-term pins from execbuf, v4.
  2021-10-21 10:36   ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-25 15:02     ` Matthew Auld
  -1 siblings, 0 replies; 114+ messages in thread
From: Matthew Auld @ 2021-10-25 15:02 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Intel Graphics Development, ML dri-devel

On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
>
> Add a flag PIN_VALIDATE, to indicate we don't need to pin and only
> protected by the object lock.
>
> This removes the need to unpin, which is done by just releasing the
> lock.
>
> eb_reserve is slightly reworked for readability, but the same steps
> are still done:
> - First pass pins with NONBLOCK.
> - Second pass unbinds all objects first, then pins.
> - Third pass is only called when not all objects are softpinned, and
>   unbinds all objects, then calls i915_gem_evict_vm(), then pins.
>
> When evicting the entire vm in eb_reserve() we do temporarily pin objects
> that are marked with EXEC_OBJECT_PINNED. This is because they are already
> at their destination, and i915_gem_evict_vm() would otherwise unbind them.
>
> However, we reduce the visibility of those pins by limiting the pin
> to our call to i915_gem_evict_vm() only, and pin with vm->mutex held,
> instead of the entire duration of the execbuf.
>
> Not sure the latter matters, one can hope..
> In theory we could kill the pinning by adding an extra flag to the vma
> to temporarily prevent unbinding for gtt for i915_gem_evict_vm only, but
> I think that might be overkill. We're still holding the object lock, and
> we don't have blocking eviction yet. It's likely sufficient to simply
> enforce EXEC_OBJECT_PINNED for all objects on >= gen12.
>
> Changes since v1:
> - Split out eb_reserve() into separate functions for readability.
> Changes since v2:
> - Make batch buffer mappable on platforms where only GGTT is available,
>   to prevent moving the batch buffer during relocations.
> Changes since v3:
> - Preserve current behavior for batch buffer, instead be cautious when
>   calling i915_gem_object_ggtt_pin_ww, and re-use the current batch vma
>   if it's inside ggtt and map-and-fenceable.
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 252 ++++++++++--------
>  drivers/gpu/drm/i915/i915_gem_gtt.h           |   1 +
>  drivers/gpu/drm/i915/i915_vma.c               |  24 +-
>  3 files changed, 161 insertions(+), 116 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> index bbf2a10738f7..19f91143cfcf 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> @@ -439,7 +439,7 @@ eb_pin_vma(struct i915_execbuffer *eb,
>         else
>                 pin_flags = entry->offset & PIN_OFFSET_MASK;
>
> -       pin_flags |= PIN_USER | PIN_NOEVICT | PIN_OFFSET_FIXED;
> +       pin_flags |= PIN_USER | PIN_NOEVICT | PIN_OFFSET_FIXED | PIN_VALIDATE;
>         if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_GTT))
>                 pin_flags |= PIN_GLOBAL;
>
> @@ -457,17 +457,15 @@ eb_pin_vma(struct i915_execbuffer *eb,
>                                              entry->pad_to_size,
>                                              entry->alignment,
>                                              eb_pin_flags(entry, ev->flags) |
> -                                            PIN_USER | PIN_NOEVICT);
> +                                            PIN_USER | PIN_NOEVICT | PIN_VALIDATE);
>                 if (unlikely(err))
>                         return err;
>         }
>
>         if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_FENCE)) {
>                 err = i915_vma_pin_fence(vma);
> -               if (unlikely(err)) {
> -                       i915_vma_unpin(vma);
> +               if (unlikely(err))
>                         return err;
> -               }
>
>                 if (vma->fence)
>                         ev->flags |= __EXEC_OBJECT_HAS_FENCE;
> @@ -483,13 +481,9 @@ eb_pin_vma(struct i915_execbuffer *eb,
>  static inline void
>  eb_unreserve_vma(struct eb_vma *ev)
>  {
> -       if (!(ev->flags & __EXEC_OBJECT_HAS_PIN))
> -               return;
> -
>         if (unlikely(ev->flags & __EXEC_OBJECT_HAS_FENCE))
>                 __i915_vma_unpin_fence(ev->vma);
>
> -       __i915_vma_unpin(ev->vma);
>         ev->flags &= ~__EXEC_OBJECT_RESERVED;
>  }
>
> @@ -682,10 +676,8 @@ static int eb_reserve_vma(struct i915_execbuffer *eb,
>
>         if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_FENCE)) {
>                 err = i915_vma_pin_fence(vma);
> -               if (unlikely(err)) {
> -                       i915_vma_unpin(vma);
> +               if (unlikely(err))
>                         return err;
> -               }
>
>                 if (vma->fence)
>                         ev->flags |= __EXEC_OBJECT_HAS_FENCE;
> @@ -697,85 +689,129 @@ static int eb_reserve_vma(struct i915_execbuffer *eb,
>         return 0;
>  }
>
> -static int eb_reserve(struct i915_execbuffer *eb)
> +static int eb_evict_vm(struct i915_execbuffer *eb)
> +{
> +       const unsigned int count = eb->buffer_count;
> +       unsigned int i;
> +       int err;
> +
> +       err = mutex_lock_interruptible(&eb->context->vm->mutex);
> +       if (err)
> +               return err;
> +
> +       /* pin to protect against i915_gem_evict_vm evicting below */
> +       for (i = 0; i < count; i++) {
> +               struct eb_vma *ev = &eb->vma[i];
> +
> +               if (ev->flags & __EXEC_OBJECT_HAS_PIN)
> +                       __i915_vma_pin(ev->vma);
> +       }
> +
> +       /* Too fragmented, unbind everything and retry */
> +       err = i915_gem_evict_vm(eb->context->vm, &eb->ww);
> +
> +       /* unpin objects.. */
> +       for (i = 0; i < count; i++) {
> +               struct eb_vma *ev = &eb->vma[i];
> +
> +               if (ev->flags & __EXEC_OBJECT_HAS_PIN)
> +                       i915_vma_unpin(ev->vma);
> +       }
> +
> +       mutex_unlock(&eb->context->vm->mutex);
> +
> +       return err;
> +}
> +
> +static bool eb_unbind(struct i915_execbuffer *eb)
>  {
>         const unsigned int count = eb->buffer_count;
> -       unsigned int pin_flags = PIN_USER | PIN_NONBLOCK;
> +       unsigned int i;
>         struct list_head last;
> +       bool unpinned = false;
> +
> +       /* Resort *all* the objects into priority order */
> +       INIT_LIST_HEAD(&eb->unbound);
> +       INIT_LIST_HEAD(&last);
> +
> +       for (i = 0; i < count; i++) {
> +               struct eb_vma *ev = &eb->vma[i];
> +               unsigned int flags = ev->flags;
> +
> +               if (flags & EXEC_OBJECT_PINNED &&
> +                   flags & __EXEC_OBJECT_HAS_PIN)
> +                       continue;
> +
> +               unpinned = true;
> +               eb_unreserve_vma(ev);
> +
> +               if (flags & EXEC_OBJECT_PINNED)
> +                       /* Pinned must have their slot */
> +                       list_add(&ev->bind_link, &eb->unbound);
> +               else if (flags & __EXEC_OBJECT_NEEDS_MAP)
> +                       /* Map require the lowest 256MiB (aperture) */
> +                       list_add_tail(&ev->bind_link, &eb->unbound);
> +               else if (!(flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS))
> +                       /* Prioritise 4GiB region for restricted bo */
> +                       list_add(&ev->bind_link, &last);
> +               else
> +                       list_add_tail(&ev->bind_link, &last);
> +       }
> +
> +       list_splice_tail(&last, &eb->unbound);
> +       return unpinned;
> +}
> +
> +static int eb_reserve(struct i915_execbuffer *eb)
> +{
>         struct eb_vma *ev;
> -       unsigned int i, pass;
> +       unsigned int pass;
>         int err = 0;
> +       bool unpinned;
>
>         /*
>          * Attempt to pin all of the buffers into the GTT.
> -        * This is done in 3 phases:
> +        * This is done in 2 phases:
>          *
> -        * 1a. Unbind all objects that do not match the GTT constraints for
> -        *     the execbuffer (fenceable, mappable, alignment etc).
> -        * 1b. Increment pin count for already bound objects.
> -        * 2.  Bind new objects.
> -        * 3.  Decrement pin count.
> +        * 1. Unbind all objects that do not match the GTT constraints for
> +        *    the execbuffer (fenceable, mappable, alignment etc).
> +        * 2. Bind new objects.
>          *
>          * This avoid unnecessary unbinding of later objects in order to make
>          * room for the earlier objects *unless* we need to defragment.
> +        *
> +        * Defragmenting is skipped if all objects are pinned at a fixed location.
>          */
> -       pass = 0;
> -       do {
> -               list_for_each_entry(ev, &eb->unbound, bind_link) {
> -                       err = eb_reserve_vma(eb, ev, pin_flags);
> -                       if (err)
> -                               break;
> -               }
> -               if (err != -ENOSPC)
> -                       return err;
> +       for (pass = 0; pass <= 2; pass++) {
> +               int pin_flags = PIN_USER | PIN_VALIDATE;
>
> -               /* Resort *all* the objects into priority order */
> -               INIT_LIST_HEAD(&eb->unbound);
> -               INIT_LIST_HEAD(&last);
> -               for (i = 0; i < count; i++) {
> -                       unsigned int flags;
> +               if (pass == 0)
> +                       pin_flags |= PIN_NONBLOCK;
>
> -                       ev = &eb->vma[i];
> -                       flags = ev->flags;
> -                       if (flags & EXEC_OBJECT_PINNED &&
> -                           flags & __EXEC_OBJECT_HAS_PIN)
> -                               continue;
> +               if (pass >= 1)
> +                       unpinned = eb_unbind(eb);
>
> -                       eb_unreserve_vma(ev);
> -
> -                       if (flags & EXEC_OBJECT_PINNED)
> -                               /* Pinned must have their slot */
> -                               list_add(&ev->bind_link, &eb->unbound);
> -                       else if (flags & __EXEC_OBJECT_NEEDS_MAP)
> -                               /* Map require the lowest 256MiB (aperture) */
> -                               list_add_tail(&ev->bind_link, &eb->unbound);
> -                       else if (!(flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS))
> -                               /* Prioritise 4GiB region for restricted bo */
> -                               list_add(&ev->bind_link, &last);
> -                       else
> -                               list_add_tail(&ev->bind_link, &last);
> -               }
> -               list_splice_tail(&last, &eb->unbound);
> -
> -               switch (pass++) {
> -               case 0:
> -                       break;
> +               if (pass == 2) {
> +                       /* No point in defragmenting gtt if all is pinned */
> +                       if (!unpinned)
> +                               return -ENOSPC;

Can this ever happen? If everything is already pinned where it's meant
to be, then how did we get here?

>
> -               case 1:
> -                       /* Too fragmented, unbind everything and retry */
> -                       mutex_lock(&eb->context->vm->mutex);
> -                       err = i915_gem_evict_vm(eb->context->vm, &eb->ww);
> -                       mutex_unlock(&eb->context->vm->mutex);
> +                       err = eb_evict_vm(eb);
>                         if (err)
>                                 return err;
> -                       break;
> +               }
>
> -               default:
> -                       return -ENOSPC;
> +               list_for_each_entry(ev, &eb->unbound, bind_link) {
> +                       err = eb_reserve_vma(eb, ev, pin_flags);
> +                       if (err)
> +                               break;
>                 }
>
> -               pin_flags = PIN_USER;
> -       } while (1);
> +               if (err != -ENOSPC)
> +                       break;
> +       }
> +
> +       return err;
>  }
>
>  static int eb_select_context(struct i915_execbuffer *eb)
> @@ -1184,10 +1220,11 @@ static void *reloc_kmap(struct drm_i915_gem_object *obj,
>         return vaddr;
>  }
>
> -static void *reloc_iomap(struct drm_i915_gem_object *obj,
> +static void *reloc_iomap(struct i915_vma *batch,
>                          struct i915_execbuffer *eb,
>                          unsigned long page)
>  {
> +       struct drm_i915_gem_object *obj = batch->obj;
>         struct reloc_cache *cache = &eb->reloc_cache;
>         struct i915_ggtt *ggtt = cache_to_ggtt(cache);
>         unsigned long offset;
> @@ -1197,7 +1234,7 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
>                 intel_gt_flush_ggtt_writes(ggtt->vm.gt);
>                 io_mapping_unmap_atomic((void __force __iomem *) unmask_page(cache->vaddr));
>         } else {
> -               struct i915_vma *vma;
> +               struct i915_vma *vma = ERR_PTR(-ENODEV);
>                 int err;
>
>                 if (i915_gem_object_is_tiled(obj))
> @@ -1210,10 +1247,23 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
>                 if (err)
>                         return ERR_PTR(err);
>
> -               vma = i915_gem_object_ggtt_pin_ww(obj, &eb->ww, NULL, 0, 0,
> -                                                 PIN_MAPPABLE |
> -                                                 PIN_NONBLOCK /* NOWARN */ |
> -                                                 PIN_NOEVICT);
> +               /*
> +                * i915_gem_object_ggtt_pin_ww may attempt to remove the batch
> +                * VMA from the object list because we no longer pin.
> +                *
> +                * Only attempt to pin the batch buffer to ggtt if the current batch
> +                * is not inside ggtt, or the batch buffer is not misplaced.
> +                */
> +               if (!i915_is_ggtt(batch->vm)) {
> +                       vma = i915_gem_object_ggtt_pin_ww(obj, &eb->ww, NULL, 0, 0,
> +                                                         PIN_MAPPABLE |
> +                                                         PIN_NONBLOCK /* NOWARN */ |
> +                                                         PIN_NOEVICT);
> +               } else if (i915_vma_is_map_and_fenceable(batch)) {
> +                       __i915_vma_pin(batch);
> +                       vma = batch;
> +               }
> +
>                 if (vma == ERR_PTR(-EDEADLK))
>                         return vma;
>
> @@ -1251,7 +1301,7 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
>         return vaddr;
>  }
>
> -static void *reloc_vaddr(struct drm_i915_gem_object *obj,
> +static void *reloc_vaddr(struct i915_vma *vma,
>                          struct i915_execbuffer *eb,
>                          unsigned long page)
>  {
> @@ -1263,9 +1313,9 @@ static void *reloc_vaddr(struct drm_i915_gem_object *obj,
>         } else {
>                 vaddr = NULL;
>                 if ((cache->vaddr & KMAP) == 0)
> -                       vaddr = reloc_iomap(obj, eb, page);
> +                       vaddr = reloc_iomap(vma, eb, page);
>                 if (!vaddr)
> -                       vaddr = reloc_kmap(obj, cache, page);
> +                       vaddr = reloc_kmap(vma->obj, cache, page);
>         }
>
>         return vaddr;
> @@ -1306,7 +1356,7 @@ relocate_entry(struct i915_vma *vma,
>         void *vaddr;
>
>  repeat:
> -       vaddr = reloc_vaddr(vma->obj, eb,
> +       vaddr = reloc_vaddr(vma, eb,
>                             offset >> PAGE_SHIFT);
>         if (IS_ERR(vaddr))
>                 return PTR_ERR(vaddr);
> @@ -2074,7 +2124,7 @@ shadow_batch_pin(struct i915_execbuffer *eb,
>         if (IS_ERR(vma))
>                 return vma;
>
> -       err = i915_vma_pin_ww(vma, &eb->ww, 0, 0, flags);
> +       err = i915_vma_pin_ww(vma, &eb->ww, 0, 0, flags | PIN_VALIDATE);
>         if (err)
>                 return ERR_PTR(err);
>
> @@ -2088,7 +2138,7 @@ static struct i915_vma *eb_dispatch_secure(struct i915_execbuffer *eb, struct i9
>          * batch" bit. Hence we need to pin secure batches into the global gtt.
>          * hsw should have this fixed, but bdw mucks it up again. */
>         if (eb->batch_flags & I915_DISPATCH_SECURE)
> -               return i915_gem_object_ggtt_pin_ww(vma->obj, &eb->ww, NULL, 0, 0, 0);
> +               return i915_gem_object_ggtt_pin_ww(vma->obj, &eb->ww, NULL, 0, 0, PIN_VALIDATE);
>
>         return NULL;
>  }
> @@ -2139,13 +2189,12 @@ static int eb_parse(struct i915_execbuffer *eb)
>
>         err = i915_gem_object_lock(pool->obj, &eb->ww);
>         if (err)
> -               goto err;
> +               return err;
>
>         shadow = shadow_batch_pin(eb, pool->obj, eb->context->vm, PIN_USER);
> -       if (IS_ERR(shadow)) {
> -               err = PTR_ERR(shadow);
> -               goto err;
> -       }
> +       if (IS_ERR(shadow))
> +               return PTR_ERR(shadow);
> +
>         intel_gt_buffer_pool_mark_used(pool);
>         i915_gem_object_set_readonly(shadow->obj);
>         shadow->private = pool;
> @@ -2157,25 +2206,21 @@ static int eb_parse(struct i915_execbuffer *eb)
>                 shadow = shadow_batch_pin(eb, pool->obj,
>                                           &eb->gt->ggtt->vm,
>                                           PIN_GLOBAL);
> -               if (IS_ERR(shadow)) {
> -                       err = PTR_ERR(shadow);
> -                       shadow = trampoline;
> -                       goto err_shadow;
> -               }
> +               if (IS_ERR(shadow))
> +                       return PTR_ERR(shadow);
> +
>                 shadow->private = pool;
>
>                 eb->batch_flags |= I915_DISPATCH_SECURE;
>         }
>
>         batch = eb_dispatch_secure(eb, shadow);
> -       if (IS_ERR(batch)) {
> -               err = PTR_ERR(batch);
> -               goto err_trampoline;
> -       }
> +       if (IS_ERR(batch))
> +               return PTR_ERR(batch);
>
>         err = dma_resv_reserve_shared(shadow->obj->base.resv, 1);
>         if (err)
> -               goto err_trampoline;
> +               return err;
>
>         err = intel_engine_cmd_parser(eb->context->engine,
>                                       eb->batches[0]->vma,
> @@ -2183,7 +2228,7 @@ static int eb_parse(struct i915_execbuffer *eb)
>                                       eb->batch_len[0],
>                                       shadow, trampoline);
>         if (err)
> -               goto err_unpin_batch;
> +               return err;
>
>         eb->batches[0] = &eb->vma[eb->buffer_count++];
>         eb->batches[0]->vma = i915_vma_get(shadow);
> @@ -2202,17 +2247,6 @@ static int eb_parse(struct i915_execbuffer *eb)
>                 eb->batches[0]->vma = i915_vma_get(batch);
>         }
>         return 0;
> -
> -err_unpin_batch:
> -       if (batch)
> -               i915_vma_unpin(batch);
> -err_trampoline:
> -       if (trampoline)
> -               i915_vma_unpin(trampoline);
> -err_shadow:
> -       i915_vma_unpin(shadow);
> -err:
> -       return err;
>  }
>
>  static int eb_request_submit(struct i915_execbuffer *eb,
> @@ -3337,8 +3371,6 @@ i915_gem_do_execbuffer(struct drm_device *dev,
>
>  err_vma:
>         eb_release_vmas(&eb, true);
> -       if (eb.trampoline)
> -               i915_vma_unpin(eb.trampoline);
>         WARN_ON(err == -EDEADLK);
>         i915_gem_ww_ctx_fini(&eb.ww);
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
> index e4938aba3fe9..8c2f57eb5dda 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.h
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
> @@ -44,6 +44,7 @@ int i915_gem_gtt_insert(struct i915_address_space *vm,
>  #define PIN_HIGH               BIT_ULL(5)
>  #define PIN_OFFSET_BIAS                BIT_ULL(6)
>  #define PIN_OFFSET_FIXED       BIT_ULL(7)
> +#define PIN_VALIDATE           BIT_ULL(8) /* validate placement only, no need to call unpin() */
>
>  #define PIN_GLOBAL             BIT_ULL(10) /* I915_VMA_GLOBAL_BIND */
>  #define PIN_USER               BIT_ULL(11) /* I915_VMA_LOCAL_BIND */
> diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
> index 65168db534f0..0706731b211d 100644
> --- a/drivers/gpu/drm/i915/i915_vma.c
> +++ b/drivers/gpu/drm/i915/i915_vma.c
> @@ -751,6 +751,15 @@ static bool try_qad_pin(struct i915_vma *vma, unsigned int flags)
>         unsigned int bound;
>
>         bound = atomic_read(&vma->flags);
> +
> +       if (flags & PIN_VALIDATE) {
> +               flags &= I915_VMA_BIND_MASK;
> +
> +               return (flags & bound) == flags;
> +       }
> +
> +       /* with the lock mandatory for unbind, we don't race here */
> +       flags &= I915_VMA_BIND_MASK;
>         do {
>                 if (unlikely(flags & ~bound))
>                         return false;
> @@ -1176,7 +1185,7 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
>         GEM_BUG_ON(!(flags & (PIN_USER | PIN_GLOBAL)));
>
>         /* First try and grab the pin without rebinding the vma */
> -       if (try_qad_pin(vma, flags & I915_VMA_BIND_MASK))
> +       if (try_qad_pin(vma, flags))
>                 return 0;
>
>         err = i915_vma_get_pages(vma);
> @@ -1255,7 +1264,8 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
>         }
>
>         if (unlikely(!(flags & ~bound & I915_VMA_BIND_MASK))) {
> -               __i915_vma_pin(vma);
> +               if (!(flags & PIN_VALIDATE))
> +                       __i915_vma_pin(vma);
>                 goto err_unlock;
>         }
>
> @@ -1284,8 +1294,10 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
>         atomic_add(I915_VMA_PAGES_ACTIVE, &vma->pages_count);
>         list_move_tail(&vma->vm_link, &vma->vm->bound_list);
>
> -       __i915_vma_pin(vma);
> -       GEM_BUG_ON(!i915_vma_is_pinned(vma));
> +       if (!(flags & PIN_VALIDATE)) {
> +               __i915_vma_pin(vma);
> +               GEM_BUG_ON(!i915_vma_is_pinned(vma));
> +       }
>         GEM_BUG_ON(!i915_vma_is_bound(vma, flags));
>         GEM_BUG_ON(i915_vma_misplaced(vma, size, alignment, flags));
>
> @@ -1538,8 +1550,6 @@ static int __i915_vma_move_to_active(struct i915_vma *vma, struct i915_request *
>  {
>         int err;
>
> -       GEM_BUG_ON(!i915_vma_is_pinned(vma));
> -
>         /* Wait for the vma to be bound before we start! */
>         err = __i915_request_await_bind(rq, vma);
>         if (err)
> @@ -1558,6 +1568,8 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
>
>         assert_object_held(obj);
>
> +       GEM_BUG_ON(!vma->pages);
> +
>         err = __i915_vma_move_to_active(vma, rq);
>         if (unlikely(err))
>                 return err;
> --
> 2.33.0
>

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 28/28] drm/i915: Remove short-term pins from execbuf, v4.
@ 2021-10-25 15:02     ` Matthew Auld
  0 siblings, 0 replies; 114+ messages in thread
From: Matthew Auld @ 2021-10-25 15:02 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Intel Graphics Development, ML dri-devel

On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
>
> Add a flag PIN_VALIDATE, to indicate we don't need to pin and only
> protected by the object lock.
>
> This removes the need to unpin, which is done by just releasing the
> lock.
>
> eb_reserve is slightly reworked for readability, but the same steps
> are still done:
> - First pass pins with NONBLOCK.
> - Second pass unbinds all objects first, then pins.
> - Third pass is only called when not all objects are softpinned, and
>   unbinds all objects, then calls i915_gem_evict_vm(), then pins.
>
> When evicting the entire vm in eb_reserve() we do temporarily pin objects
> that are marked with EXEC_OBJECT_PINNED. This is because they are already
> at their destination, and i915_gem_evict_vm() would otherwise unbind them.
>
> However, we reduce the visibility of those pins by limiting the pin
> to our call to i915_gem_evict_vm() only, and pin with vm->mutex held,
> instead of the entire duration of the execbuf.
>
> Not sure the latter matters, one can hope..
> In theory we could kill the pinning by adding an extra flag to the vma
> to temporarily prevent unbinding for gtt for i915_gem_evict_vm only, but
> I think that might be overkill. We're still holding the object lock, and
> we don't have blocking eviction yet. It's likely sufficient to simply
> enforce EXEC_OBJECT_PINNED for all objects on >= gen12.
>
> Changes since v1:
> - Split out eb_reserve() into separate functions for readability.
> Changes since v2:
> - Make batch buffer mappable on platforms where only GGTT is available,
>   to prevent moving the batch buffer during relocations.
> Changes since v3:
> - Preserve current behavior for batch buffer, instead be cautious when
>   calling i915_gem_object_ggtt_pin_ww, and re-use the current batch vma
>   if it's inside ggtt and map-and-fenceable.
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 252 ++++++++++--------
>  drivers/gpu/drm/i915/i915_gem_gtt.h           |   1 +
>  drivers/gpu/drm/i915/i915_vma.c               |  24 +-
>  3 files changed, 161 insertions(+), 116 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> index bbf2a10738f7..19f91143cfcf 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> @@ -439,7 +439,7 @@ eb_pin_vma(struct i915_execbuffer *eb,
>         else
>                 pin_flags = entry->offset & PIN_OFFSET_MASK;
>
> -       pin_flags |= PIN_USER | PIN_NOEVICT | PIN_OFFSET_FIXED;
> +       pin_flags |= PIN_USER | PIN_NOEVICT | PIN_OFFSET_FIXED | PIN_VALIDATE;
>         if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_GTT))
>                 pin_flags |= PIN_GLOBAL;
>
> @@ -457,17 +457,15 @@ eb_pin_vma(struct i915_execbuffer *eb,
>                                              entry->pad_to_size,
>                                              entry->alignment,
>                                              eb_pin_flags(entry, ev->flags) |
> -                                            PIN_USER | PIN_NOEVICT);
> +                                            PIN_USER | PIN_NOEVICT | PIN_VALIDATE);
>                 if (unlikely(err))
>                         return err;
>         }
>
>         if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_FENCE)) {
>                 err = i915_vma_pin_fence(vma);
> -               if (unlikely(err)) {
> -                       i915_vma_unpin(vma);
> +               if (unlikely(err))
>                         return err;
> -               }
>
>                 if (vma->fence)
>                         ev->flags |= __EXEC_OBJECT_HAS_FENCE;
> @@ -483,13 +481,9 @@ eb_pin_vma(struct i915_execbuffer *eb,
>  static inline void
>  eb_unreserve_vma(struct eb_vma *ev)
>  {
> -       if (!(ev->flags & __EXEC_OBJECT_HAS_PIN))
> -               return;
> -
>         if (unlikely(ev->flags & __EXEC_OBJECT_HAS_FENCE))
>                 __i915_vma_unpin_fence(ev->vma);
>
> -       __i915_vma_unpin(ev->vma);
>         ev->flags &= ~__EXEC_OBJECT_RESERVED;
>  }
>
> @@ -682,10 +676,8 @@ static int eb_reserve_vma(struct i915_execbuffer *eb,
>
>         if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_FENCE)) {
>                 err = i915_vma_pin_fence(vma);
> -               if (unlikely(err)) {
> -                       i915_vma_unpin(vma);
> +               if (unlikely(err))
>                         return err;
> -               }
>
>                 if (vma->fence)
>                         ev->flags |= __EXEC_OBJECT_HAS_FENCE;
> @@ -697,85 +689,129 @@ static int eb_reserve_vma(struct i915_execbuffer *eb,
>         return 0;
>  }
>
> -static int eb_reserve(struct i915_execbuffer *eb)
> +static int eb_evict_vm(struct i915_execbuffer *eb)
> +{
> +       const unsigned int count = eb->buffer_count;
> +       unsigned int i;
> +       int err;
> +
> +       err = mutex_lock_interruptible(&eb->context->vm->mutex);
> +       if (err)
> +               return err;
> +
> +       /* pin to protect against i915_gem_evict_vm evicting below */
> +       for (i = 0; i < count; i++) {
> +               struct eb_vma *ev = &eb->vma[i];
> +
> +               if (ev->flags & __EXEC_OBJECT_HAS_PIN)
> +                       __i915_vma_pin(ev->vma);
> +       }
> +
> +       /* Too fragmented, unbind everything and retry */
> +       err = i915_gem_evict_vm(eb->context->vm, &eb->ww);
> +
> +       /* unpin objects.. */
> +       for (i = 0; i < count; i++) {
> +               struct eb_vma *ev = &eb->vma[i];
> +
> +               if (ev->flags & __EXEC_OBJECT_HAS_PIN)
> +                       i915_vma_unpin(ev->vma);
> +       }
> +
> +       mutex_unlock(&eb->context->vm->mutex);
> +
> +       return err;
> +}
> +
> +static bool eb_unbind(struct i915_execbuffer *eb)
>  {
>         const unsigned int count = eb->buffer_count;
> -       unsigned int pin_flags = PIN_USER | PIN_NONBLOCK;
> +       unsigned int i;
>         struct list_head last;
> +       bool unpinned = false;
> +
> +       /* Resort *all* the objects into priority order */
> +       INIT_LIST_HEAD(&eb->unbound);
> +       INIT_LIST_HEAD(&last);
> +
> +       for (i = 0; i < count; i++) {
> +               struct eb_vma *ev = &eb->vma[i];
> +               unsigned int flags = ev->flags;
> +
> +               if (flags & EXEC_OBJECT_PINNED &&
> +                   flags & __EXEC_OBJECT_HAS_PIN)
> +                       continue;
> +
> +               unpinned = true;
> +               eb_unreserve_vma(ev);
> +
> +               if (flags & EXEC_OBJECT_PINNED)
> +                       /* Pinned must have their slot */
> +                       list_add(&ev->bind_link, &eb->unbound);
> +               else if (flags & __EXEC_OBJECT_NEEDS_MAP)
> +                       /* Map require the lowest 256MiB (aperture) */
> +                       list_add_tail(&ev->bind_link, &eb->unbound);
> +               else if (!(flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS))
> +                       /* Prioritise 4GiB region for restricted bo */
> +                       list_add(&ev->bind_link, &last);
> +               else
> +                       list_add_tail(&ev->bind_link, &last);
> +       }
> +
> +       list_splice_tail(&last, &eb->unbound);
> +       return unpinned;
> +}
> +
> +static int eb_reserve(struct i915_execbuffer *eb)
> +{
>         struct eb_vma *ev;
> -       unsigned int i, pass;
> +       unsigned int pass;
>         int err = 0;
> +       bool unpinned;
>
>         /*
>          * Attempt to pin all of the buffers into the GTT.
> -        * This is done in 3 phases:
> +        * This is done in 2 phases:
>          *
> -        * 1a. Unbind all objects that do not match the GTT constraints for
> -        *     the execbuffer (fenceable, mappable, alignment etc).
> -        * 1b. Increment pin count for already bound objects.
> -        * 2.  Bind new objects.
> -        * 3.  Decrement pin count.
> +        * 1. Unbind all objects that do not match the GTT constraints for
> +        *    the execbuffer (fenceable, mappable, alignment etc).
> +        * 2. Bind new objects.
>          *
>          * This avoid unnecessary unbinding of later objects in order to make
>          * room for the earlier objects *unless* we need to defragment.
> +        *
> +        * Defragmenting is skipped if all objects are pinned at a fixed location.
>          */
> -       pass = 0;
> -       do {
> -               list_for_each_entry(ev, &eb->unbound, bind_link) {
> -                       err = eb_reserve_vma(eb, ev, pin_flags);
> -                       if (err)
> -                               break;
> -               }
> -               if (err != -ENOSPC)
> -                       return err;
> +       for (pass = 0; pass <= 2; pass++) {
> +               int pin_flags = PIN_USER | PIN_VALIDATE;
>
> -               /* Resort *all* the objects into priority order */
> -               INIT_LIST_HEAD(&eb->unbound);
> -               INIT_LIST_HEAD(&last);
> -               for (i = 0; i < count; i++) {
> -                       unsigned int flags;
> +               if (pass == 0)
> +                       pin_flags |= PIN_NONBLOCK;
>
> -                       ev = &eb->vma[i];
> -                       flags = ev->flags;
> -                       if (flags & EXEC_OBJECT_PINNED &&
> -                           flags & __EXEC_OBJECT_HAS_PIN)
> -                               continue;
> +               if (pass >= 1)
> +                       unpinned = eb_unbind(eb);
>
> -                       eb_unreserve_vma(ev);
> -
> -                       if (flags & EXEC_OBJECT_PINNED)
> -                               /* Pinned must have their slot */
> -                               list_add(&ev->bind_link, &eb->unbound);
> -                       else if (flags & __EXEC_OBJECT_NEEDS_MAP)
> -                               /* Map require the lowest 256MiB (aperture) */
> -                               list_add_tail(&ev->bind_link, &eb->unbound);
> -                       else if (!(flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS))
> -                               /* Prioritise 4GiB region for restricted bo */
> -                               list_add(&ev->bind_link, &last);
> -                       else
> -                               list_add_tail(&ev->bind_link, &last);
> -               }
> -               list_splice_tail(&last, &eb->unbound);
> -
> -               switch (pass++) {
> -               case 0:
> -                       break;
> +               if (pass == 2) {
> +                       /* No point in defragmenting gtt if all is pinned */
> +                       if (!unpinned)
> +                               return -ENOSPC;

Can this ever happen? If everything is already pinned where it's meant
to be, then how did we get here?

>
> -               case 1:
> -                       /* Too fragmented, unbind everything and retry */
> -                       mutex_lock(&eb->context->vm->mutex);
> -                       err = i915_gem_evict_vm(eb->context->vm, &eb->ww);
> -                       mutex_unlock(&eb->context->vm->mutex);
> +                       err = eb_evict_vm(eb);
>                         if (err)
>                                 return err;
> -                       break;
> +               }
>
> -               default:
> -                       return -ENOSPC;
> +               list_for_each_entry(ev, &eb->unbound, bind_link) {
> +                       err = eb_reserve_vma(eb, ev, pin_flags);
> +                       if (err)
> +                               break;
>                 }
>
> -               pin_flags = PIN_USER;
> -       } while (1);
> +               if (err != -ENOSPC)
> +                       break;
> +       }
> +
> +       return err;
>  }
>
>  static int eb_select_context(struct i915_execbuffer *eb)
> @@ -1184,10 +1220,11 @@ static void *reloc_kmap(struct drm_i915_gem_object *obj,
>         return vaddr;
>  }
>
> -static void *reloc_iomap(struct drm_i915_gem_object *obj,
> +static void *reloc_iomap(struct i915_vma *batch,
>                          struct i915_execbuffer *eb,
>                          unsigned long page)
>  {
> +       struct drm_i915_gem_object *obj = batch->obj;
>         struct reloc_cache *cache = &eb->reloc_cache;
>         struct i915_ggtt *ggtt = cache_to_ggtt(cache);
>         unsigned long offset;
> @@ -1197,7 +1234,7 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
>                 intel_gt_flush_ggtt_writes(ggtt->vm.gt);
>                 io_mapping_unmap_atomic((void __force __iomem *) unmask_page(cache->vaddr));
>         } else {
> -               struct i915_vma *vma;
> +               struct i915_vma *vma = ERR_PTR(-ENODEV);
>                 int err;
>
>                 if (i915_gem_object_is_tiled(obj))
> @@ -1210,10 +1247,23 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
>                 if (err)
>                         return ERR_PTR(err);
>
> -               vma = i915_gem_object_ggtt_pin_ww(obj, &eb->ww, NULL, 0, 0,
> -                                                 PIN_MAPPABLE |
> -                                                 PIN_NONBLOCK /* NOWARN */ |
> -                                                 PIN_NOEVICT);
> +               /*
> +                * i915_gem_object_ggtt_pin_ww may attempt to remove the batch
> +                * VMA from the object list because we no longer pin.
> +                *
> +                * Only attempt to pin the batch buffer to ggtt if the current batch
> +                * is not inside ggtt, or the batch buffer is not misplaced.
> +                */
> +               if (!i915_is_ggtt(batch->vm)) {
> +                       vma = i915_gem_object_ggtt_pin_ww(obj, &eb->ww, NULL, 0, 0,
> +                                                         PIN_MAPPABLE |
> +                                                         PIN_NONBLOCK /* NOWARN */ |
> +                                                         PIN_NOEVICT);
> +               } else if (i915_vma_is_map_and_fenceable(batch)) {
> +                       __i915_vma_pin(batch);
> +                       vma = batch;
> +               }
> +
>                 if (vma == ERR_PTR(-EDEADLK))
>                         return vma;
>
> @@ -1251,7 +1301,7 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
>         return vaddr;
>  }
>
> -static void *reloc_vaddr(struct drm_i915_gem_object *obj,
> +static void *reloc_vaddr(struct i915_vma *vma,
>                          struct i915_execbuffer *eb,
>                          unsigned long page)
>  {
> @@ -1263,9 +1313,9 @@ static void *reloc_vaddr(struct drm_i915_gem_object *obj,
>         } else {
>                 vaddr = NULL;
>                 if ((cache->vaddr & KMAP) == 0)
> -                       vaddr = reloc_iomap(obj, eb, page);
> +                       vaddr = reloc_iomap(vma, eb, page);
>                 if (!vaddr)
> -                       vaddr = reloc_kmap(obj, cache, page);
> +                       vaddr = reloc_kmap(vma->obj, cache, page);
>         }
>
>         return vaddr;
> @@ -1306,7 +1356,7 @@ relocate_entry(struct i915_vma *vma,
>         void *vaddr;
>
>  repeat:
> -       vaddr = reloc_vaddr(vma->obj, eb,
> +       vaddr = reloc_vaddr(vma, eb,
>                             offset >> PAGE_SHIFT);
>         if (IS_ERR(vaddr))
>                 return PTR_ERR(vaddr);
> @@ -2074,7 +2124,7 @@ shadow_batch_pin(struct i915_execbuffer *eb,
>         if (IS_ERR(vma))
>                 return vma;
>
> -       err = i915_vma_pin_ww(vma, &eb->ww, 0, 0, flags);
> +       err = i915_vma_pin_ww(vma, &eb->ww, 0, 0, flags | PIN_VALIDATE);
>         if (err)
>                 return ERR_PTR(err);
>
> @@ -2088,7 +2138,7 @@ static struct i915_vma *eb_dispatch_secure(struct i915_execbuffer *eb, struct i9
>          * batch" bit. Hence we need to pin secure batches into the global gtt.
>          * hsw should have this fixed, but bdw mucks it up again. */
>         if (eb->batch_flags & I915_DISPATCH_SECURE)
> -               return i915_gem_object_ggtt_pin_ww(vma->obj, &eb->ww, NULL, 0, 0, 0);
> +               return i915_gem_object_ggtt_pin_ww(vma->obj, &eb->ww, NULL, 0, 0, PIN_VALIDATE);
>
>         return NULL;
>  }
> @@ -2139,13 +2189,12 @@ static int eb_parse(struct i915_execbuffer *eb)
>
>         err = i915_gem_object_lock(pool->obj, &eb->ww);
>         if (err)
> -               goto err;
> +               return err;
>
>         shadow = shadow_batch_pin(eb, pool->obj, eb->context->vm, PIN_USER);
> -       if (IS_ERR(shadow)) {
> -               err = PTR_ERR(shadow);
> -               goto err;
> -       }
> +       if (IS_ERR(shadow))
> +               return PTR_ERR(shadow);
> +
>         intel_gt_buffer_pool_mark_used(pool);
>         i915_gem_object_set_readonly(shadow->obj);
>         shadow->private = pool;
> @@ -2157,25 +2206,21 @@ static int eb_parse(struct i915_execbuffer *eb)
>                 shadow = shadow_batch_pin(eb, pool->obj,
>                                           &eb->gt->ggtt->vm,
>                                           PIN_GLOBAL);
> -               if (IS_ERR(shadow)) {
> -                       err = PTR_ERR(shadow);
> -                       shadow = trampoline;
> -                       goto err_shadow;
> -               }
> +               if (IS_ERR(shadow))
> +                       return PTR_ERR(shadow);
> +
>                 shadow->private = pool;
>
>                 eb->batch_flags |= I915_DISPATCH_SECURE;
>         }
>
>         batch = eb_dispatch_secure(eb, shadow);
> -       if (IS_ERR(batch)) {
> -               err = PTR_ERR(batch);
> -               goto err_trampoline;
> -       }
> +       if (IS_ERR(batch))
> +               return PTR_ERR(batch);
>
>         err = dma_resv_reserve_shared(shadow->obj->base.resv, 1);
>         if (err)
> -               goto err_trampoline;
> +               return err;
>
>         err = intel_engine_cmd_parser(eb->context->engine,
>                                       eb->batches[0]->vma,
> @@ -2183,7 +2228,7 @@ static int eb_parse(struct i915_execbuffer *eb)
>                                       eb->batch_len[0],
>                                       shadow, trampoline);
>         if (err)
> -               goto err_unpin_batch;
> +               return err;
>
>         eb->batches[0] = &eb->vma[eb->buffer_count++];
>         eb->batches[0]->vma = i915_vma_get(shadow);
> @@ -2202,17 +2247,6 @@ static int eb_parse(struct i915_execbuffer *eb)
>                 eb->batches[0]->vma = i915_vma_get(batch);
>         }
>         return 0;
> -
> -err_unpin_batch:
> -       if (batch)
> -               i915_vma_unpin(batch);
> -err_trampoline:
> -       if (trampoline)
> -               i915_vma_unpin(trampoline);
> -err_shadow:
> -       i915_vma_unpin(shadow);
> -err:
> -       return err;
>  }
>
>  static int eb_request_submit(struct i915_execbuffer *eb,
> @@ -3337,8 +3371,6 @@ i915_gem_do_execbuffer(struct drm_device *dev,
>
>  err_vma:
>         eb_release_vmas(&eb, true);
> -       if (eb.trampoline)
> -               i915_vma_unpin(eb.trampoline);
>         WARN_ON(err == -EDEADLK);
>         i915_gem_ww_ctx_fini(&eb.ww);
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
> index e4938aba3fe9..8c2f57eb5dda 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.h
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
> @@ -44,6 +44,7 @@ int i915_gem_gtt_insert(struct i915_address_space *vm,
>  #define PIN_HIGH               BIT_ULL(5)
>  #define PIN_OFFSET_BIAS                BIT_ULL(6)
>  #define PIN_OFFSET_FIXED       BIT_ULL(7)
> +#define PIN_VALIDATE           BIT_ULL(8) /* validate placement only, no need to call unpin() */
>
>  #define PIN_GLOBAL             BIT_ULL(10) /* I915_VMA_GLOBAL_BIND */
>  #define PIN_USER               BIT_ULL(11) /* I915_VMA_LOCAL_BIND */
> diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
> index 65168db534f0..0706731b211d 100644
> --- a/drivers/gpu/drm/i915/i915_vma.c
> +++ b/drivers/gpu/drm/i915/i915_vma.c
> @@ -751,6 +751,15 @@ static bool try_qad_pin(struct i915_vma *vma, unsigned int flags)
>         unsigned int bound;
>
>         bound = atomic_read(&vma->flags);
> +
> +       if (flags & PIN_VALIDATE) {
> +               flags &= I915_VMA_BIND_MASK;
> +
> +               return (flags & bound) == flags;
> +       }
> +
> +       /* with the lock mandatory for unbind, we don't race here */
> +       flags &= I915_VMA_BIND_MASK;
>         do {
>                 if (unlikely(flags & ~bound))
>                         return false;
> @@ -1176,7 +1185,7 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
>         GEM_BUG_ON(!(flags & (PIN_USER | PIN_GLOBAL)));
>
>         /* First try and grab the pin without rebinding the vma */
> -       if (try_qad_pin(vma, flags & I915_VMA_BIND_MASK))
> +       if (try_qad_pin(vma, flags))
>                 return 0;
>
>         err = i915_vma_get_pages(vma);
> @@ -1255,7 +1264,8 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
>         }
>
>         if (unlikely(!(flags & ~bound & I915_VMA_BIND_MASK))) {
> -               __i915_vma_pin(vma);
> +               if (!(flags & PIN_VALIDATE))
> +                       __i915_vma_pin(vma);
>                 goto err_unlock;
>         }
>
> @@ -1284,8 +1294,10 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
>         atomic_add(I915_VMA_PAGES_ACTIVE, &vma->pages_count);
>         list_move_tail(&vma->vm_link, &vma->vm->bound_list);
>
> -       __i915_vma_pin(vma);
> -       GEM_BUG_ON(!i915_vma_is_pinned(vma));
> +       if (!(flags & PIN_VALIDATE)) {
> +               __i915_vma_pin(vma);
> +               GEM_BUG_ON(!i915_vma_is_pinned(vma));
> +       }
>         GEM_BUG_ON(!i915_vma_is_bound(vma, flags));
>         GEM_BUG_ON(i915_vma_misplaced(vma, size, alignment, flags));
>
> @@ -1538,8 +1550,6 @@ static int __i915_vma_move_to_active(struct i915_vma *vma, struct i915_request *
>  {
>         int err;
>
> -       GEM_BUG_ON(!i915_vma_is_pinned(vma));
> -
>         /* Wait for the vma to be bound before we start! */
>         err = __i915_request_await_bind(rq, vma);
>         if (err)
> @@ -1558,6 +1568,8 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
>
>         assert_object_held(obj);
>
> +       GEM_BUG_ON(!vma->pages);
> +
>         err = __i915_vma_move_to_active(vma, rq);
>         if (unlikely(err))
>                 return err;
> --
> 2.33.0
>

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [PATCH 21/28] drm/i915: Drain the ttm delayed workqueue too
  2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
@ 2021-10-25 15:11     ` Matthew Auld
  -1 siblings, 0 replies; 114+ messages in thread
From: Matthew Auld @ 2021-10-25 15:11 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Intel Graphics Development, ML dri-devel

On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
>
> Be thorough..
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

Is this strictly needed for something? Needs a proper commit message anyway.

> ---
>  drivers/gpu/drm/i915/i915_drv.h | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 22c891720c6d..7c5ed5957fe2 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1819,6 +1819,7 @@ static inline void i915_gem_drain_freed_objects(struct drm_i915_private *i915)
>          */
>         while (atomic_read(&i915->mm.free_count)) {
>                 flush_work(&i915->mm.free_work);
> +               flush_delayed_work(&i915->bdev.wq);
>                 rcu_barrier();
>         }
>  }
> --
> 2.33.0
>

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 21/28] drm/i915: Drain the ttm delayed workqueue too
@ 2021-10-25 15:11     ` Matthew Auld
  0 siblings, 0 replies; 114+ messages in thread
From: Matthew Auld @ 2021-10-25 15:11 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Intel Graphics Development, ML dri-devel

On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
>
> Be thorough..
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

Is this strictly needed for something? Needs a proper commit message anyway.

> ---
>  drivers/gpu/drm/i915/i915_drv.h | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 22c891720c6d..7c5ed5957fe2 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1819,6 +1819,7 @@ static inline void i915_gem_drain_freed_objects(struct drm_i915_private *i915)
>          */
>         while (atomic_read(&i915->mm.free_count)) {
>                 flush_work(&i915->mm.free_work);
> +               flush_delayed_work(&i915->bdev.wq);
>                 rcu_barrier();
>         }
>  }
> --
> 2.33.0
>

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 02/28] drm/i915: use new iterator in i915_gem_object_wait_reservation
  2021-10-21 11:13       ` Tvrtko Ursulin
@ 2021-10-28  8:41         ` Christian König
  2021-10-28 15:30           ` Daniel Vetter
  0 siblings, 1 reply; 114+ messages in thread
From: Christian König @ 2021-10-28  8:41 UTC (permalink / raw)
  To: Tvrtko Ursulin, Maarten Lankhorst, intel-gfx; +Cc: dri-devel, Daniel Vetter

Am 21.10.21 um 13:13 schrieb Tvrtko Ursulin:
>
> On 21/10/2021 12:06, Maarten Lankhorst wrote:
>> Op 21-10-2021 om 12:38 schreef Christian König:
>>> Am 21.10.21 um 12:35 schrieb Maarten Lankhorst:
>>>> From: Christian König <christian.koenig@amd.com>
>>>>
>>>> Simplifying the code a bit.
>>>>
>>>> Signed-off-by: Christian König <christian.koenig@amd.com>
>>>> [mlankhorst: Handle timeout = 0 correctly, use new 
>>>> i915_request_wait_timeout.]
>>>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>>>
>>> LGTM, do you want to push it or should I pick it up into drm-misc-next?
>>
>> I think it can be applied to drm-intel-gt-next, after a backmerge. It 
>> needs patch 1 too, which fixes
>>
>> i915_request_wait semantics when used in dma-fence. It exports a 
>> dma-fence compatible i915_request_wait_timeout function, used in this 
>> patch.

What about the other i915 patches? I guess you then want to merge them 
through drm-intel-gt-next as well.

> I don't think my open has been resolved, at least I haven't seen a 
> reply from Daniel on the topic of potential for infinite waits with 
> untrusted clients after this change. +Daniel

Please resolve that internally and let me know the result. I'm fine to 
use any of the possible approaches, I just need to know which one.

Regards,
Christian.

>
> Regards,
>
> Tvrtko


^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 02/28] drm/i915: use new iterator in i915_gem_object_wait_reservation
  2021-10-28  8:41         ` Christian König
@ 2021-10-28 15:30           ` Daniel Vetter
  2021-11-01  9:41             ` Tvrtko Ursulin
  0 siblings, 1 reply; 114+ messages in thread
From: Daniel Vetter @ 2021-10-28 15:30 UTC (permalink / raw)
  To: Christian König
  Cc: Tvrtko Ursulin, Maarten Lankhorst, intel-gfx, dri-devel, Daniel Vetter

On Thu, Oct 28, 2021 at 10:41:38AM +0200, Christian König wrote:
> Am 21.10.21 um 13:13 schrieb Tvrtko Ursulin:
> > 
> > On 21/10/2021 12:06, Maarten Lankhorst wrote:
> > > Op 21-10-2021 om 12:38 schreef Christian König:
> > > > Am 21.10.21 um 12:35 schrieb Maarten Lankhorst:
> > > > > From: Christian König <christian.koenig@amd.com>
> > > > > 
> > > > > Simplifying the code a bit.
> > > > > 
> > > > > Signed-off-by: Christian König <christian.koenig@amd.com>
> > > > > [mlankhorst: Handle timeout = 0 correctly, use new
> > > > > i915_request_wait_timeout.]
> > > > > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > 
> > > > LGTM, do you want to push it or should I pick it up into drm-misc-next?
> > > 
> > > I think it can be applied to drm-intel-gt-next, after a backmerge.
> > > It needs patch 1 too, which fixes
> > > 
> > > i915_request_wait semantics when used in dma-fence. It exports a
> > > dma-fence compatible i915_request_wait_timeout function, used in
> > > this patch.
> 
> What about the other i915 patches? I guess you then want to merge them
> through drm-intel-gt-next as well.
> 
> > I don't think my open has been resolved, at least I haven't seen a reply
> > from Daniel on the topic of potential for infinite waits with untrusted
> > clients after this change. +Daniel
> 
> Please resolve that internally and let me know the result. I'm fine to use
> any of the possible approaches, I just need to know which one.

I thought I explained this in the patch set from Maarten. This isn't an
issue, since the exact same thing can happen if you get interrupts and
stuff.

The only proper fix for bounding the waits is a) compositor grabs a stable
set of dma_fence from the dma-buf through the proposed fence export ioctl
b) compositor waits on that fence (or drm_syncobj).

Everything else is cargo-culted nonsense, and very much includes that igt
patch that's floating around internally.

I can also whack this into drm-next if this is stuck in this silly
bikeshed.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 02/28] drm/i915: use new iterator in i915_gem_object_wait_reservation
  2021-10-28 15:30           ` Daniel Vetter
@ 2021-11-01  9:41             ` Tvrtko Ursulin
  2021-11-11 11:36               ` Christian König
  0 siblings, 1 reply; 114+ messages in thread
From: Tvrtko Ursulin @ 2021-11-01  9:41 UTC (permalink / raw)
  To: Daniel Vetter, Christian König; +Cc: intel-gfx, dri-devel


On 28/10/2021 16:30, Daniel Vetter wrote:
> On Thu, Oct 28, 2021 at 10:41:38AM +0200, Christian König wrote:
>> Am 21.10.21 um 13:13 schrieb Tvrtko Ursulin:
>>>
>>> On 21/10/2021 12:06, Maarten Lankhorst wrote:
>>>> Op 21-10-2021 om 12:38 schreef Christian König:
>>>>> Am 21.10.21 um 12:35 schrieb Maarten Lankhorst:
>>>>>> From: Christian König <christian.koenig@amd.com>
>>>>>>
>>>>>> Simplifying the code a bit.
>>>>>>
>>>>>> Signed-off-by: Christian König <christian.koenig@amd.com>
>>>>>> [mlankhorst: Handle timeout = 0 correctly, use new
>>>>>> i915_request_wait_timeout.]
>>>>>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>>>>>
>>>>> LGTM, do you want to push it or should I pick it up into drm-misc-next?
>>>>
>>>> I think it can be applied to drm-intel-gt-next, after a backmerge.
>>>> It needs patch 1 too, which fixes
>>>>
>>>> i915_request_wait semantics when used in dma-fence. It exports a
>>>> dma-fence compatible i915_request_wait_timeout function, used in
>>>> this patch.
>>
>> What about the other i915 patches? I guess you then want to merge them
>> through drm-intel-gt-next as well.
>>
>>> I don't think my open has been resolved, at least I haven't seen a reply
>>> from Daniel on the topic of potential for infinite waits with untrusted
>>> clients after this change. +Daniel
>>
>> Please resolve that internally and let me know the result. I'm fine to use
>> any of the possible approaches, I just need to know which one.
> 
> I thought I explained this in the patch set from Maarten. This isn't an
> issue, since the exact same thing can happen if you get interrupts and
> stuff.

Ah were you trying to point out all this time the infinite wait just got 
moved from inside the "old" dma_resv_get_fences to the new iterator caller?

Regards,

Tvrtko

> 
> The only proper fix for bounding the waits is a) compositor grabs a stable
> set of dma_fence from the dma-buf through the proposed fence export ioctl
> b) compositor waits on that fence (or drm_syncobj).
> 
> Everything else is cargo-culted nonsense, and very much includes that igt
> patch that's floating around internally.
> 
> I can also whack this into drm-next if this is stuck in this silly
> bikeshed.
> -Daniel
> 

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 11/28] drm/i915/pm: Move CONTEXT_VALID_BIT check
  2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
@ 2021-11-02 16:13     ` Matthew Auld
  -1 siblings, 0 replies; 114+ messages in thread
From: Matthew Auld @ 2021-11-02 16:13 UTC (permalink / raw)
  To: Maarten Lankhorst
  Cc: Intel Graphics Development, Niranjana Vishwanathapura, ML dri-devel

On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
>
> Resetting will clear the CONTEXT_VALID_BIT, so wait until after that to test.
>

AFAIK this seems to be fixing something earlier in the series(maybe
patch 7?) i.e without this patch we seem to trigger the BUG_ON. If so,
this needs to be much earlier in the series?

Also this probably needs some more commentary in the commit message
for whether moving the BUG_ON matters, or if this is potentially
papering over something significant?

> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Reviewed-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
> ---
>  drivers/gpu/drm/i915/gt/intel_engine_pm.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.c b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
> index a1334b48dde7..849fbb229bd3 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c
> +++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
> @@ -52,8 +52,6 @@ static int __engine_unpark(struct intel_wakeref *wf)
>         /* Discard stale context state from across idling */
>         ce = engine->kernel_context;
>         if (ce) {
> -               GEM_BUG_ON(test_bit(CONTEXT_VALID_BIT, &ce->flags));
> -
>                 /* Flush all pending HW writes before we touch the context */
>                 while (unlikely(intel_context_inflight(ce)))
>                         intel_engine_flush_submission(engine);
> @@ -68,6 +66,9 @@ static int __engine_unpark(struct intel_wakeref *wf)
>                          ce->timeline->seqno,
>                          READ_ONCE(*ce->timeline->hwsp_seqno),
>                          ce->ring->emit);
> +
> +               GEM_BUG_ON(test_bit(CONTEXT_VALID_BIT, &ce->flags));
> +
>                 GEM_BUG_ON(ce->timeline->seqno !=
>                            READ_ONCE(*ce->timeline->hwsp_seqno));
>         }
> --
> 2.33.0
>

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 11/28] drm/i915/pm: Move CONTEXT_VALID_BIT check
@ 2021-11-02 16:13     ` Matthew Auld
  0 siblings, 0 replies; 114+ messages in thread
From: Matthew Auld @ 2021-11-02 16:13 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Intel Graphics Development, ML dri-devel

On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
>
> Resetting will clear the CONTEXT_VALID_BIT, so wait until after that to test.
>

AFAIK this seems to be fixing something earlier in the series(maybe
patch 7?) i.e without this patch we seem to trigger the BUG_ON. If so,
this needs to be much earlier in the series?

Also this probably needs some more commentary in the commit message
for whether moving the BUG_ON matters, or if this is potentially
papering over something significant?

> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Reviewed-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
> ---
>  drivers/gpu/drm/i915/gt/intel_engine_pm.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.c b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
> index a1334b48dde7..849fbb229bd3 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c
> +++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
> @@ -52,8 +52,6 @@ static int __engine_unpark(struct intel_wakeref *wf)
>         /* Discard stale context state from across idling */
>         ce = engine->kernel_context;
>         if (ce) {
> -               GEM_BUG_ON(test_bit(CONTEXT_VALID_BIT, &ce->flags));
> -
>                 /* Flush all pending HW writes before we touch the context */
>                 while (unlikely(intel_context_inflight(ce)))
>                         intel_engine_flush_submission(engine);
> @@ -68,6 +66,9 @@ static int __engine_unpark(struct intel_wakeref *wf)
>                          ce->timeline->seqno,
>                          READ_ONCE(*ce->timeline->hwsp_seqno),
>                          ce->ring->emit);
> +
> +               GEM_BUG_ON(test_bit(CONTEXT_VALID_BIT, &ce->flags));
> +
>                 GEM_BUG_ON(ce->timeline->seqno !=
>                            READ_ONCE(*ce->timeline->hwsp_seqno));
>         }
> --
> 2.33.0
>

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 16/28] drm/i915: Rework context handling in hugepages selftests
  2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
                     ` (3 preceding siblings ...)
  (?)
@ 2021-11-03 11:33   ` kernel test robot
  -1 siblings, 0 replies; 114+ messages in thread
From: kernel test robot @ 2021-11-03 11:33 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 1924 bytes --]

Hi Maarten,

I love your patch! Perhaps something to improve:

[auto build test WARNING on drm-tip/drm-tip]
[also build test WARNING on next-20211103]
[cannot apply to drm-intel/for-linux-next drm-exynos/exynos-drm-next tegra-drm/drm/tegra/for-next airlied/drm-next v5.15]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Maarten-Lankhorst/drm-i915-Fix-i915_request-fence-wait-semantics/20211021-183839
base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
config: i386-randconfig-s001-20211101 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.4-dirty
        # https://github.com/0day-ci/linux/commit/536df9470ecdddde67095f4f40f37752d944c343
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Maarten-Lankhorst/drm-i915-Fix-i915_request-fence-wait-semantics/20211021-183839
        git checkout 536df9470ecdddde67095f4f40f37752d944c343
        # save the attached .config to linux build tree
        make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=i386 SHELL=/bin/bash drivers/gpu/drm/i915/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


sparse warnings: (new ones prefixed by >>)
   drivers/gpu/drm/i915/gem/i915_gem_object.c: note: in included file:
>> drivers/gpu/drm/i915/gem/selftests/huge_pages.c:25:25: sparse: sparse: symbol 'hugepage_ctx' was not declared. Should it be static?

Please review and possibly fold the followup patch.

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 34389 bytes --]

^ permalink raw reply	[flat|nested] 114+ messages in thread

* [RFC PATCH] drm/i915: hugepage_ctx() can be static
  2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
                     ` (4 preceding siblings ...)
  (?)
@ 2021-11-03 11:33   ` kernel test robot
  -1 siblings, 0 replies; 114+ messages in thread
From: kernel test robot @ 2021-11-03 11:33 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 950 bytes --]

drivers/gpu/drm/i915/gem/selftests/huge_pages.c:25:25: warning: symbol 'hugepage_ctx' was not declared. Should it be static?

Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: kernel test robot <lkp@intel.com>
---
 huge_pages.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index 493509f90b35c..81f09530e9a88 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -22,7 +22,7 @@
 #include "selftests/mock_region.h"
 #include "selftests/i915_random.h"
 
-struct i915_gem_context *hugepage_ctx(struct drm_i915_private *i915, struct file *file)
+static struct i915_gem_context *hugepage_ctx(struct drm_i915_private *i915, struct file *file)
 {
 	struct i915_gem_context *ctx = live_context(i915, file);
 	struct i915_address_space *vm;

^ permalink raw reply related	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 02/28] drm/i915: use new iterator in i915_gem_object_wait_reservation
  2021-11-01  9:41             ` Tvrtko Ursulin
@ 2021-11-11 11:36               ` Christian König
  2021-11-12 16:07                   ` Daniel Vetter
  0 siblings, 1 reply; 114+ messages in thread
From: Christian König @ 2021-11-11 11:36 UTC (permalink / raw)
  To: Tvrtko Ursulin, Daniel Vetter; +Cc: intel-gfx, dri-devel

Am 01.11.21 um 10:41 schrieb Tvrtko Ursulin:
>
> On 28/10/2021 16:30, Daniel Vetter wrote:
>> On Thu, Oct 28, 2021 at 10:41:38AM +0200, Christian König wrote:
>>> Am 21.10.21 um 13:13 schrieb Tvrtko Ursulin:
>>>>
>>>> On 21/10/2021 12:06, Maarten Lankhorst wrote:
>>>>> Op 21-10-2021 om 12:38 schreef Christian König:
>>>>>> Am 21.10.21 um 12:35 schrieb Maarten Lankhorst:
>>>>>>> From: Christian König <christian.koenig@amd.com>
>>>>>>>
>>>>>>> Simplifying the code a bit.
>>>>>>>
>>>>>>> Signed-off-by: Christian König <christian.koenig@amd.com>
>>>>>>> [mlankhorst: Handle timeout = 0 correctly, use new
>>>>>>> i915_request_wait_timeout.]
>>>>>>> Signed-off-by: Maarten Lankhorst 
>>>>>>> <maarten.lankhorst@linux.intel.com>
>>>>>>
>>>>>> LGTM, do you want to push it or should I pick it up into 
>>>>>> drm-misc-next?
>>>>>
>>>>> I think it can be applied to drm-intel-gt-next, after a backmerge.
>>>>> It needs patch 1 too, which fixes
>>>>>
>>>>> i915_request_wait semantics when used in dma-fence. It exports a
>>>>> dma-fence compatible i915_request_wait_timeout function, used in
>>>>> this patch.
>>>
>>> What about the other i915 patches? I guess you then want to merge them
>>> through drm-intel-gt-next as well.
>>>
>>>> I don't think my open has been resolved, at least I haven't seen a 
>>>> reply
>>>> from Daniel on the topic of potential for infinite waits with 
>>>> untrusted
>>>> clients after this change. +Daniel
>>>
>>> Please resolve that internally and let me know the result. I'm fine 
>>> to use
>>> any of the possible approaches, I just need to know which one.
>>
>> I thought I explained this in the patch set from Maarten. This isn't an
>> issue, since the exact same thing can happen if you get interrupts and
>> stuff.
>
> Ah were you trying to point out all this time the infinite wait just 
> got moved from inside the "old" dma_resv_get_fences to the new 
> iterator caller?

At least I think so, yes. But Daniel needs to answer that.

>
> Regards,
>
> Tvrtko
>
>>
>> The only proper fix for bounding the waits is a) compositor grabs a 
>> stable
>> set of dma_fence from the dma-buf through the proposed fence export 
>> ioctl
>> b) compositor waits on that fence (or drm_syncobj).
>>
>> Everything else is cargo-culted nonsense, and very much includes that 
>> igt
>> patch that's floating around internally.
>>
>> I can also whack this into drm-next if this is stuck in this silly
>> bikeshed.

Can we move forward with those patches? I still don't see them in 
drm-misc-next.

I you want I can also pick Maartens modified version here up and send it 
out with the reset of the i915 patches once more.

Everything else is already pushed.

Thanks,
Christian.

>> -Daniel
>>


^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 02/28] drm/i915: use new iterator in i915_gem_object_wait_reservation
  2021-11-11 11:36               ` Christian König
@ 2021-11-12 16:07                   ` Daniel Vetter
  0 siblings, 0 replies; 114+ messages in thread
From: Daniel Vetter @ 2021-11-12 16:07 UTC (permalink / raw)
  To: Christian König; +Cc: Tvrtko Ursulin, intel-gfx, dri-devel

On Thu, Nov 11, 2021 at 12:36:47PM +0100, Christian König wrote:
> Am 01.11.21 um 10:41 schrieb Tvrtko Ursulin:
> > 
> > On 28/10/2021 16:30, Daniel Vetter wrote:
> > > On Thu, Oct 28, 2021 at 10:41:38AM +0200, Christian König wrote:
> > > > Am 21.10.21 um 13:13 schrieb Tvrtko Ursulin:
> > > > > 
> > > > > On 21/10/2021 12:06, Maarten Lankhorst wrote:
> > > > > > Op 21-10-2021 om 12:38 schreef Christian König:
> > > > > > > Am 21.10.21 um 12:35 schrieb Maarten Lankhorst:
> > > > > > > > From: Christian König <christian.koenig@amd.com>
> > > > > > > > 
> > > > > > > > Simplifying the code a bit.
> > > > > > > > 
> > > > > > > > Signed-off-by: Christian König <christian.koenig@amd.com>
> > > > > > > > [mlankhorst: Handle timeout = 0 correctly, use new
> > > > > > > > i915_request_wait_timeout.]
> > > > > > > > Signed-off-by: Maarten Lankhorst
> > > > > > > > <maarten.lankhorst@linux.intel.com>
> > > > > > > 
> > > > > > > LGTM, do you want to push it or should I pick it up
> > > > > > > into drm-misc-next?
> > > > > > 
> > > > > > I think it can be applied to drm-intel-gt-next, after a backmerge.
> > > > > > It needs patch 1 too, which fixes
> > > > > > 
> > > > > > i915_request_wait semantics when used in dma-fence. It exports a
> > > > > > dma-fence compatible i915_request_wait_timeout function, used in
> > > > > > this patch.
> > > > 
> > > > What about the other i915 patches? I guess you then want to merge them
> > > > through drm-intel-gt-next as well.
> > > > 
> > > > > I don't think my open has been resolved, at least I haven't
> > > > > seen a reply
> > > > > from Daniel on the topic of potential for infinite waits
> > > > > with untrusted
> > > > > clients after this change. +Daniel
> > > > 
> > > > Please resolve that internally and let me know the result. I'm
> > > > fine to use
> > > > any of the possible approaches, I just need to know which one.
> > > 
> > > I thought I explained this in the patch set from Maarten. This isn't an
> > > issue, since the exact same thing can happen if you get interrupts and
> > > stuff.
> > 
> > Ah were you trying to point out all this time the infinite wait just got
> > moved from inside the "old" dma_resv_get_fences to the new iterator
> > caller?
> 
> At least I think so, yes. But Daniel needs to answer that.

Well maybe there's also an infinite wait inside the old
dma_resv_get_fences, what I mean is that when you have some signals
interrupting you, then the infinite wait is already there due to a retry
loop outside of the syscall even.

Anyway _any_ userspace which wants to use this wait on a shared bo and
waits to be safe against the other end adding more rendering has to use
something else (like the sync_file export ioctl on the dma-buf that Jason
typed). Trying to make this ioctl here against fence addition is just bs.

> > Regards,
> > 
> > Tvrtko
> > 
> > > 
> > > The only proper fix for bounding the waits is a) compositor grabs a
> > > stable
> > > set of dma_fence from the dma-buf through the proposed fence export
> > > ioctl
> > > b) compositor waits on that fence (or drm_syncobj).
> > > 
> > > Everything else is cargo-culted nonsense, and very much includes
> > > that igt
> > > patch that's floating around internally.
> > > 
> > > I can also whack this into drm-next if this is stuck in this silly
> > > bikeshed.
> 
> Can we move forward with those patches? I still don't see them in
> drm-misc-next.
> 
> I you want I can also pick Maartens modified version here up and send it out
> with the reset of the i915 patches once more.
> 
> Everything else is already pushed.

Please push to drm-misc-next or wherever (assuming CI is happy) and feel
free to add my ack.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 02/28] drm/i915: use new iterator in i915_gem_object_wait_reservation
@ 2021-11-12 16:07                   ` Daniel Vetter
  0 siblings, 0 replies; 114+ messages in thread
From: Daniel Vetter @ 2021-11-12 16:07 UTC (permalink / raw)
  To: Christian König; +Cc: intel-gfx, dri-devel

On Thu, Nov 11, 2021 at 12:36:47PM +0100, Christian König wrote:
> Am 01.11.21 um 10:41 schrieb Tvrtko Ursulin:
> > 
> > On 28/10/2021 16:30, Daniel Vetter wrote:
> > > On Thu, Oct 28, 2021 at 10:41:38AM +0200, Christian König wrote:
> > > > Am 21.10.21 um 13:13 schrieb Tvrtko Ursulin:
> > > > > 
> > > > > On 21/10/2021 12:06, Maarten Lankhorst wrote:
> > > > > > Op 21-10-2021 om 12:38 schreef Christian König:
> > > > > > > Am 21.10.21 um 12:35 schrieb Maarten Lankhorst:
> > > > > > > > From: Christian König <christian.koenig@amd.com>
> > > > > > > > 
> > > > > > > > Simplifying the code a bit.
> > > > > > > > 
> > > > > > > > Signed-off-by: Christian König <christian.koenig@amd.com>
> > > > > > > > [mlankhorst: Handle timeout = 0 correctly, use new
> > > > > > > > i915_request_wait_timeout.]
> > > > > > > > Signed-off-by: Maarten Lankhorst
> > > > > > > > <maarten.lankhorst@linux.intel.com>
> > > > > > > 
> > > > > > > LGTM, do you want to push it or should I pick it up
> > > > > > > into drm-misc-next?
> > > > > > 
> > > > > > I think it can be applied to drm-intel-gt-next, after a backmerge.
> > > > > > It needs patch 1 too, which fixes
> > > > > > 
> > > > > > i915_request_wait semantics when used in dma-fence. It exports a
> > > > > > dma-fence compatible i915_request_wait_timeout function, used in
> > > > > > this patch.
> > > > 
> > > > What about the other i915 patches? I guess you then want to merge them
> > > > through drm-intel-gt-next as well.
> > > > 
> > > > > I don't think my open has been resolved, at least I haven't
> > > > > seen a reply
> > > > > from Daniel on the topic of potential for infinite waits
> > > > > with untrusted
> > > > > clients after this change. +Daniel
> > > > 
> > > > Please resolve that internally and let me know the result. I'm
> > > > fine to use
> > > > any of the possible approaches, I just need to know which one.
> > > 
> > > I thought I explained this in the patch set from Maarten. This isn't an
> > > issue, since the exact same thing can happen if you get interrupts and
> > > stuff.
> > 
> > Ah were you trying to point out all this time the infinite wait just got
> > moved from inside the "old" dma_resv_get_fences to the new iterator
> > caller?
> 
> At least I think so, yes. But Daniel needs to answer that.

Well maybe there's also an infinite wait inside the old
dma_resv_get_fences, what I mean is that when you have some signals
interrupting you, then the infinite wait is already there due to a retry
loop outside of the syscall even.

Anyway _any_ userspace which wants to use this wait on a shared bo and
waits to be safe against the other end adding more rendering has to use
something else (like the sync_file export ioctl on the dma-buf that Jason
typed). Trying to make this ioctl here against fence addition is just bs.

> > Regards,
> > 
> > Tvrtko
> > 
> > > 
> > > The only proper fix for bounding the waits is a) compositor grabs a
> > > stable
> > > set of dma_fence from the dma-buf through the proposed fence export
> > > ioctl
> > > b) compositor waits on that fence (or drm_syncobj).
> > > 
> > > Everything else is cargo-culted nonsense, and very much includes
> > > that igt
> > > patch that's floating around internally.
> > > 
> > > I can also whack this into drm-next if this is stuck in this silly
> > > bikeshed.
> 
> Can we move forward with those patches? I still don't see them in
> drm-misc-next.
> 
> I you want I can also pick Maartens modified version here up and send it out
> with the reset of the i915 patches once more.
> 
> Everything else is already pushed.

Please push to drm-misc-next or wherever (assuming CI is happy) and feel
free to add my ack.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 13/28] drm/i915: Remove pages_mutex and intel_gtt->vma_ops.set/clear_pages members
  2021-10-22 10:59     ` Matthew Auld
@ 2021-11-29 12:40       ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-11-29 12:40 UTC (permalink / raw)
  To: Matthew Auld; +Cc: Intel Graphics Development, ML dri-devel

On 22-10-2021 12:59, Matthew Auld wrote:
> On Thu, 21 Oct 2021 at 18:30, Matthew Auld
> <matthew.william.auld@gmail.com> wrote:
>> On Thu, 21 Oct 2021 at 11:36, Maarten Lankhorst
>> <maarten.lankhorst@linux.intel.com> wrote:
>>> Big delta, but boils down to moving set_pages to i915_vma.c, and removing
>>> the special handling, all callers use the defaults anyway. We only remap
>>> in ggtt, so default case will fall through.
>>>
>>> Because we still don't require locking in i915_vma_unpin(), handle this by
>>> using xchg in get_pages(), as it's locked with obj->mutex, and cmpxchg in
>>> unpin, which only fails if we race a against a new pin.
>>>
>>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>>> ---
>>>  drivers/gpu/drm/i915/display/intel_dpt.c      |   2 -
>>>  drivers/gpu/drm/i915/gt/gen6_ppgtt.c          |  15 -
>>>  drivers/gpu/drm/i915/gt/intel_ggtt.c          | 345 ----------------
>>>  drivers/gpu/drm/i915/gt/intel_gtt.c           |  13 -
>>>  drivers/gpu/drm/i915/gt/intel_gtt.h           |   7 -
>>>  drivers/gpu/drm/i915/gt/intel_ppgtt.c         |  12 -
>>>  drivers/gpu/drm/i915/i915_vma.c               | 388 ++++++++++++++++--
>>>  drivers/gpu/drm/i915/i915_vma.h               |   3 +
>>>  drivers/gpu/drm/i915/i915_vma_types.h         |   1 -
>>>  drivers/gpu/drm/i915/selftests/i915_gem_gtt.c |  12 +-
>>>  drivers/gpu/drm/i915/selftests/mock_gtt.c     |   4 -
>>>  11 files changed, 368 insertions(+), 434 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c
>>> index 8f7b1f7534a4..ef428f3fc538 100644
>>> --- a/drivers/gpu/drm/i915/display/intel_dpt.c
>>> +++ b/drivers/gpu/drm/i915/display/intel_dpt.c
>>> @@ -221,8 +221,6 @@ intel_dpt_create(struct intel_framebuffer *fb)
>>>
>>>         vm->vma_ops.bind_vma    = dpt_bind_vma;
>>>         vm->vma_ops.unbind_vma  = dpt_unbind_vma;
>>> -       vm->vma_ops.set_pages   = ggtt_set_pages;
>>> -       vm->vma_ops.clear_pages = clear_pages;
>>>
>>>         vm->pte_encode = gen8_ggtt_pte_encode;
>>>
>>> diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
>>> index 5caa1703716e..5c048b4ccd4d 100644
>>> --- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
>>> +++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
>>> @@ -270,19 +270,6 @@ static void gen6_ppgtt_cleanup(struct i915_address_space *vm)
>>>         free_pd(&ppgtt->base.vm, ppgtt->base.pd);
>>>  }
>>>
>>> -static int pd_vma_set_pages(struct i915_vma *vma)
>>> -{
>>> -       vma->pages = ERR_PTR(-ENODEV);
>>> -       return 0;
>>> -}
>>> -
>>> -static void pd_vma_clear_pages(struct i915_vma *vma)
>>> -{
>>> -       GEM_BUG_ON(!vma->pages);
>>> -
>>> -       vma->pages = NULL;
>>> -}
>>> -
>>>  static void pd_vma_bind(struct i915_address_space *vm,
>>>                         struct i915_vm_pt_stash *stash,
>>>                         struct i915_vma *vma,
>>> @@ -322,8 +309,6 @@ static void pd_vma_unbind(struct i915_address_space *vm, struct i915_vma *vma)
>>>  }
>>>
>>>  static const struct i915_vma_ops pd_vma_ops = {
>>> -       .set_pages = pd_vma_set_pages,
>>> -       .clear_pages = pd_vma_clear_pages,
>>>         .bind_vma = pd_vma_bind,
>>>         .unbind_vma = pd_vma_unbind,
>>>  };
>>> diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
>>> index f17383e76eb7..6da57199bb33 100644
>>> --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
>>> +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
>>> @@ -20,9 +20,6 @@
>>>  #include "intel_gtt.h"
>>>  #include "gen8_ppgtt.h"
>>>
>>> -static int
>>> -i915_get_ggtt_vma_pages(struct i915_vma *vma);
>>> -
>>>  static void i915_ggtt_color_adjust(const struct drm_mm_node *node,
>>>                                    unsigned long color,
>>>                                    u64 *start,
>>> @@ -875,21 +872,6 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, u64 size)
>>>         return 0;
>>>  }
>>>
>>> -int ggtt_set_pages(struct i915_vma *vma)
>>> -{
>>> -       int ret;
>>> -
>>> -       GEM_BUG_ON(vma->pages);
>>> -
>>> -       ret = i915_get_ggtt_vma_pages(vma);
>>> -       if (ret)
>>> -               return ret;
>>> -
>>> -       vma->page_sizes = vma->obj->mm.page_sizes;
>>> -
>>> -       return 0;
>>> -}
>>> -
>>>  static void gen6_gmch_remove(struct i915_address_space *vm)
>>>  {
>>>         struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
>>> @@ -950,8 +932,6 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
>>>
>>>         ggtt->vm.vma_ops.bind_vma    = ggtt_bind_vma;
>>>         ggtt->vm.vma_ops.unbind_vma  = ggtt_unbind_vma;
>>> -       ggtt->vm.vma_ops.set_pages   = ggtt_set_pages;
>>> -       ggtt->vm.vma_ops.clear_pages = clear_pages;
>>>
>>>         ggtt->vm.pte_encode = gen8_ggtt_pte_encode;
>>>
>>> @@ -1100,8 +1080,6 @@ static int gen6_gmch_probe(struct i915_ggtt *ggtt)
>>>
>>>         ggtt->vm.vma_ops.bind_vma    = ggtt_bind_vma;
>>>         ggtt->vm.vma_ops.unbind_vma  = ggtt_unbind_vma;
>>> -       ggtt->vm.vma_ops.set_pages   = ggtt_set_pages;
>>> -       ggtt->vm.vma_ops.clear_pages = clear_pages;
>>>
>>>         return ggtt_probe_common(ggtt, size);
>>>  }
>>> @@ -1145,8 +1123,6 @@ static int i915_gmch_probe(struct i915_ggtt *ggtt)
>>>
>>>         ggtt->vm.vma_ops.bind_vma    = ggtt_bind_vma;
>>>         ggtt->vm.vma_ops.unbind_vma  = ggtt_unbind_vma;
>>> -       ggtt->vm.vma_ops.set_pages   = ggtt_set_pages;
>>> -       ggtt->vm.vma_ops.clear_pages = clear_pages;
>>>
>>>         if (unlikely(ggtt->do_idle_maps))
>>>                 drm_notice(&i915->drm,
>>> @@ -1294,324 +1270,3 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
>>>
>>>         intel_ggtt_restore_fences(ggtt);
>>>  }
>>> -
>>> -static struct scatterlist *
>>> -rotate_pages(struct drm_i915_gem_object *obj, unsigned int offset,
>>> -            unsigned int width, unsigned int height,
>>> -            unsigned int src_stride, unsigned int dst_stride,
>>> -            struct sg_table *st, struct scatterlist *sg)
>>> -{
>>> -       unsigned int column, row;
>>> -       unsigned int src_idx;
>>> -
>>> -       for (column = 0; column < width; column++) {
>>> -               unsigned int left;
>>> -
>>> -               src_idx = src_stride * (height - 1) + column + offset;
>>> -               for (row = 0; row < height; row++) {
>>> -                       st->nents++;
>>> -                       /*
>>> -                        * We don't need the pages, but need to initialize
>>> -                        * the entries so the sg list can be happily traversed.
>>> -                        * The only thing we need are DMA addresses.
>>> -                        */
>>> -                       sg_set_page(sg, NULL, I915_GTT_PAGE_SIZE, 0);
>>> -                       sg_dma_address(sg) =
>>> -                               i915_gem_object_get_dma_address(obj, src_idx);
>>> -                       sg_dma_len(sg) = I915_GTT_PAGE_SIZE;
>>> -                       sg = sg_next(sg);
>>> -                       src_idx -= src_stride;
>>> -               }
>>> -
>>> -               left = (dst_stride - height) * I915_GTT_PAGE_SIZE;
>>> -
>>> -               if (!left)
>>> -                       continue;
>>> -
>>> -               st->nents++;
>>> -
>>> -               /*
>>> -                * The DE ignores the PTEs for the padding tiles, the sg entry
>>> -                * here is just a conenience to indicate how many padding PTEs
>>> -                * to insert at this spot.
>>> -                */
>>> -               sg_set_page(sg, NULL, left, 0);
>>> -               sg_dma_address(sg) = 0;
>>> -               sg_dma_len(sg) = left;
>>> -               sg = sg_next(sg);
>>> -       }
>>> -
>>> -       return sg;
>>> -}
>>> -
>>> -static noinline struct sg_table *
>>> -intel_rotate_pages(struct intel_rotation_info *rot_info,
>>> -                  struct drm_i915_gem_object *obj)
>>> -{
>>> -       unsigned int size = intel_rotation_info_size(rot_info);
>>> -       struct drm_i915_private *i915 = to_i915(obj->base.dev);
>>> -       struct sg_table *st;
>>> -       struct scatterlist *sg;
>>> -       int ret = -ENOMEM;
>>> -       int i;
>>> -
>>> -       /* Allocate target SG list. */
>>> -       st = kmalloc(sizeof(*st), GFP_KERNEL);
>>> -       if (!st)
>>> -               goto err_st_alloc;
>>> -
>>> -       ret = sg_alloc_table(st, size, GFP_KERNEL);
>>> -       if (ret)
>>> -               goto err_sg_alloc;
>>> -
>>> -       st->nents = 0;
>>> -       sg = st->sgl;
>>> -
>>> -       for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++)
>>> -               sg = rotate_pages(obj, rot_info->plane[i].offset,
>>> -                                 rot_info->plane[i].width, rot_info->plane[i].height,
>>> -                                 rot_info->plane[i].src_stride,
>>> -                                 rot_info->plane[i].dst_stride,
>>> -                                 st, sg);
>>> -
>>> -       return st;
>>> -
>>> -err_sg_alloc:
>>> -       kfree(st);
>>> -err_st_alloc:
>>> -
>>> -       drm_dbg(&i915->drm, "Failed to create rotated mapping for object size %zu! (%ux%u tiles, %u pages)\n",
>>> -               obj->base.size, rot_info->plane[0].width,
>>> -               rot_info->plane[0].height, size);
>>> -
>>> -       return ERR_PTR(ret);
>>> -}
>>> -
>>> -static struct scatterlist *
>>> -remap_pages(struct drm_i915_gem_object *obj,
>>> -           unsigned int offset, unsigned int alignment_pad,
>>> -           unsigned int width, unsigned int height,
>>> -           unsigned int src_stride, unsigned int dst_stride,
>>> -           struct sg_table *st, struct scatterlist *sg)
>>> -{
>>> -       unsigned int row;
>>> -
>>> -       if (alignment_pad) {
>>> -               st->nents++;
>>> -
>>> -               /*
>>> -                * The DE ignores the PTEs for the padding tiles, the sg entry
>>> -                * here is just a convenience to indicate how many padding PTEs
>>> -                * to insert at this spot.
>>> -                */
>>> -               sg_set_page(sg, NULL, alignment_pad * 4096, 0);
>>> -               sg_dma_address(sg) = 0;
>>> -               sg_dma_len(sg) = alignment_pad * 4096;
>>> -               sg = sg_next(sg);
>>> -       }
>>> -
>>> -       for (row = 0; row < height; row++) {
>>> -               unsigned int left = width * I915_GTT_PAGE_SIZE;
>>> -
>>> -               while (left) {
>>> -                       dma_addr_t addr;
>>> -                       unsigned int length;
>>> -
>>> -                       /*
>>> -                        * We don't need the pages, but need to initialize
>>> -                        * the entries so the sg list can be happily traversed.
>>> -                        * The only thing we need are DMA addresses.
>>> -                        */
>>> -
>>> -                       addr = i915_gem_object_get_dma_address_len(obj, offset, &length);
>>> -
>>> -                       length = min(left, length);
>>> -
>>> -                       st->nents++;
>>> -
>>> -                       sg_set_page(sg, NULL, length, 0);
>>> -                       sg_dma_address(sg) = addr;
>>> -                       sg_dma_len(sg) = length;
>>> -                       sg = sg_next(sg);
>>> -
>>> -                       offset += length / I915_GTT_PAGE_SIZE;
>>> -                       left -= length;
>>> -               }
>>> -
>>> -               offset += src_stride - width;
>>> -
>>> -               left = (dst_stride - width) * I915_GTT_PAGE_SIZE;
>>> -
>>> -               if (!left)
>>> -                       continue;
>>> -
>>> -               st->nents++;
>>> -
>>> -               /*
>>> -                * The DE ignores the PTEs for the padding tiles, the sg entry
>>> -                * here is just a conenience to indicate how many padding PTEs
>>> -                * to insert at this spot.
>>> -                */
>>> -               sg_set_page(sg, NULL, left, 0);
>>> -               sg_dma_address(sg) = 0;
>>> -               sg_dma_len(sg) = left;
>>> -               sg = sg_next(sg);
>>> -       }
>>> -
>>> -       return sg;
>>> -}
>>> -
>>> -static noinline struct sg_table *
>>> -intel_remap_pages(struct intel_remapped_info *rem_info,
>>> -                 struct drm_i915_gem_object *obj)
>>> -{
>>> -       unsigned int size = intel_remapped_info_size(rem_info);
>>> -       struct drm_i915_private *i915 = to_i915(obj->base.dev);
>>> -       struct sg_table *st;
>>> -       struct scatterlist *sg;
>>> -       unsigned int gtt_offset = 0;
>>> -       int ret = -ENOMEM;
>>> -       int i;
>>> -
>>> -       /* Allocate target SG list. */
>>> -       st = kmalloc(sizeof(*st), GFP_KERNEL);
>>> -       if (!st)
>>> -               goto err_st_alloc;
>>> -
>>> -       ret = sg_alloc_table(st, size, GFP_KERNEL);
>>> -       if (ret)
>>> -               goto err_sg_alloc;
>>> -
>>> -       st->nents = 0;
>>> -       sg = st->sgl;
>>> -
>>> -       for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
>>> -               unsigned int alignment_pad = 0;
>>> -
>>> -               if (rem_info->plane_alignment)
>>> -                       alignment_pad = ALIGN(gtt_offset, rem_info->plane_alignment) - gtt_offset;
>>> -
>>> -               sg = remap_pages(obj,
>>> -                                rem_info->plane[i].offset, alignment_pad,
>>> -                                rem_info->plane[i].width, rem_info->plane[i].height,
>>> -                                rem_info->plane[i].src_stride, rem_info->plane[i].dst_stride,
>>> -                                st, sg);
>>> -
>>> -               gtt_offset += alignment_pad +
>>> -                             rem_info->plane[i].dst_stride * rem_info->plane[i].height;
>>> -       }
>>> -
>>> -       i915_sg_trim(st);
>>> -
>>> -       return st;
>>> -
>>> -err_sg_alloc:
>>> -       kfree(st);
>>> -err_st_alloc:
>>> -
>>> -       drm_dbg(&i915->drm, "Failed to create remapped mapping for object size %zu! (%ux%u tiles, %u pages)\n",
>>> -               obj->base.size, rem_info->plane[0].width,
>>> -               rem_info->plane[0].height, size);
>>> -
>>> -       return ERR_PTR(ret);
>>> -}
>>> -
>>> -static noinline struct sg_table *
>>> -intel_partial_pages(const struct i915_ggtt_view *view,
>>> -                   struct drm_i915_gem_object *obj)
>>> -{
>>> -       struct sg_table *st;
>>> -       struct scatterlist *sg, *iter;
>>> -       unsigned int count = view->partial.size;
>>> -       unsigned int offset;
>>> -       int ret = -ENOMEM;
>>> -
>>> -       st = kmalloc(sizeof(*st), GFP_KERNEL);
>>> -       if (!st)
>>> -               goto err_st_alloc;
>>> -
>>> -       ret = sg_alloc_table(st, count, GFP_KERNEL);
>>> -       if (ret)
>>> -               goto err_sg_alloc;
>>> -
>>> -       iter = i915_gem_object_get_sg_dma(obj, view->partial.offset, &offset);
>>> -       GEM_BUG_ON(!iter);
>>> -
>>> -       sg = st->sgl;
>>> -       st->nents = 0;
>>> -       do {
>>> -               unsigned int len;
>>> -
>>> -               len = min(sg_dma_len(iter) - (offset << PAGE_SHIFT),
>>> -                         count << PAGE_SHIFT);
>>> -               sg_set_page(sg, NULL, len, 0);
>>> -               sg_dma_address(sg) =
>>> -                       sg_dma_address(iter) + (offset << PAGE_SHIFT);
>>> -               sg_dma_len(sg) = len;
>>> -
>>> -               st->nents++;
>>> -               count -= len >> PAGE_SHIFT;
>>> -               if (count == 0) {
>>> -                       sg_mark_end(sg);
>>> -                       i915_sg_trim(st); /* Drop any unused tail entries. */
>>> -
>>> -                       return st;
>>> -               }
>>> -
>>> -               sg = __sg_next(sg);
>>> -               iter = __sg_next(iter);
>>> -               offset = 0;
>>> -       } while (1);
>>> -
>>> -err_sg_alloc:
>>> -       kfree(st);
>>> -err_st_alloc:
>>> -       return ERR_PTR(ret);
>>> -}
>>> -
>>> -static int
>>> -i915_get_ggtt_vma_pages(struct i915_vma *vma)
>>> -{
>>> -       int ret;
>>> -
>>> -       /*
>>> -        * The vma->pages are only valid within the lifespan of the borrowed
>>> -        * obj->mm.pages. When the obj->mm.pages sg_table is regenerated, so
>>> -        * must be the vma->pages. A simple rule is that vma->pages must only
>>> -        * be accessed when the obj->mm.pages are pinned.
>>> -        */
>>> -       GEM_BUG_ON(!i915_gem_object_has_pinned_pages(vma->obj));
>>> -
>>> -       switch (vma->ggtt_view.type) {
>>> -       default:
>>> -               GEM_BUG_ON(vma->ggtt_view.type);
>>> -               fallthrough;
>>> -       case I915_GGTT_VIEW_NORMAL:
>>> -               vma->pages = vma->obj->mm.pages;
>>> -               return 0;
>>> -
>>> -       case I915_GGTT_VIEW_ROTATED:
>>> -               vma->pages =
>>> -                       intel_rotate_pages(&vma->ggtt_view.rotated, vma->obj);
>>> -               break;
>>> -
>>> -       case I915_GGTT_VIEW_REMAPPED:
>>> -               vma->pages =
>>> -                       intel_remap_pages(&vma->ggtt_view.remapped, vma->obj);
>>> -               break;
>>> -
>>> -       case I915_GGTT_VIEW_PARTIAL:
>>> -               vma->pages = intel_partial_pages(&vma->ggtt_view, vma->obj);
>>> -               break;
>>> -       }
>>> -
>>> -       ret = 0;
>>> -       if (IS_ERR(vma->pages)) {
>>> -               ret = PTR_ERR(vma->pages);
>>> -               vma->pages = NULL;
>>> -               drm_err(&vma->vm->i915->drm,
>>> -                       "Failed to get pages for VMA view type %u (%d)!\n",
>>> -                       vma->ggtt_view.type, ret);
>>> -       }
>>> -       return ret;
>>> -}
>>> diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c b/drivers/gpu/drm/i915/gt/intel_gtt.c
>>> index 67d14afa6623..12eed5fcb17a 100644
>>> --- a/drivers/gpu/drm/i915/gt/intel_gtt.c
>>> +++ b/drivers/gpu/drm/i915/gt/intel_gtt.c
>>> @@ -221,19 +221,6 @@ void i915_address_space_init(struct i915_address_space *vm, int subclass)
>>>         INIT_LIST_HEAD(&vm->bound_list);
>>>  }
>>>
>>> -void clear_pages(struct i915_vma *vma)
>>> -{
>>> -       GEM_BUG_ON(!vma->pages);
>>> -
>>> -       if (vma->pages != vma->obj->mm.pages) {
>>> -               sg_free_table(vma->pages);
>>> -               kfree(vma->pages);
>>> -       }
>>> -       vma->pages = NULL;
>>> -
>>> -       memset(&vma->page_sizes, 0, sizeof(vma->page_sizes));
>>> -}
>>> -
>>>  void *__px_vaddr(struct drm_i915_gem_object *p)
>>>  {
>>>         enum i915_map_type type;
>>> diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.h b/drivers/gpu/drm/i915/gt/intel_gtt.h
>>> index bc6750263359..306e7645fdc5 100644
>>> --- a/drivers/gpu/drm/i915/gt/intel_gtt.h
>>> +++ b/drivers/gpu/drm/i915/gt/intel_gtt.h
>>> @@ -206,9 +206,6 @@ struct i915_vma_ops {
>>>          */
>>>         void (*unbind_vma)(struct i915_address_space *vm,
>>>                            struct i915_vma *vma);
>>> -
>>> -       int (*set_pages)(struct i915_vma *vma);
>>> -       void (*clear_pages)(struct i915_vma *vma);
>>>  };
>>>
>>>  struct i915_address_space {
>>> @@ -594,10 +591,6 @@ release_pd_entry(struct i915_page_directory * const pd,
>>>                  const struct drm_i915_gem_object * const scratch);
>>>  void gen6_ggtt_invalidate(struct i915_ggtt *ggtt);
>>>
>>> -int ggtt_set_pages(struct i915_vma *vma);
>>> -int ppgtt_set_pages(struct i915_vma *vma);
>>> -void clear_pages(struct i915_vma *vma);
>>> -
>>>  void ppgtt_bind_vma(struct i915_address_space *vm,
>>>                     struct i915_vm_pt_stash *stash,
>>>                     struct i915_vma *vma,
>>> diff --git a/drivers/gpu/drm/i915/gt/intel_ppgtt.c b/drivers/gpu/drm/i915/gt/intel_ppgtt.c
>>> index 4396bfd630d8..083b3090c69c 100644
>>> --- a/drivers/gpu/drm/i915/gt/intel_ppgtt.c
>>> +++ b/drivers/gpu/drm/i915/gt/intel_ppgtt.c
>>> @@ -289,16 +289,6 @@ void i915_vm_free_pt_stash(struct i915_address_space *vm,
>>>         }
>>>  }
>>>
>>> -int ppgtt_set_pages(struct i915_vma *vma)
>>> -{
>>> -       GEM_BUG_ON(vma->pages);
>>> -
>>> -       vma->pages = vma->obj->mm.pages;
>>> -       vma->page_sizes = vma->obj->mm.page_sizes;
>>> -
>>> -       return 0;
>>> -}
>>> -
>>>  void ppgtt_init(struct i915_ppgtt *ppgtt, struct intel_gt *gt,
>>>                 unsigned long lmem_pt_obj_flags)
>>>  {
>>> @@ -315,6 +305,4 @@ void ppgtt_init(struct i915_ppgtt *ppgtt, struct intel_gt *gt,
>>>
>>>         ppgtt->vm.vma_ops.bind_vma    = ppgtt_bind_vma;
>>>         ppgtt->vm.vma_ops.unbind_vma  = ppgtt_unbind_vma;
>>> -       ppgtt->vm.vma_ops.set_pages   = ppgtt_set_pages;
>>> -       ppgtt->vm.vma_ops.clear_pages = clear_pages;
>>>  }
>>> diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
>>> index ac09b685678a..bacc8d68e495 100644
>>> --- a/drivers/gpu/drm/i915/i915_vma.c
>>> +++ b/drivers/gpu/drm/i915/i915_vma.c
>>> @@ -112,7 +112,6 @@ vma_create(struct drm_i915_gem_object *obj,
>>>                 return ERR_PTR(-ENOMEM);
>>>
>>>         kref_init(&vma->ref);
>>> -       mutex_init(&vma->pages_mutex);
>>>         vma->vm = i915_vm_get(vm);
>>>         vma->ops = &vm->vma_ops;
>>>         vma->obj = obj;
>>> @@ -789,10 +788,343 @@ static bool try_qad_pin(struct i915_vma *vma, unsigned int flags)
>>>         return pinned;
>>>  }
>>>
>>> -static int vma_get_pages(struct i915_vma *vma)
>>> +
>>> +
>>> +static struct scatterlist *
>>> +rotate_pages(struct drm_i915_gem_object *obj, unsigned int offset,
>>> +            unsigned int width, unsigned int height,
>>> +            unsigned int src_stride, unsigned int dst_stride,
>>> +            struct sg_table *st, struct scatterlist *sg)
>>>  {
>>> -       int err = 0;
>>> -       bool pinned_pages = true;
>>> +       unsigned int column, row;
>>> +       unsigned int src_idx;
>>> +
>>> +       for (column = 0; column < width; column++) {
>>> +               unsigned int left;
>>> +
>>> +               src_idx = src_stride * (height - 1) + column + offset;
>>> +               for (row = 0; row < height; row++) {
>>> +                       st->nents++;
>>> +                       /*
>>> +                        * We don't need the pages, but need to initialize
>>> +                        * the entries so the sg list can be happily traversed.
>>> +                        * The only thing we need are DMA addresses.
>>> +                        */
>>> +                       sg_set_page(sg, NULL, I915_GTT_PAGE_SIZE, 0);
>>> +                       sg_dma_address(sg) =
>>> +                               i915_gem_object_get_dma_address(obj, src_idx);
>>> +                       sg_dma_len(sg) = I915_GTT_PAGE_SIZE;
>>> +                       sg = sg_next(sg);
>>> +                       src_idx -= src_stride;
>>> +               }
>>> +
>>> +               left = (dst_stride - height) * I915_GTT_PAGE_SIZE;
>>> +
>>> +               if (!left)
>>> +                       continue;
>>> +
>>> +               st->nents++;
>>> +
>>> +               /*
>>> +                * The DE ignores the PTEs for the padding tiles, the sg entry
>>> +                * here is just a conenience to indicate how many padding PTEs
>>> +                * to insert at this spot.
>>> +                */
>>> +               sg_set_page(sg, NULL, left, 0);
>>> +               sg_dma_address(sg) = 0;
>>> +               sg_dma_len(sg) = left;
>>> +               sg = sg_next(sg);
>>> +       }
>>> +
>>> +       return sg;
>>> +}
>>> +
>>> +static noinline struct sg_table *
>>> +intel_rotate_pages(struct intel_rotation_info *rot_info,
>>> +                  struct drm_i915_gem_object *obj)
>>> +{
>>> +       unsigned int size = intel_rotation_info_size(rot_info);
>>> +       struct drm_i915_private *i915 = to_i915(obj->base.dev);
>>> +       struct sg_table *st;
>>> +       struct scatterlist *sg;
>>> +       int ret = -ENOMEM;
>>> +       int i;
>>> +
>>> +       /* Allocate target SG list. */
>>> +       st = kmalloc(sizeof(*st), GFP_KERNEL);
>>> +       if (!st)
>>> +               goto err_st_alloc;
>>> +
>>> +       ret = sg_alloc_table(st, size, GFP_KERNEL);
>>> +       if (ret)
>>> +               goto err_sg_alloc;
>>> +
>>> +       st->nents = 0;
>>> +       sg = st->sgl;
>>> +
>>> +       for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++)
>>> +               sg = rotate_pages(obj, rot_info->plane[i].offset,
>>> +                                 rot_info->plane[i].width, rot_info->plane[i].height,
>>> +                                 rot_info->plane[i].src_stride,
>>> +                                 rot_info->plane[i].dst_stride,
>>> +                                 st, sg);
>>> +
>>> +       return st;
>>> +
>>> +err_sg_alloc:
>>> +       kfree(st);
>>> +err_st_alloc:
>>> +
>>> +       drm_dbg(&i915->drm, "Failed to create rotated mapping for object size %zu! (%ux%u tiles, %u pages)\n",
>>> +               obj->base.size, rot_info->plane[0].width,
>>> +               rot_info->plane[0].height, size);
>>> +
>>> +       return ERR_PTR(ret);
>>> +}
>>> +
>>> +static struct scatterlist *
>>> +remap_pages(struct drm_i915_gem_object *obj,
>>> +           unsigned int offset, unsigned int alignment_pad,
>>> +           unsigned int width, unsigned int height,
>>> +           unsigned int src_stride, unsigned int dst_stride,
>>> +           struct sg_table *st, struct scatterlist *sg)
>>> +{
>>> +       unsigned int row;
>>> +
>>> +       if (alignment_pad) {
>>> +               st->nents++;
>>> +
>>> +               /*
>>> +                * The DE ignores the PTEs for the padding tiles, the sg entry
>>> +                * here is just a convenience to indicate how many padding PTEs
>>> +                * to insert at this spot.
>>> +                */
>>> +               sg_set_page(sg, NULL, alignment_pad * 4096, 0);
>>> +               sg_dma_address(sg) = 0;
>>> +               sg_dma_len(sg) = alignment_pad * 4096;
>>> +               sg = sg_next(sg);
>>> +       }
>>> +
>>> +       for (row = 0; row < height; row++) {
>>> +               unsigned int left = width * I915_GTT_PAGE_SIZE;
>>> +
>>> +               while (left) {
>>> +                       dma_addr_t addr;
>>> +                       unsigned int length;
>>> +
>>> +                       /*
>>> +                        * We don't need the pages, but need to initialize
>>> +                        * the entries so the sg list can be happily traversed.
>>> +                        * The only thing we need are DMA addresses.
>>> +                        */
>>> +
>>> +                       addr = i915_gem_object_get_dma_address_len(obj, offset, &length);
>>> +
>>> +                       length = min(left, length);
>>> +
>>> +                       st->nents++;
>>> +
>>> +                       sg_set_page(sg, NULL, length, 0);
>>> +                       sg_dma_address(sg) = addr;
>>> +                       sg_dma_len(sg) = length;
>>> +                       sg = sg_next(sg);
>>> +
>>> +                       offset += length / I915_GTT_PAGE_SIZE;
>>> +                       left -= length;
>>> +               }
>>> +
>>> +               offset += src_stride - width;
>>> +
>>> +               left = (dst_stride - width) * I915_GTT_PAGE_SIZE;
>>> +
>>> +               if (!left)
>>> +                       continue;
>>> +
>>> +               st->nents++;
>>> +
>>> +               /*
>>> +                * The DE ignores the PTEs for the padding tiles, the sg entry
>>> +                * here is just a conenience to indicate how many padding PTEs
>>> +                * to insert at this spot.
>>> +                */
>>> +               sg_set_page(sg, NULL, left, 0);
>>> +               sg_dma_address(sg) = 0;
>>> +               sg_dma_len(sg) = left;
>>> +               sg = sg_next(sg);
>>> +       }
>>> +
>>> +       return sg;
>>> +}
>>> +
>>> +static noinline struct sg_table *
>>> +intel_remap_pages(struct intel_remapped_info *rem_info,
>>> +                 struct drm_i915_gem_object *obj)
>>> +{
>>> +       unsigned int size = intel_remapped_info_size(rem_info);
>>> +       struct drm_i915_private *i915 = to_i915(obj->base.dev);
>>> +       struct sg_table *st;
>>> +       struct scatterlist *sg;
>>> +       unsigned int gtt_offset = 0;
>>> +       int ret = -ENOMEM;
>>> +       int i;
>>> +
>>> +       /* Allocate target SG list. */
>>> +       st = kmalloc(sizeof(*st), GFP_KERNEL);
>>> +       if (!st)
>>> +               goto err_st_alloc;
>>> +
>>> +       ret = sg_alloc_table(st, size, GFP_KERNEL);
>>> +       if (ret)
>>> +               goto err_sg_alloc;
>>> +
>>> +       st->nents = 0;
>>> +       sg = st->sgl;
>>> +
>>> +       for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
>>> +               unsigned int alignment_pad = 0;
>>> +
>>> +               if (rem_info->plane_alignment)
>>> +                       alignment_pad = ALIGN(gtt_offset, rem_info->plane_alignment) - gtt_offset;
>>> +
>>> +               sg = remap_pages(obj,
>>> +                                rem_info->plane[i].offset, alignment_pad,
>>> +                                rem_info->plane[i].width, rem_info->plane[i].height,
>>> +                                rem_info->plane[i].src_stride, rem_info->plane[i].dst_stride,
>>> +                                st, sg);
>>> +
>>> +               gtt_offset += alignment_pad +
>>> +                             rem_info->plane[i].dst_stride * rem_info->plane[i].height;
>>> +       }
>>> +
>>> +       i915_sg_trim(st);
>>> +
>>> +       return st;
>>> +
>>> +err_sg_alloc:
>>> +       kfree(st);
>>> +err_st_alloc:
>>> +
>>> +       drm_dbg(&i915->drm, "Failed to create remapped mapping for object size %zu! (%ux%u tiles, %u pages)\n",
>>> +               obj->base.size, rem_info->plane[0].width,
>>> +               rem_info->plane[0].height, size);
>>> +
>>> +       return ERR_PTR(ret);
>>> +}
>>> +
>>> +static noinline struct sg_table *
>>> +intel_partial_pages(const struct i915_ggtt_view *view,
>>> +                   struct drm_i915_gem_object *obj)
>>> +{
>>> +       struct sg_table *st;
>>> +       struct scatterlist *sg, *iter;
>>> +       unsigned int count = view->partial.size;
>>> +       unsigned int offset;
>>> +       int ret = -ENOMEM;
>>> +
>>> +       st = kmalloc(sizeof(*st), GFP_KERNEL);
>>> +       if (!st)
>>> +               goto err_st_alloc;
>>> +
>>> +       ret = sg_alloc_table(st, count, GFP_KERNEL);
>>> +       if (ret)
>>> +               goto err_sg_alloc;
>>> +
>>> +       iter = i915_gem_object_get_sg_dma(obj, view->partial.offset, &offset);
>>> +       GEM_BUG_ON(!iter);
>>> +
>>> +       sg = st->sgl;
>>> +       st->nents = 0;
>>> +       do {
>>> +               unsigned int len;
>>> +
>>> +               len = min(sg_dma_len(iter) - (offset << PAGE_SHIFT),
>>> +                         count << PAGE_SHIFT);
>>> +               sg_set_page(sg, NULL, len, 0);
>>> +               sg_dma_address(sg) =
>>> +                       sg_dma_address(iter) + (offset << PAGE_SHIFT);
>>> +               sg_dma_len(sg) = len;
>>> +
>>> +               st->nents++;
>>> +               count -= len >> PAGE_SHIFT;
>>> +               if (count == 0) {
>>> +                       sg_mark_end(sg);
>>> +                       i915_sg_trim(st); /* Drop any unused tail entries. */
>>> +
>>> +                       return st;
>>> +               }
>>> +
>>> +               sg = __sg_next(sg);
>>> +               iter = __sg_next(iter);
>>> +               offset = 0;
>>> +       } while (1);
>>> +
>>> +err_sg_alloc:
>>> +       kfree(st);
>>> +err_st_alloc:
>>> +       return ERR_PTR(ret);
>>> +}
>>> +
>>> +static int
>>> +__i915_vma_get_pages(struct i915_vma *vma)
>>> +{
>>> +       struct sg_table *pages;
>>> +       int ret;
>>> +
>>> +       /*
>>> +        * The vma->pages are only valid within the lifespan of the borrowed
>>> +        * obj->mm.pages. When the obj->mm.pages sg_table is regenerated, so
>>> +        * must be the vma->pages. A simple rule is that vma->pages must only
>>> +        * be accessed when the obj->mm.pages are pinned.
>>> +        */
>>> +       GEM_BUG_ON(!i915_gem_object_has_pinned_pages(vma->obj));
>>> +
>>> +       switch (vma->ggtt_view.type) {
>>> +       default:
>>> +               GEM_BUG_ON(vma->ggtt_view.type);
>>> +               fallthrough;
>>> +       case I915_GGTT_VIEW_NORMAL:
>>> +               pages = vma->obj->mm.pages;
>>> +               break;
>>> +
>>> +       case I915_GGTT_VIEW_ROTATED:
>>> +               pages =
>>> +                       intel_rotate_pages(&vma->ggtt_view.rotated, vma->obj);
>>> +               break;
>>> +
>>> +       case I915_GGTT_VIEW_REMAPPED:
>>> +               pages =
>>> +                       intel_remap_pages(&vma->ggtt_view.remapped, vma->obj);
>>> +               break;
>>> +
>>> +       case I915_GGTT_VIEW_PARTIAL:
>>> +               pages = intel_partial_pages(&vma->ggtt_view, vma->obj);
>>> +               break;
>>> +       }
>>> +
>>> +       ret = 0;
>>> +       /* gen6 ppgtt doesn't have backing pages, special-case it */
>>> +       if (IS_ERR(pages) && pages != ERR_PTR(-ENODEV)) {
>> Where does this -ENODEV come from? AFAIK for the gen6 thing mm.pages =
>> ZERO_SIZE_PTR. Also, just checking, I assume we always hit the
>> VIEW_NORMAL for that?
It was from when I was still converting the code. Looks like it can be removed now because setting pages to -ENODEV caused too many changes, and be unconditional IS_ERR.
>>> +               ret = PTR_ERR(pages);
>>> +               pages = NULL;
>>> +               drm_err(&vma->vm->i915->drm,
>>> +                       "Failed to get pages for VMA view type %u (%d)!\n",
>>> +                       vma->ggtt_view.type, ret);
>> Can we just return here?
Yeah, should be harmless. Out of paranoia I set pages to 0 below.
>>> +       }
>>> +
>>> +       pages = xchg(&vma->pages, pages);
>>> +
>>> +       /* did we race against a put_pages? */
>>> +       if (pages && pages != vma->obj->mm.pages) {
>>> +               sg_free_table(vma->pages);
>>> +               kfree(vma->pages);
>>> +       }
>> What is this race exactly, can we add some more details here please?
>> So we can more easily evaluate the lockless trickery here.
> Ok, the lockless stuff just gets removed by the end of the series.

Correct!

Will fix the ENODEV thing and send a new version.

~Maarten


^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 14/28] drm/i915: Take object lock in i915_ggtt_pin if ww is not set
  2021-10-21 17:39   ` Matthew Auld
@ 2021-11-29 12:46     ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-11-29 12:46 UTC (permalink / raw)
  To: Matthew Auld; +Cc: Intel Graphics Development, ML dri-devel

On 21-10-2021 19:39, Matthew Auld wrote:
> On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
> <maarten.lankhorst@linux.intel.com> wrote:
>> i915_vma_wait_for_bind needs the vma lock held, fix the caller.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/i915_vma.c | 40 +++++++++++++++++++++++----------
>>  1 file changed, 28 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
>> index bacc8d68e495..2877dcd62acb 100644
>> --- a/drivers/gpu/drm/i915/i915_vma.c
>> +++ b/drivers/gpu/drm/i915/i915_vma.c
>> @@ -1348,23 +1348,15 @@ static void flush_idle_contexts(struct intel_gt *gt)
>>         intel_gt_wait_for_idle(gt, MAX_SCHEDULE_TIMEOUT);
>>  }
>>
>> -int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
>> -                 u32 align, unsigned int flags)
>> +static int __i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
>> +                          u32 align, unsigned int flags)
>>  {
>>         struct i915_address_space *vm = vma->vm;
>>         int err;
>>
>> -       GEM_BUG_ON(!i915_vma_is_ggtt(vma));
>> -
>> -#ifdef CONFIG_LOCKDEP
>> -       WARN_ON(!ww && dma_resv_held(vma->obj->base.resv));
>> -#endif
>> -
>>         do {
>> -               if (ww)
>> -                       err = i915_vma_pin_ww(vma, ww, 0, align, flags | PIN_GLOBAL);
>> -               else
>> -                       err = i915_vma_pin(vma, 0, align, flags | PIN_GLOBAL);
>> +               err = i915_vma_pin_ww(vma, ww, 0, align, flags | PIN_GLOBAL);
>> +
>>                 if (err != -ENOSPC) {
>>                         if (!err) {
>>                                 err = i915_vma_wait_for_bind(vma);
>> @@ -1383,6 +1375,30 @@ int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
>>         } while (1);
>>  }
>>
>> +int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
>> +                 u32 align, unsigned int flags)
>> +{
>> +       struct i915_gem_ww_ctx _ww;
>> +       int err;
>> +
>> +       GEM_BUG_ON(!i915_vma_is_ggtt(vma));
>> +
>> +       if (ww)
>> +               return __i915_ggtt_pin(vma, ww, align, flags);
>> +
>> +#ifdef CONFIG_LOCKDEP
>> +       WARN_ON(dma_resv_held(vma->obj->base.resv));
> Hmm, so this can't trigger, say if shrinker grabs the lock, or some
> other concurrent user?

No, it checks internally in lockdep that the current task doesn't hold the lock. Others can lock just fine.

dma_resv_is_locked() would check if anyone locked it. :)

~Maarten


^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 15/28] drm/i915: Add lock for unbinding to i915_gem_object_ggtt_pin_ww
  2021-10-21 17:48   ` [Intel-gfx] " Matthew Auld
@ 2021-11-29 13:25     ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-11-29 13:25 UTC (permalink / raw)
  To: Matthew Auld; +Cc: Intel Graphics Development, ML dri-devel

On 21-10-2021 19:48, Matthew Auld wrote:
> On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
> <maarten.lankhorst@linux.intel.com> wrote:
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Needs a proper commit message.

What about this?


>> ---
>>  drivers/gpu/drm/i915/i915_gem.c | 9 ++++++++-
>>  1 file changed, 8 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
>> index 981e383d1a5d..6aa9e465b48e 100644
>> --- a/drivers/gpu/drm/i915/i915_gem.c
>> +++ b/drivers/gpu/drm/i915/i915_gem.c
>> @@ -931,7 +931,14 @@ i915_gem_object_ggtt_pin_ww(struct drm_i915_gem_object *obj,
>>                         goto new_vma;
>>                 }
>>
>> -               ret = i915_vma_unbind(vma);
>> +               ret = 0;
>> +               if (!ww)
>> +                       ret = i915_gem_object_lock_interruptible(obj, NULL);
>> +               if (!ret) {
>> +                       ret = i915_vma_unbind(vma);
>> +                       if (!ww)
>> +                               i915_gem_object_unlock(obj);
>> +               }
> There is also a wait_for_bind below. Do we need the lock for that also?

Hmm good find.

Not sure if required in this patch series. I have some patches on top that require the lock because of async binding / unbinding, that would need it for sure.

I will fix this function to use WARN_ON(!ww), and add ww handling to i915_gem_object_ggtt_pin(). That should fix all issues without special casing !ww.

~Maarten


^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [PATCH 28/28] drm/i915: Remove short-term pins from execbuf, v4.
  2021-10-25 15:02     ` [Intel-gfx] " Matthew Auld
@ 2021-11-29 13:44       ` Maarten Lankhorst
  -1 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-11-29 13:44 UTC (permalink / raw)
  To: Matthew Auld; +Cc: Intel Graphics Development, ML dri-devel

On 25-10-2021 17:02, Matthew Auld wrote:
> On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
> <maarten.lankhorst@linux.intel.com> wrote:
>> Add a flag PIN_VALIDATE, to indicate we don't need to pin and only
>> protected by the object lock.
>>
>> This removes the need to unpin, which is done by just releasing the
>> lock.
>>
>> eb_reserve is slightly reworked for readability, but the same steps
>> are still done:
>> - First pass pins with NONBLOCK.
>> - Second pass unbinds all objects first, then pins.
>> - Third pass is only called when not all objects are softpinned, and
>>   unbinds all objects, then calls i915_gem_evict_vm(), then pins.
>>
>> When evicting the entire vm in eb_reserve() we do temporarily pin objects
>> that are marked with EXEC_OBJECT_PINNED. This is because they are already
>> at their destination, and i915_gem_evict_vm() would otherwise unbind them.
>>
>> However, we reduce the visibility of those pins by limiting the pin
>> to our call to i915_gem_evict_vm() only, and pin with vm->mutex held,
>> instead of the entire duration of the execbuf.
>>
>> Not sure the latter matters, one can hope..
>> In theory we could kill the pinning by adding an extra flag to the vma
>> to temporarily prevent unbinding for gtt for i915_gem_evict_vm only, but
>> I think that might be overkill. We're still holding the object lock, and
>> we don't have blocking eviction yet. It's likely sufficient to simply
>> enforce EXEC_OBJECT_PINNED for all objects on >= gen12.
>>
>> Changes since v1:
>> - Split out eb_reserve() into separate functions for readability.
>> Changes since v2:
>> - Make batch buffer mappable on platforms where only GGTT is available,
>>   to prevent moving the batch buffer during relocations.
>> Changes since v3:
>> - Preserve current behavior for batch buffer, instead be cautious when
>>   calling i915_gem_object_ggtt_pin_ww, and re-use the current batch vma
>>   if it's inside ggtt and map-and-fenceable.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 252 ++++++++++--------
>>  drivers/gpu/drm/i915/i915_gem_gtt.h           |   1 +
>>  drivers/gpu/drm/i915/i915_vma.c               |  24 +-
>>  3 files changed, 161 insertions(+), 116 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> index bbf2a10738f7..19f91143cfcf 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> @@ -439,7 +439,7 @@ eb_pin_vma(struct i915_execbuffer *eb,
>>         else
>>                 pin_flags = entry->offset & PIN_OFFSET_MASK;
>>
>> -       pin_flags |= PIN_USER | PIN_NOEVICT | PIN_OFFSET_FIXED;
>> +       pin_flags |= PIN_USER | PIN_NOEVICT | PIN_OFFSET_FIXED | PIN_VALIDATE;
>>         if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_GTT))
>>                 pin_flags |= PIN_GLOBAL;
>>
>> @@ -457,17 +457,15 @@ eb_pin_vma(struct i915_execbuffer *eb,
>>                                              entry->pad_to_size,
>>                                              entry->alignment,
>>                                              eb_pin_flags(entry, ev->flags) |
>> -                                            PIN_USER | PIN_NOEVICT);
>> +                                            PIN_USER | PIN_NOEVICT | PIN_VALIDATE);
>>                 if (unlikely(err))
>>                         return err;
>>         }
>>
>>         if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_FENCE)) {
>>                 err = i915_vma_pin_fence(vma);
>> -               if (unlikely(err)) {
>> -                       i915_vma_unpin(vma);
>> +               if (unlikely(err))
>>                         return err;
>> -               }
>>
>>                 if (vma->fence)
>>                         ev->flags |= __EXEC_OBJECT_HAS_FENCE;
>> @@ -483,13 +481,9 @@ eb_pin_vma(struct i915_execbuffer *eb,
>>  static inline void
>>  eb_unreserve_vma(struct eb_vma *ev)
>>  {
>> -       if (!(ev->flags & __EXEC_OBJECT_HAS_PIN))
>> -               return;
>> -
>>         if (unlikely(ev->flags & __EXEC_OBJECT_HAS_FENCE))
>>                 __i915_vma_unpin_fence(ev->vma);
>>
>> -       __i915_vma_unpin(ev->vma);
>>         ev->flags &= ~__EXEC_OBJECT_RESERVED;
>>  }
>>
>> @@ -682,10 +676,8 @@ static int eb_reserve_vma(struct i915_execbuffer *eb,
>>
>>         if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_FENCE)) {
>>                 err = i915_vma_pin_fence(vma);
>> -               if (unlikely(err)) {
>> -                       i915_vma_unpin(vma);
>> +               if (unlikely(err))
>>                         return err;
>> -               }
>>
>>                 if (vma->fence)
>>                         ev->flags |= __EXEC_OBJECT_HAS_FENCE;
>> @@ -697,85 +689,129 @@ static int eb_reserve_vma(struct i915_execbuffer *eb,
>>         return 0;
>>  }
>>
>> -static int eb_reserve(struct i915_execbuffer *eb)
>> +static int eb_evict_vm(struct i915_execbuffer *eb)
>> +{
>> +       const unsigned int count = eb->buffer_count;
>> +       unsigned int i;
>> +       int err;
>> +
>> +       err = mutex_lock_interruptible(&eb->context->vm->mutex);
>> +       if (err)
>> +               return err;
>> +
>> +       /* pin to protect against i915_gem_evict_vm evicting below */
>> +       for (i = 0; i < count; i++) {
>> +               struct eb_vma *ev = &eb->vma[i];
>> +
>> +               if (ev->flags & __EXEC_OBJECT_HAS_PIN)
>> +                       __i915_vma_pin(ev->vma);
>> +       }
>> +
>> +       /* Too fragmented, unbind everything and retry */
>> +       err = i915_gem_evict_vm(eb->context->vm, &eb->ww);
>> +
>> +       /* unpin objects.. */
>> +       for (i = 0; i < count; i++) {
>> +               struct eb_vma *ev = &eb->vma[i];
>> +
>> +               if (ev->flags & __EXEC_OBJECT_HAS_PIN)
>> +                       i915_vma_unpin(ev->vma);
>> +       }
>> +
>> +       mutex_unlock(&eb->context->vm->mutex);
>> +
>> +       return err;
>> +}
>> +
>> +static bool eb_unbind(struct i915_execbuffer *eb)
>>  {
>>         const unsigned int count = eb->buffer_count;
>> -       unsigned int pin_flags = PIN_USER | PIN_NONBLOCK;
>> +       unsigned int i;
>>         struct list_head last;
>> +       bool unpinned = false;
>> +
>> +       /* Resort *all* the objects into priority order */
>> +       INIT_LIST_HEAD(&eb->unbound);
>> +       INIT_LIST_HEAD(&last);
>> +
>> +       for (i = 0; i < count; i++) {
>> +               struct eb_vma *ev = &eb->vma[i];
>> +               unsigned int flags = ev->flags;
>> +
>> +               if (flags & EXEC_OBJECT_PINNED &&
>> +                   flags & __EXEC_OBJECT_HAS_PIN)
>> +                       continue;
>> +
>> +               unpinned = true;
>> +               eb_unreserve_vma(ev);
>> +
>> +               if (flags & EXEC_OBJECT_PINNED)
>> +                       /* Pinned must have their slot */
>> +                       list_add(&ev->bind_link, &eb->unbound);
>> +               else if (flags & __EXEC_OBJECT_NEEDS_MAP)
>> +                       /* Map require the lowest 256MiB (aperture) */
>> +                       list_add_tail(&ev->bind_link, &eb->unbound);
>> +               else if (!(flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS))
>> +                       /* Prioritise 4GiB region for restricted bo */
>> +                       list_add(&ev->bind_link, &last);
>> +               else
>> +                       list_add_tail(&ev->bind_link, &last);
>> +       }
>> +
>> +       list_splice_tail(&last, &eb->unbound);
>> +       return unpinned;
>> +}
>> +
>> +static int eb_reserve(struct i915_execbuffer *eb)
>> +{
>>         struct eb_vma *ev;
>> -       unsigned int i, pass;
>> +       unsigned int pass;
>>         int err = 0;
>> +       bool unpinned;
>>
>>         /*
>>          * Attempt to pin all of the buffers into the GTT.
>> -        * This is done in 3 phases:
>> +        * This is done in 2 phases:
>>          *
>> -        * 1a. Unbind all objects that do not match the GTT constraints for
>> -        *     the execbuffer (fenceable, mappable, alignment etc).
>> -        * 1b. Increment pin count for already bound objects.
>> -        * 2.  Bind new objects.
>> -        * 3.  Decrement pin count.
>> +        * 1. Unbind all objects that do not match the GTT constraints for
>> +        *    the execbuffer (fenceable, mappable, alignment etc).
>> +        * 2. Bind new objects.
>>          *
>>          * This avoid unnecessary unbinding of later objects in order to make
>>          * room for the earlier objects *unless* we need to defragment.
>> +        *
>> +        * Defragmenting is skipped if all objects are pinned at a fixed location.
>>          */
>> -       pass = 0;
>> -       do {
>> -               list_for_each_entry(ev, &eb->unbound, bind_link) {
>> -                       err = eb_reserve_vma(eb, ev, pin_flags);
>> -                       if (err)
>> -                               break;
>> -               }
>> -               if (err != -ENOSPC)
>> -                       return err;
>> +       for (pass = 0; pass <= 2; pass++) {
>> +               int pin_flags = PIN_USER | PIN_VALIDATE;
>>
>> -               /* Resort *all* the objects into priority order */
>> -               INIT_LIST_HEAD(&eb->unbound);
>> -               INIT_LIST_HEAD(&last);
>> -               for (i = 0; i < count; i++) {
>> -                       unsigned int flags;
>> +               if (pass == 0)
>> +                       pin_flags |= PIN_NONBLOCK;
>>
>> -                       ev = &eb->vma[i];
>> -                       flags = ev->flags;
>> -                       if (flags & EXEC_OBJECT_PINNED &&
>> -                           flags & __EXEC_OBJECT_HAS_PIN)
>> -                               continue;
>> +               if (pass >= 1)
>> +                       unpinned = eb_unbind(eb);
>>
>> -                       eb_unreserve_vma(ev);
>> -
>> -                       if (flags & EXEC_OBJECT_PINNED)
>> -                               /* Pinned must have their slot */
>> -                               list_add(&ev->bind_link, &eb->unbound);
>> -                       else if (flags & __EXEC_OBJECT_NEEDS_MAP)
>> -                               /* Map require the lowest 256MiB (aperture) */
>> -                               list_add_tail(&ev->bind_link, &eb->unbound);
>> -                       else if (!(flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS))
>> -                               /* Prioritise 4GiB region for restricted bo */
>> -                               list_add(&ev->bind_link, &last);
>> -                       else
>> -                               list_add_tail(&ev->bind_link, &last);
>> -               }
>> -               list_splice_tail(&last, &eb->unbound);
>> -
>> -               switch (pass++) {
>> -               case 0:
>> -                       break;
>> +               if (pass == 2) {
>> +                       /* No point in defragmenting gtt if all is pinned */
>> +                       if (!unpinned)
>> +                               return -ENOSPC;
> Can this ever happen? If everything is already pinned where it's meant
> to be, then how did we get here?
Hmm no, in previous versions it could, but it looks like I removed that in a refactor. Seems like dead code.
>
>> -               case 1:
>> -                       /* Too fragmented, unbind everything and retry */
>> -                       mutex_lock(&eb->context->vm->mutex);
>> -                       err = i915_gem_evict_vm(eb->context->vm, &eb->ww);
>> -                       mutex_unlock(&eb->context->vm->mutex);
>> +                       err = eb_evict_vm(eb);
>>                         if (err)
>>                                 return err;
>> -                       break;
>> +               }
>>
>> -               default:
>> -                       return -ENOSPC;
>> +               list_for_each_entry(ev, &eb->unbound, bind_link) {
>> +                       err = eb_reserve_vma(eb, ev, pin_flags);
>> +                       if (err)
>> +                               break;
>>                 }
>>
>> -               pin_flags = PIN_USER;
>> -       } while (1);
>> +               if (err != -ENOSPC)
>> +                       break;
>> +       }
>> +
>> +       return err;
>>  }
>>
>>  static int eb_select_context(struct i915_execbuffer *eb)
>> @@ -1184,10 +1220,11 @@ static void *reloc_kmap(struct drm_i915_gem_object *obj,
>>         return vaddr;
>>  }
>>
>> -static void *reloc_iomap(struct drm_i915_gem_object *obj,
>> +static void *reloc_iomap(struct i915_vma *batch,
>>                          struct i915_execbuffer *eb,
>>                          unsigned long page)
>>  {
>> +       struct drm_i915_gem_object *obj = batch->obj;
>>         struct reloc_cache *cache = &eb->reloc_cache;
>>         struct i915_ggtt *ggtt = cache_to_ggtt(cache);
>>         unsigned long offset;
>> @@ -1197,7 +1234,7 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
>>                 intel_gt_flush_ggtt_writes(ggtt->vm.gt);
>>                 io_mapping_unmap_atomic((void __force __iomem *) unmask_page(cache->vaddr));
>>         } else {
>> -               struct i915_vma *vma;
>> +               struct i915_vma *vma = ERR_PTR(-ENODEV);
>>                 int err;
>>
>>                 if (i915_gem_object_is_tiled(obj))
>> @@ -1210,10 +1247,23 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
>>                 if (err)
>>                         return ERR_PTR(err);
>>
>> -               vma = i915_gem_object_ggtt_pin_ww(obj, &eb->ww, NULL, 0, 0,
>> -                                                 PIN_MAPPABLE |
>> -                                                 PIN_NONBLOCK /* NOWARN */ |
>> -                                                 PIN_NOEVICT);
>> +               /*
>> +                * i915_gem_object_ggtt_pin_ww may attempt to remove the batch
>> +                * VMA from the object list because we no longer pin.
>> +                *
>> +                * Only attempt to pin the batch buffer to ggtt if the current batch
>> +                * is not inside ggtt, or the batch buffer is not misplaced.
>> +                */
>> +               if (!i915_is_ggtt(batch->vm)) {
>> +                       vma = i915_gem_object_ggtt_pin_ww(obj, &eb->ww, NULL, 0, 0,
>> +                                                         PIN_MAPPABLE |
>> +                                                         PIN_NONBLOCK /* NOWARN */ |
>> +                                                         PIN_NOEVICT);
>> +               } else if (i915_vma_is_map_and_fenceable(batch)) {
>> +                       __i915_vma_pin(batch);
>> +                       vma = batch;
>> +               }
>> +
>>                 if (vma == ERR_PTR(-EDEADLK))
>>                         return vma;
>>
>> @@ -1251,7 +1301,7 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
>>         return vaddr;
>>  }
>>
>> -static void *reloc_vaddr(struct drm_i915_gem_object *obj,
>> +static void *reloc_vaddr(struct i915_vma *vma,
>>                          struct i915_execbuffer *eb,
>>                          unsigned long page)
>>  {
>> @@ -1263,9 +1313,9 @@ static void *reloc_vaddr(struct drm_i915_gem_object *obj,
>>         } else {
>>                 vaddr = NULL;
>>                 if ((cache->vaddr & KMAP) == 0)
>> -                       vaddr = reloc_iomap(obj, eb, page);
>> +                       vaddr = reloc_iomap(vma, eb, page);
>>                 if (!vaddr)
>> -                       vaddr = reloc_kmap(obj, cache, page);
>> +                       vaddr = reloc_kmap(vma->obj, cache, page);
>>         }
>>
>>         return vaddr;
>> @@ -1306,7 +1356,7 @@ relocate_entry(struct i915_vma *vma,
>>         void *vaddr;
>>
>>  repeat:
>> -       vaddr = reloc_vaddr(vma->obj, eb,
>> +       vaddr = reloc_vaddr(vma, eb,
>>                             offset >> PAGE_SHIFT);
>>         if (IS_ERR(vaddr))
>>                 return PTR_ERR(vaddr);
>> @@ -2074,7 +2124,7 @@ shadow_batch_pin(struct i915_execbuffer *eb,
>>         if (IS_ERR(vma))
>>                 return vma;
>>
>> -       err = i915_vma_pin_ww(vma, &eb->ww, 0, 0, flags);
>> +       err = i915_vma_pin_ww(vma, &eb->ww, 0, 0, flags | PIN_VALIDATE);
>>         if (err)
>>                 return ERR_PTR(err);
>>
>> @@ -2088,7 +2138,7 @@ static struct i915_vma *eb_dispatch_secure(struct i915_execbuffer *eb, struct i9
>>          * batch" bit. Hence we need to pin secure batches into the global gtt.
>>          * hsw should have this fixed, but bdw mucks it up again. */
>>         if (eb->batch_flags & I915_DISPATCH_SECURE)
>> -               return i915_gem_object_ggtt_pin_ww(vma->obj, &eb->ww, NULL, 0, 0, 0);
>> +               return i915_gem_object_ggtt_pin_ww(vma->obj, &eb->ww, NULL, 0, 0, PIN_VALIDATE);
>>
>>         return NULL;
>>  }
>> @@ -2139,13 +2189,12 @@ static int eb_parse(struct i915_execbuffer *eb)
>>
>>         err = i915_gem_object_lock(pool->obj, &eb->ww);
>>         if (err)
>> -               goto err;
>> +               return err;
>>
>>         shadow = shadow_batch_pin(eb, pool->obj, eb->context->vm, PIN_USER);
>> -       if (IS_ERR(shadow)) {
>> -               err = PTR_ERR(shadow);
>> -               goto err;
>> -       }
>> +       if (IS_ERR(shadow))
>> +               return PTR_ERR(shadow);
>> +
>>         intel_gt_buffer_pool_mark_used(pool);
>>         i915_gem_object_set_readonly(shadow->obj);
>>         shadow->private = pool;
>> @@ -2157,25 +2206,21 @@ static int eb_parse(struct i915_execbuffer *eb)
>>                 shadow = shadow_batch_pin(eb, pool->obj,
>>                                           &eb->gt->ggtt->vm,
>>                                           PIN_GLOBAL);
>> -               if (IS_ERR(shadow)) {
>> -                       err = PTR_ERR(shadow);
>> -                       shadow = trampoline;
>> -                       goto err_shadow;
>> -               }
>> +               if (IS_ERR(shadow))
>> +                       return PTR_ERR(shadow);
>> +
>>                 shadow->private = pool;
>>
>>                 eb->batch_flags |= I915_DISPATCH_SECURE;
>>         }
>>
>>         batch = eb_dispatch_secure(eb, shadow);
>> -       if (IS_ERR(batch)) {
>> -               err = PTR_ERR(batch);
>> -               goto err_trampoline;
>> -       }
>> +       if (IS_ERR(batch))
>> +               return PTR_ERR(batch);
>>
>>         err = dma_resv_reserve_shared(shadow->obj->base.resv, 1);
>>         if (err)
>> -               goto err_trampoline;
>> +               return err;
>>
>>         err = intel_engine_cmd_parser(eb->context->engine,
>>                                       eb->batches[0]->vma,
>> @@ -2183,7 +2228,7 @@ static int eb_parse(struct i915_execbuffer *eb)
>>                                       eb->batch_len[0],
>>                                       shadow, trampoline);
>>         if (err)
>> -               goto err_unpin_batch;
>> +               return err;
>>
>>         eb->batches[0] = &eb->vma[eb->buffer_count++];
>>         eb->batches[0]->vma = i915_vma_get(shadow);
>> @@ -2202,17 +2247,6 @@ static int eb_parse(struct i915_execbuffer *eb)
>>                 eb->batches[0]->vma = i915_vma_get(batch);
>>         }
>>         return 0;
>> -
>> -err_unpin_batch:
>> -       if (batch)
>> -               i915_vma_unpin(batch);
>> -err_trampoline:
>> -       if (trampoline)
>> -               i915_vma_unpin(trampoline);
>> -err_shadow:
>> -       i915_vma_unpin(shadow);
>> -err:
>> -       return err;
>>  }
>>
>>  static int eb_request_submit(struct i915_execbuffer *eb,
>> @@ -3337,8 +3371,6 @@ i915_gem_do_execbuffer(struct drm_device *dev,
>>
>>  err_vma:
>>         eb_release_vmas(&eb, true);
>> -       if (eb.trampoline)
>> -               i915_vma_unpin(eb.trampoline);
>>         WARN_ON(err == -EDEADLK);
>>         i915_gem_ww_ctx_fini(&eb.ww);
>>
>> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
>> index e4938aba3fe9..8c2f57eb5dda 100644
>> --- a/drivers/gpu/drm/i915/i915_gem_gtt.h
>> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
>> @@ -44,6 +44,7 @@ int i915_gem_gtt_insert(struct i915_address_space *vm,
>>  #define PIN_HIGH               BIT_ULL(5)
>>  #define PIN_OFFSET_BIAS                BIT_ULL(6)
>>  #define PIN_OFFSET_FIXED       BIT_ULL(7)
>> +#define PIN_VALIDATE           BIT_ULL(8) /* validate placement only, no need to call unpin() */
>>
>>  #define PIN_GLOBAL             BIT_ULL(10) /* I915_VMA_GLOBAL_BIND */
>>  #define PIN_USER               BIT_ULL(11) /* I915_VMA_LOCAL_BIND */
>> diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
>> index 65168db534f0..0706731b211d 100644
>> --- a/drivers/gpu/drm/i915/i915_vma.c
>> +++ b/drivers/gpu/drm/i915/i915_vma.c
>> @@ -751,6 +751,15 @@ static bool try_qad_pin(struct i915_vma *vma, unsigned int flags)
>>         unsigned int bound;
>>
>>         bound = atomic_read(&vma->flags);
>> +
>> +       if (flags & PIN_VALIDATE) {
>> +               flags &= I915_VMA_BIND_MASK;
>> +
>> +               return (flags & bound) == flags;
>> +       }
>> +
>> +       /* with the lock mandatory for unbind, we don't race here */
>> +       flags &= I915_VMA_BIND_MASK;
>>         do {
>>                 if (unlikely(flags & ~bound))
>>                         return false;
>> @@ -1176,7 +1185,7 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
>>         GEM_BUG_ON(!(flags & (PIN_USER | PIN_GLOBAL)));
>>
>>         /* First try and grab the pin without rebinding the vma */
>> -       if (try_qad_pin(vma, flags & I915_VMA_BIND_MASK))
>> +       if (try_qad_pin(vma, flags))
>>                 return 0;
>>
>>         err = i915_vma_get_pages(vma);
>> @@ -1255,7 +1264,8 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
>>         }
>>
>>         if (unlikely(!(flags & ~bound & I915_VMA_BIND_MASK))) {
>> -               __i915_vma_pin(vma);
>> +               if (!(flags & PIN_VALIDATE))
>> +                       __i915_vma_pin(vma);
>>                 goto err_unlock;
>>         }
>>
>> @@ -1284,8 +1294,10 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
>>         atomic_add(I915_VMA_PAGES_ACTIVE, &vma->pages_count);
>>         list_move_tail(&vma->vm_link, &vma->vm->bound_list);
>>
>> -       __i915_vma_pin(vma);
>> -       GEM_BUG_ON(!i915_vma_is_pinned(vma));
>> +       if (!(flags & PIN_VALIDATE)) {
>> +               __i915_vma_pin(vma);
>> +               GEM_BUG_ON(!i915_vma_is_pinned(vma));
>> +       }
>>         GEM_BUG_ON(!i915_vma_is_bound(vma, flags));
>>         GEM_BUG_ON(i915_vma_misplaced(vma, size, alignment, flags));
>>
>> @@ -1538,8 +1550,6 @@ static int __i915_vma_move_to_active(struct i915_vma *vma, struct i915_request *
>>  {
>>         int err;
>>
>> -       GEM_BUG_ON(!i915_vma_is_pinned(vma));
>> -
>>         /* Wait for the vma to be bound before we start! */
>>         err = __i915_request_await_bind(rq, vma);
>>         if (err)
>> @@ -1558,6 +1568,8 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
>>
>>         assert_object_held(obj);
>>
>> +       GEM_BUG_ON(!vma->pages);
>> +
>>         err = __i915_vma_move_to_active(vma, rq);
>>         if (unlikely(err))
>>                 return err;
>> --
>> 2.33.0
>>


^ permalink raw reply	[flat|nested] 114+ messages in thread

* Re: [Intel-gfx] [PATCH 28/28] drm/i915: Remove short-term pins from execbuf, v4.
@ 2021-11-29 13:44       ` Maarten Lankhorst
  0 siblings, 0 replies; 114+ messages in thread
From: Maarten Lankhorst @ 2021-11-29 13:44 UTC (permalink / raw)
  To: Matthew Auld; +Cc: Intel Graphics Development, ML dri-devel

On 25-10-2021 17:02, Matthew Auld wrote:
> On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
> <maarten.lankhorst@linux.intel.com> wrote:
>> Add a flag PIN_VALIDATE, to indicate we don't need to pin and only
>> protected by the object lock.
>>
>> This removes the need to unpin, which is done by just releasing the
>> lock.
>>
>> eb_reserve is slightly reworked for readability, but the same steps
>> are still done:
>> - First pass pins with NONBLOCK.
>> - Second pass unbinds all objects first, then pins.
>> - Third pass is only called when not all objects are softpinned, and
>>   unbinds all objects, then calls i915_gem_evict_vm(), then pins.
>>
>> When evicting the entire vm in eb_reserve() we do temporarily pin objects
>> that are marked with EXEC_OBJECT_PINNED. This is because they are already
>> at their destination, and i915_gem_evict_vm() would otherwise unbind them.
>>
>> However, we reduce the visibility of those pins by limiting the pin
>> to our call to i915_gem_evict_vm() only, and pin with vm->mutex held,
>> instead of the entire duration of the execbuf.
>>
>> Not sure the latter matters, one can hope..
>> In theory we could kill the pinning by adding an extra flag to the vma
>> to temporarily prevent unbinding for gtt for i915_gem_evict_vm only, but
>> I think that might be overkill. We're still holding the object lock, and
>> we don't have blocking eviction yet. It's likely sufficient to simply
>> enforce EXEC_OBJECT_PINNED for all objects on >= gen12.
>>
>> Changes since v1:
>> - Split out eb_reserve() into separate functions for readability.
>> Changes since v2:
>> - Make batch buffer mappable on platforms where only GGTT is available,
>>   to prevent moving the batch buffer during relocations.
>> Changes since v3:
>> - Preserve current behavior for batch buffer, instead be cautious when
>>   calling i915_gem_object_ggtt_pin_ww, and re-use the current batch vma
>>   if it's inside ggtt and map-and-fenceable.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 252 ++++++++++--------
>>  drivers/gpu/drm/i915/i915_gem_gtt.h           |   1 +
>>  drivers/gpu/drm/i915/i915_vma.c               |  24 +-
>>  3 files changed, 161 insertions(+), 116 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> index bbf2a10738f7..19f91143cfcf 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> @@ -439,7 +439,7 @@ eb_pin_vma(struct i915_execbuffer *eb,
>>         else
>>                 pin_flags = entry->offset & PIN_OFFSET_MASK;
>>
>> -       pin_flags |= PIN_USER | PIN_NOEVICT | PIN_OFFSET_FIXED;
>> +       pin_flags |= PIN_USER | PIN_NOEVICT | PIN_OFFSET_FIXED | PIN_VALIDATE;
>>         if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_GTT))
>>                 pin_flags |= PIN_GLOBAL;
>>
>> @@ -457,17 +457,15 @@ eb_pin_vma(struct i915_execbuffer *eb,
>>                                              entry->pad_to_size,
>>                                              entry->alignment,
>>                                              eb_pin_flags(entry, ev->flags) |
>> -                                            PIN_USER | PIN_NOEVICT);
>> +                                            PIN_USER | PIN_NOEVICT | PIN_VALIDATE);
>>                 if (unlikely(err))
>>                         return err;
>>         }
>>
>>         if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_FENCE)) {
>>                 err = i915_vma_pin_fence(vma);
>> -               if (unlikely(err)) {
>> -                       i915_vma_unpin(vma);
>> +               if (unlikely(err))
>>                         return err;
>> -               }
>>
>>                 if (vma->fence)
>>                         ev->flags |= __EXEC_OBJECT_HAS_FENCE;
>> @@ -483,13 +481,9 @@ eb_pin_vma(struct i915_execbuffer *eb,
>>  static inline void
>>  eb_unreserve_vma(struct eb_vma *ev)
>>  {
>> -       if (!(ev->flags & __EXEC_OBJECT_HAS_PIN))
>> -               return;
>> -
>>         if (unlikely(ev->flags & __EXEC_OBJECT_HAS_FENCE))
>>                 __i915_vma_unpin_fence(ev->vma);
>>
>> -       __i915_vma_unpin(ev->vma);
>>         ev->flags &= ~__EXEC_OBJECT_RESERVED;
>>  }
>>
>> @@ -682,10 +676,8 @@ static int eb_reserve_vma(struct i915_execbuffer *eb,
>>
>>         if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_FENCE)) {
>>                 err = i915_vma_pin_fence(vma);
>> -               if (unlikely(err)) {
>> -                       i915_vma_unpin(vma);
>> +               if (unlikely(err))
>>                         return err;
>> -               }
>>
>>                 if (vma->fence)
>>                         ev->flags |= __EXEC_OBJECT_HAS_FENCE;
>> @@ -697,85 +689,129 @@ static int eb_reserve_vma(struct i915_execbuffer *eb,
>>         return 0;
>>  }
>>
>> -static int eb_reserve(struct i915_execbuffer *eb)
>> +static int eb_evict_vm(struct i915_execbuffer *eb)
>> +{
>> +       const unsigned int count = eb->buffer_count;
>> +       unsigned int i;
>> +       int err;
>> +
>> +       err = mutex_lock_interruptible(&eb->context->vm->mutex);
>> +       if (err)
>> +               return err;
>> +
>> +       /* pin to protect against i915_gem_evict_vm evicting below */
>> +       for (i = 0; i < count; i++) {
>> +               struct eb_vma *ev = &eb->vma[i];
>> +
>> +               if (ev->flags & __EXEC_OBJECT_HAS_PIN)
>> +                       __i915_vma_pin(ev->vma);
>> +       }
>> +
>> +       /* Too fragmented, unbind everything and retry */
>> +       err = i915_gem_evict_vm(eb->context->vm, &eb->ww);
>> +
>> +       /* unpin objects.. */
>> +       for (i = 0; i < count; i++) {
>> +               struct eb_vma *ev = &eb->vma[i];
>> +
>> +               if (ev->flags & __EXEC_OBJECT_HAS_PIN)
>> +                       i915_vma_unpin(ev->vma);
>> +       }
>> +
>> +       mutex_unlock(&eb->context->vm->mutex);
>> +
>> +       return err;
>> +}
>> +
>> +static bool eb_unbind(struct i915_execbuffer *eb)
>>  {
>>         const unsigned int count = eb->buffer_count;
>> -       unsigned int pin_flags = PIN_USER | PIN_NONBLOCK;
>> +       unsigned int i;
>>         struct list_head last;
>> +       bool unpinned = false;
>> +
>> +       /* Resort *all* the objects into priority order */
>> +       INIT_LIST_HEAD(&eb->unbound);
>> +       INIT_LIST_HEAD(&last);
>> +
>> +       for (i = 0; i < count; i++) {
>> +               struct eb_vma *ev = &eb->vma[i];
>> +               unsigned int flags = ev->flags;
>> +
>> +               if (flags & EXEC_OBJECT_PINNED &&
>> +                   flags & __EXEC_OBJECT_HAS_PIN)
>> +                       continue;
>> +
>> +               unpinned = true;
>> +               eb_unreserve_vma(ev);
>> +
>> +               if (flags & EXEC_OBJECT_PINNED)
>> +                       /* Pinned must have their slot */
>> +                       list_add(&ev->bind_link, &eb->unbound);
>> +               else if (flags & __EXEC_OBJECT_NEEDS_MAP)
>> +                       /* Map require the lowest 256MiB (aperture) */
>> +                       list_add_tail(&ev->bind_link, &eb->unbound);
>> +               else if (!(flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS))
>> +                       /* Prioritise 4GiB region for restricted bo */
>> +                       list_add(&ev->bind_link, &last);
>> +               else
>> +                       list_add_tail(&ev->bind_link, &last);
>> +       }
>> +
>> +       list_splice_tail(&last, &eb->unbound);
>> +       return unpinned;
>> +}
>> +
>> +static int eb_reserve(struct i915_execbuffer *eb)
>> +{
>>         struct eb_vma *ev;
>> -       unsigned int i, pass;
>> +       unsigned int pass;
>>         int err = 0;
>> +       bool unpinned;
>>
>>         /*
>>          * Attempt to pin all of the buffers into the GTT.
>> -        * This is done in 3 phases:
>> +        * This is done in 2 phases:
>>          *
>> -        * 1a. Unbind all objects that do not match the GTT constraints for
>> -        *     the execbuffer (fenceable, mappable, alignment etc).
>> -        * 1b. Increment pin count for already bound objects.
>> -        * 2.  Bind new objects.
>> -        * 3.  Decrement pin count.
>> +        * 1. Unbind all objects that do not match the GTT constraints for
>> +        *    the execbuffer (fenceable, mappable, alignment etc).
>> +        * 2. Bind new objects.
>>          *
>>          * This avoid unnecessary unbinding of later objects in order to make
>>          * room for the earlier objects *unless* we need to defragment.
>> +        *
>> +        * Defragmenting is skipped if all objects are pinned at a fixed location.
>>          */
>> -       pass = 0;
>> -       do {
>> -               list_for_each_entry(ev, &eb->unbound, bind_link) {
>> -                       err = eb_reserve_vma(eb, ev, pin_flags);
>> -                       if (err)
>> -                               break;
>> -               }
>> -               if (err != -ENOSPC)
>> -                       return err;
>> +       for (pass = 0; pass <= 2; pass++) {
>> +               int pin_flags = PIN_USER | PIN_VALIDATE;
>>
>> -               /* Resort *all* the objects into priority order */
>> -               INIT_LIST_HEAD(&eb->unbound);
>> -               INIT_LIST_HEAD(&last);
>> -               for (i = 0; i < count; i++) {
>> -                       unsigned int flags;
>> +               if (pass == 0)
>> +                       pin_flags |= PIN_NONBLOCK;
>>
>> -                       ev = &eb->vma[i];
>> -                       flags = ev->flags;
>> -                       if (flags & EXEC_OBJECT_PINNED &&
>> -                           flags & __EXEC_OBJECT_HAS_PIN)
>> -                               continue;
>> +               if (pass >= 1)
>> +                       unpinned = eb_unbind(eb);
>>
>> -                       eb_unreserve_vma(ev);
>> -
>> -                       if (flags & EXEC_OBJECT_PINNED)
>> -                               /* Pinned must have their slot */
>> -                               list_add(&ev->bind_link, &eb->unbound);
>> -                       else if (flags & __EXEC_OBJECT_NEEDS_MAP)
>> -                               /* Map require the lowest 256MiB (aperture) */
>> -                               list_add_tail(&ev->bind_link, &eb->unbound);
>> -                       else if (!(flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS))
>> -                               /* Prioritise 4GiB region for restricted bo */
>> -                               list_add(&ev->bind_link, &last);
>> -                       else
>> -                               list_add_tail(&ev->bind_link, &last);
>> -               }
>> -               list_splice_tail(&last, &eb->unbound);
>> -
>> -               switch (pass++) {
>> -               case 0:
>> -                       break;
>> +               if (pass == 2) {
>> +                       /* No point in defragmenting gtt if all is pinned */
>> +                       if (!unpinned)
>> +                               return -ENOSPC;
> Can this ever happen? If everything is already pinned where it's meant
> to be, then how did we get here?
Hmm no, in previous versions it could, but it looks like I removed that in a refactor. Seems like dead code.
>
>> -               case 1:
>> -                       /* Too fragmented, unbind everything and retry */
>> -                       mutex_lock(&eb->context->vm->mutex);
>> -                       err = i915_gem_evict_vm(eb->context->vm, &eb->ww);
>> -                       mutex_unlock(&eb->context->vm->mutex);
>> +                       err = eb_evict_vm(eb);
>>                         if (err)
>>                                 return err;
>> -                       break;
>> +               }
>>
>> -               default:
>> -                       return -ENOSPC;
>> +               list_for_each_entry(ev, &eb->unbound, bind_link) {
>> +                       err = eb_reserve_vma(eb, ev, pin_flags);
>> +                       if (err)
>> +                               break;
>>                 }
>>
>> -               pin_flags = PIN_USER;
>> -       } while (1);
>> +               if (err != -ENOSPC)
>> +                       break;
>> +       }
>> +
>> +       return err;
>>  }
>>
>>  static int eb_select_context(struct i915_execbuffer *eb)
>> @@ -1184,10 +1220,11 @@ static void *reloc_kmap(struct drm_i915_gem_object *obj,
>>         return vaddr;
>>  }
>>
>> -static void *reloc_iomap(struct drm_i915_gem_object *obj,
>> +static void *reloc_iomap(struct i915_vma *batch,
>>                          struct i915_execbuffer *eb,
>>                          unsigned long page)
>>  {
>> +       struct drm_i915_gem_object *obj = batch->obj;
>>         struct reloc_cache *cache = &eb->reloc_cache;
>>         struct i915_ggtt *ggtt = cache_to_ggtt(cache);
>>         unsigned long offset;
>> @@ -1197,7 +1234,7 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
>>                 intel_gt_flush_ggtt_writes(ggtt->vm.gt);
>>                 io_mapping_unmap_atomic((void __force __iomem *) unmask_page(cache->vaddr));
>>         } else {
>> -               struct i915_vma *vma;
>> +               struct i915_vma *vma = ERR_PTR(-ENODEV);
>>                 int err;
>>
>>                 if (i915_gem_object_is_tiled(obj))
>> @@ -1210,10 +1247,23 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
>>                 if (err)
>>                         return ERR_PTR(err);
>>
>> -               vma = i915_gem_object_ggtt_pin_ww(obj, &eb->ww, NULL, 0, 0,
>> -                                                 PIN_MAPPABLE |
>> -                                                 PIN_NONBLOCK /* NOWARN */ |
>> -                                                 PIN_NOEVICT);
>> +               /*
>> +                * i915_gem_object_ggtt_pin_ww may attempt to remove the batch
>> +                * VMA from the object list because we no longer pin.
>> +                *
>> +                * Only attempt to pin the batch buffer to ggtt if the current batch
>> +                * is not inside ggtt, or the batch buffer is not misplaced.
>> +                */
>> +               if (!i915_is_ggtt(batch->vm)) {
>> +                       vma = i915_gem_object_ggtt_pin_ww(obj, &eb->ww, NULL, 0, 0,
>> +                                                         PIN_MAPPABLE |
>> +                                                         PIN_NONBLOCK /* NOWARN */ |
>> +                                                         PIN_NOEVICT);
>> +               } else if (i915_vma_is_map_and_fenceable(batch)) {
>> +                       __i915_vma_pin(batch);
>> +                       vma = batch;
>> +               }
>> +
>>                 if (vma == ERR_PTR(-EDEADLK))
>>                         return vma;
>>
>> @@ -1251,7 +1301,7 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
>>         return vaddr;
>>  }
>>
>> -static void *reloc_vaddr(struct drm_i915_gem_object *obj,
>> +static void *reloc_vaddr(struct i915_vma *vma,
>>                          struct i915_execbuffer *eb,
>>                          unsigned long page)
>>  {
>> @@ -1263,9 +1313,9 @@ static void *reloc_vaddr(struct drm_i915_gem_object *obj,
>>         } else {
>>                 vaddr = NULL;
>>                 if ((cache->vaddr & KMAP) == 0)
>> -                       vaddr = reloc_iomap(obj, eb, page);
>> +                       vaddr = reloc_iomap(vma, eb, page);
>>                 if (!vaddr)
>> -                       vaddr = reloc_kmap(obj, cache, page);
>> +                       vaddr = reloc_kmap(vma->obj, cache, page);
>>         }
>>
>>         return vaddr;
>> @@ -1306,7 +1356,7 @@ relocate_entry(struct i915_vma *vma,
>>         void *vaddr;
>>
>>  repeat:
>> -       vaddr = reloc_vaddr(vma->obj, eb,
>> +       vaddr = reloc_vaddr(vma, eb,
>>                             offset >> PAGE_SHIFT);
>>         if (IS_ERR(vaddr))
>>                 return PTR_ERR(vaddr);
>> @@ -2074,7 +2124,7 @@ shadow_batch_pin(struct i915_execbuffer *eb,
>>         if (IS_ERR(vma))
>>                 return vma;
>>
>> -       err = i915_vma_pin_ww(vma, &eb->ww, 0, 0, flags);
>> +       err = i915_vma_pin_ww(vma, &eb->ww, 0, 0, flags | PIN_VALIDATE);
>>         if (err)
>>                 return ERR_PTR(err);
>>
>> @@ -2088,7 +2138,7 @@ static struct i915_vma *eb_dispatch_secure(struct i915_execbuffer *eb, struct i9
>>          * batch" bit. Hence we need to pin secure batches into the global gtt.
>>          * hsw should have this fixed, but bdw mucks it up again. */
>>         if (eb->batch_flags & I915_DISPATCH_SECURE)
>> -               return i915_gem_object_ggtt_pin_ww(vma->obj, &eb->ww, NULL, 0, 0, 0);
>> +               return i915_gem_object_ggtt_pin_ww(vma->obj, &eb->ww, NULL, 0, 0, PIN_VALIDATE);
>>
>>         return NULL;
>>  }
>> @@ -2139,13 +2189,12 @@ static int eb_parse(struct i915_execbuffer *eb)
>>
>>         err = i915_gem_object_lock(pool->obj, &eb->ww);
>>         if (err)
>> -               goto err;
>> +               return err;
>>
>>         shadow = shadow_batch_pin(eb, pool->obj, eb->context->vm, PIN_USER);
>> -       if (IS_ERR(shadow)) {
>> -               err = PTR_ERR(shadow);
>> -               goto err;
>> -       }
>> +       if (IS_ERR(shadow))
>> +               return PTR_ERR(shadow);
>> +
>>         intel_gt_buffer_pool_mark_used(pool);
>>         i915_gem_object_set_readonly(shadow->obj);
>>         shadow->private = pool;
>> @@ -2157,25 +2206,21 @@ static int eb_parse(struct i915_execbuffer *eb)
>>                 shadow = shadow_batch_pin(eb, pool->obj,
>>                                           &eb->gt->ggtt->vm,
>>                                           PIN_GLOBAL);
>> -               if (IS_ERR(shadow)) {
>> -                       err = PTR_ERR(shadow);
>> -                       shadow = trampoline;
>> -                       goto err_shadow;
>> -               }
>> +               if (IS_ERR(shadow))
>> +                       return PTR_ERR(shadow);
>> +
>>                 shadow->private = pool;
>>
>>                 eb->batch_flags |= I915_DISPATCH_SECURE;
>>         }
>>
>>         batch = eb_dispatch_secure(eb, shadow);
>> -       if (IS_ERR(batch)) {
>> -               err = PTR_ERR(batch);
>> -               goto err_trampoline;
>> -       }
>> +       if (IS_ERR(batch))
>> +               return PTR_ERR(batch);
>>
>>         err = dma_resv_reserve_shared(shadow->obj->base.resv, 1);
>>         if (err)
>> -               goto err_trampoline;
>> +               return err;
>>
>>         err = intel_engine_cmd_parser(eb->context->engine,
>>                                       eb->batches[0]->vma,
>> @@ -2183,7 +2228,7 @@ static int eb_parse(struct i915_execbuffer *eb)
>>                                       eb->batch_len[0],
>>                                       shadow, trampoline);
>>         if (err)
>> -               goto err_unpin_batch;
>> +               return err;
>>
>>         eb->batches[0] = &eb->vma[eb->buffer_count++];
>>         eb->batches[0]->vma = i915_vma_get(shadow);
>> @@ -2202,17 +2247,6 @@ static int eb_parse(struct i915_execbuffer *eb)
>>                 eb->batches[0]->vma = i915_vma_get(batch);
>>         }
>>         return 0;
>> -
>> -err_unpin_batch:
>> -       if (batch)
>> -               i915_vma_unpin(batch);
>> -err_trampoline:
>> -       if (trampoline)
>> -               i915_vma_unpin(trampoline);
>> -err_shadow:
>> -       i915_vma_unpin(shadow);
>> -err:
>> -       return err;
>>  }
>>
>>  static int eb_request_submit(struct i915_execbuffer *eb,
>> @@ -3337,8 +3371,6 @@ i915_gem_do_execbuffer(struct drm_device *dev,
>>
>>  err_vma:
>>         eb_release_vmas(&eb, true);
>> -       if (eb.trampoline)
>> -               i915_vma_unpin(eb.trampoline);
>>         WARN_ON(err == -EDEADLK);
>>         i915_gem_ww_ctx_fini(&eb.ww);
>>
>> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
>> index e4938aba3fe9..8c2f57eb5dda 100644
>> --- a/drivers/gpu/drm/i915/i915_gem_gtt.h
>> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
>> @@ -44,6 +44,7 @@ int i915_gem_gtt_insert(struct i915_address_space *vm,
>>  #define PIN_HIGH               BIT_ULL(5)
>>  #define PIN_OFFSET_BIAS                BIT_ULL(6)
>>  #define PIN_OFFSET_FIXED       BIT_ULL(7)
>> +#define PIN_VALIDATE           BIT_ULL(8) /* validate placement only, no need to call unpin() */
>>
>>  #define PIN_GLOBAL             BIT_ULL(10) /* I915_VMA_GLOBAL_BIND */
>>  #define PIN_USER               BIT_ULL(11) /* I915_VMA_LOCAL_BIND */
>> diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
>> index 65168db534f0..0706731b211d 100644
>> --- a/drivers/gpu/drm/i915/i915_vma.c
>> +++ b/drivers/gpu/drm/i915/i915_vma.c
>> @@ -751,6 +751,15 @@ static bool try_qad_pin(struct i915_vma *vma, unsigned int flags)
>>         unsigned int bound;
>>
>>         bound = atomic_read(&vma->flags);
>> +
>> +       if (flags & PIN_VALIDATE) {
>> +               flags &= I915_VMA_BIND_MASK;
>> +
>> +               return (flags & bound) == flags;
>> +       }
>> +
>> +       /* with the lock mandatory for unbind, we don't race here */
>> +       flags &= I915_VMA_BIND_MASK;
>>         do {
>>                 if (unlikely(flags & ~bound))
>>                         return false;
>> @@ -1176,7 +1185,7 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
>>         GEM_BUG_ON(!(flags & (PIN_USER | PIN_GLOBAL)));
>>
>>         /* First try and grab the pin without rebinding the vma */
>> -       if (try_qad_pin(vma, flags & I915_VMA_BIND_MASK))
>> +       if (try_qad_pin(vma, flags))
>>                 return 0;
>>
>>         err = i915_vma_get_pages(vma);
>> @@ -1255,7 +1264,8 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
>>         }
>>
>>         if (unlikely(!(flags & ~bound & I915_VMA_BIND_MASK))) {
>> -               __i915_vma_pin(vma);
>> +               if (!(flags & PIN_VALIDATE))
>> +                       __i915_vma_pin(vma);
>>                 goto err_unlock;
>>         }
>>
>> @@ -1284,8 +1294,10 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
>>         atomic_add(I915_VMA_PAGES_ACTIVE, &vma->pages_count);
>>         list_move_tail(&vma->vm_link, &vma->vm->bound_list);
>>
>> -       __i915_vma_pin(vma);
>> -       GEM_BUG_ON(!i915_vma_is_pinned(vma));
>> +       if (!(flags & PIN_VALIDATE)) {
>> +               __i915_vma_pin(vma);
>> +               GEM_BUG_ON(!i915_vma_is_pinned(vma));
>> +       }
>>         GEM_BUG_ON(!i915_vma_is_bound(vma, flags));
>>         GEM_BUG_ON(i915_vma_misplaced(vma, size, alignment, flags));
>>
>> @@ -1538,8 +1550,6 @@ static int __i915_vma_move_to_active(struct i915_vma *vma, struct i915_request *
>>  {
>>         int err;
>>
>> -       GEM_BUG_ON(!i915_vma_is_pinned(vma));
>> -
>>         /* Wait for the vma to be bound before we start! */
>>         err = __i915_request_await_bind(rq, vma);
>>         if (err)
>> @@ -1558,6 +1568,8 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
>>
>>         assert_object_held(obj);
>>
>> +       GEM_BUG_ON(!vma->pages);
>> +
>>         err = __i915_vma_move_to_active(vma, rq);
>>         if (unlikely(err))
>>                 return err;
>> --
>> 2.33.0
>>


^ permalink raw reply	[flat|nested] 114+ messages in thread

end of thread, other threads:[~2021-11-29 13:44 UTC | newest]

Thread overview: 114+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-21 10:35 [PATCH 01/28] drm/i915: Fix i915_request fence wait semantics Maarten Lankhorst
2021-10-21 10:35 ` [Intel-gfx] " Maarten Lankhorst
2021-10-21 10:35 ` [PATCH 02/28] drm/i915: use new iterator in i915_gem_object_wait_reservation Maarten Lankhorst
2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
2021-10-21 10:38   ` Christian König
2021-10-21 10:38     ` [Intel-gfx] " Christian König
2021-10-21 11:06     ` Maarten Lankhorst
2021-10-21 11:06       ` [Intel-gfx] " Maarten Lankhorst
2021-10-21 11:13       ` Tvrtko Ursulin
2021-10-28  8:41         ` Christian König
2021-10-28 15:30           ` Daniel Vetter
2021-11-01  9:41             ` Tvrtko Ursulin
2021-11-11 11:36               ` Christian König
2021-11-12 16:07                 ` Daniel Vetter
2021-11-12 16:07                   ` Daniel Vetter
2021-10-21 10:35 ` [PATCH 03/28] drm/i915: Remove dma_resv_prune Maarten Lankhorst
2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
2021-10-21 14:43   ` Matthew Auld
2021-10-21 14:43     ` [Intel-gfx] " Matthew Auld
2021-10-22  8:48     ` Maarten Lankhorst
2021-10-22  8:48       ` [Intel-gfx] " Maarten Lankhorst
2021-10-21 10:35 ` [PATCH 04/28] drm/i915: Remove unused bits of i915_vma/active api Maarten Lankhorst
2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
2021-10-21 10:35 ` [PATCH 05/28] drm/i915: Slightly rework EXEC_OBJECT_CAPTURE handling, v2 Maarten Lankhorst
2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
2021-10-21 10:35 ` [PATCH 06/28] drm/i915: Remove gen6_ppgtt_unpin_all Maarten Lankhorst
2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
2021-10-21 10:35 ` [PATCH 07/28] drm/i915: Create a dummy object for gen6 ppgtt Maarten Lankhorst
2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
2021-10-21 15:42   ` Matthew Auld
2021-10-21 10:35 ` [PATCH 08/28] drm/i915: Create a full object for mock_ring, v2 Maarten Lankhorst
2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
2021-10-21 15:57   ` Matthew Auld
2021-10-21 15:57     ` [Intel-gfx] " Matthew Auld
2021-10-22 11:03     ` Maarten Lankhorst
2021-10-22 11:03       ` [Intel-gfx] " Maarten Lankhorst
2021-10-21 10:35 ` [PATCH 09/28] drm/i915: vma is always backed by an object Maarten Lankhorst
2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
2021-10-21 16:09   ` Matthew Auld
2021-10-21 10:35 ` [Intel-gfx] [PATCH 10/28] drm/i915: Change shrink ordering to use locking around unbinding Maarten Lankhorst
2021-10-21 10:35   ` Maarten Lankhorst
2021-10-21 16:12   ` [Intel-gfx] " Matthew Auld
2021-10-22 11:04     ` Maarten Lankhorst
2021-10-21 10:35 ` [PATCH 11/28] drm/i915/pm: Move CONTEXT_VALID_BIT check Maarten Lankhorst
2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
2021-11-02 16:13   ` Matthew Auld
2021-11-02 16:13     ` Matthew Auld
2021-10-21 10:35 ` [PATCH 12/28] drm/i915: Remove resv from i915_vma Maarten Lankhorst
2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
2021-10-21 10:35 ` [Intel-gfx] [PATCH 13/28] drm/i915: Remove pages_mutex and intel_gtt->vma_ops.set/clear_pages members Maarten Lankhorst
2021-10-21 10:35   ` Maarten Lankhorst
2021-10-21 17:30   ` [Intel-gfx] " Matthew Auld
2021-10-22 10:59     ` Matthew Auld
2021-11-29 12:40       ` Maarten Lankhorst
2021-10-21 10:35 ` [PATCH 14/28] drm/i915: Take object lock in i915_ggtt_pin if ww is not set Maarten Lankhorst
2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
2021-10-21 17:39   ` Matthew Auld
2021-11-29 12:46     ` Maarten Lankhorst
2021-10-21 10:35 ` [Intel-gfx] [PATCH 15/28] drm/i915: Add lock for unbinding to i915_gem_object_ggtt_pin_ww Maarten Lankhorst
2021-10-21 10:35   ` Maarten Lankhorst
2021-10-21 17:48   ` [Intel-gfx] " Matthew Auld
2021-11-29 13:25     ` Maarten Lankhorst
2021-10-21 10:35 ` [PATCH 16/28] drm/i915: Rework context handling in hugepages selftests Maarten Lankhorst
2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
2021-10-21 17:55   ` Matthew Auld
2021-10-22  6:51   ` kernel test robot
2021-10-22  6:51     ` kernel test robot
2021-10-22  7:21   ` kernel test robot
2021-10-22  7:21     ` kernel test robot
2021-11-03 11:33   ` kernel test robot
2021-11-03 11:33   ` [RFC PATCH] drm/i915: hugepage_ctx() can be static kernel test robot
2021-10-21 10:35 ` [PATCH 17/28] drm/i915: Ensure gem_contexts selftests work with unbind changes Maarten Lankhorst
2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
2021-10-21 10:35 ` [Intel-gfx] [PATCH 18/28] drm/i915: Take trylock during eviction, v2 Maarten Lankhorst
2021-10-21 10:35   ` Maarten Lankhorst
2021-10-21 17:59   ` [Intel-gfx] " Matthew Auld
2021-10-22  8:44     ` Maarten Lankhorst
2021-10-22  8:44       ` Maarten Lankhorst
2021-10-21 10:35 ` [PATCH 19/28] drm/i915: Pass trylock context to callers Maarten Lankhorst
2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
2021-10-21 18:03   ` Matthew Auld
2021-10-22  8:52     ` Maarten Lankhorst
2021-10-21 10:35 ` [PATCH 20/28] drm/i915: Ensure i915_vma tests do not get -ENOSPC with the locking changes Maarten Lankhorst
2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
2021-10-21 10:35 ` [PATCH 21/28] drm/i915: Drain the ttm delayed workqueue too Maarten Lankhorst
2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
2021-10-25 15:11   ` Matthew Auld
2021-10-25 15:11     ` [Intel-gfx] " Matthew Auld
2021-10-21 10:35 ` [PATCH 22/28] drm/i915: Make i915_gem_evict_vm work correctly for already locked objects Maarten Lankhorst
2021-10-21 10:35   ` [Intel-gfx] " Maarten Lankhorst
2021-10-21 10:36 ` [Intel-gfx] [PATCH 23/28] drm/i915: Call i915_gem_evict_vm in vm_fault_gtt to prevent new ENOSPC errors Maarten Lankhorst
2021-10-21 10:36   ` Maarten Lankhorst
2021-10-21 10:36 ` [PATCH 24/28] drm/i915: Add i915_vma_unbind_unlocked, and take obj lock for i915_vma_unbind Maarten Lankhorst
2021-10-21 10:36   ` [Intel-gfx] " Maarten Lankhorst
2021-10-21 10:36 ` [PATCH 25/28] drm/i915: Require object lock when freeing pages during destruction Maarten Lankhorst
2021-10-21 10:36   ` [Intel-gfx] " Maarten Lankhorst
2021-10-22 11:10   ` Matthew Auld
2021-10-21 10:36 ` [PATCH 26/28] drm/i915: Remove assert_object_held_shared Maarten Lankhorst
2021-10-21 10:36   ` [Intel-gfx] " Maarten Lankhorst
2021-10-21 10:36 ` [PATCH 27/28] drm/i915: Remove support for unlocked i915_vma unbind Maarten Lankhorst
2021-10-21 10:36   ` [Intel-gfx] " Maarten Lankhorst
2021-10-21 10:36 ` [PATCH 28/28] drm/i915: Remove short-term pins from execbuf, v4 Maarten Lankhorst
2021-10-21 10:36   ` [Intel-gfx] " Maarten Lankhorst
2021-10-25 15:02   ` Matthew Auld
2021-10-25 15:02     ` [Intel-gfx] " Matthew Auld
2021-11-29 13:44     ` Maarten Lankhorst
2021-11-29 13:44       ` [Intel-gfx] " Maarten Lankhorst
2021-10-21 10:56 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/28] drm/i915: Fix i915_request fence wait semantics Patchwork
2021-10-21 10:57 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2021-10-21 11:01 ` [Intel-gfx] ✗ Fi.CI.DOCS: " Patchwork
2021-10-21 11:27 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2021-10-21 12:57 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork
2021-10-22 11:24   ` Matthew Auld
2021-10-22 13:17     ` Maarten Lankhorst

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.