All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Wilson <chris@chris-wilson.co.uk>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH 59/62] drm/i915: Track active vma requests
Date: Fri,  3 Jun 2016 17:37:24 +0100	[thread overview]
Message-ID: <1464971847-15809-60-git-send-email-chris@chris-wilson.co.uk> (raw)
In-Reply-To: <1464971847-15809-1-git-send-email-chris@chris-wilson.co.uk>

Hook the vma itself into the i915_gem_request_retire() so that we can
accurately track when a solitary vma is inactive (as opposed to having
to wait for the entire object to be idle). This improves the interaction
when using multiple contexts (with full-ppgtt) and eliminates some
frequent list walking when retiring objects after a completed request.

A side-effect is that we get an active vma reference for free. The
consequence of this is shown in the next patch...

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_debugfs.c        |  2 +-
 drivers/gpu/drm/i915/i915_gem.c            | 20 +++++++-------------
 drivers/gpu/drm/i915/i915_gem_execbuffer.c | 10 +++++++++-
 drivers/gpu/drm/i915/i915_gem_gtt.c        | 20 ++++++++++++++++++++
 drivers/gpu/drm/i915/i915_gem_gtt.h        | 26 ++++++++++++++++++++++++++
 5 files changed, 63 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 51f84dd37675..99857ee0bb8b 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -367,7 +367,7 @@ static int per_file_stats(int id, void *ptr, void *data)
 				continue;
 		}
 
-		if (obj->active) /* XXX per-vma statistic */
+		if (i915_vma_is_active(vma))
 			stats->active += vma->node.size;
 		else
 			stats->inactive += vma->node.size;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index a39d767d8137..ef68a9183d7d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2100,7 +2100,6 @@ i915_gem_object_retire__read(struct i915_gem_active *active,
 	int ring = request->engine->id;
 	struct drm_i915_gem_object *obj =
 		container_of(active, struct drm_i915_gem_object, last_read[ring]);
-	struct i915_vma *vma;
 
 	GEM_BUG_ON((obj->active & (1 << ring)) == 0);
 
@@ -2112,12 +2111,9 @@ i915_gem_object_retire__read(struct i915_gem_active *active,
 	 * so that we don't steal from recently used but inactive objects
 	 * (unless we are forced to ofc!)
 	 */
-	list_move_tail(&obj->global_list, &request->i915->mm.bound_list);
-
-	list_for_each_entry(vma, &obj->vma_list, obj_link) {
-		if (!list_empty(&vma->vm_link))
-			list_move_tail(&vma->vm_link, &vma->vm->inactive_list);
-	}
+	if (obj->bind_count)
+		list_move_tail(&obj->global_list,
+			       &request->i915->mm.bound_list);
 
 	i915_gem_object_put(obj);
 }
@@ -2915,9 +2911,6 @@ i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj)
 int
 i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
 {
-	struct drm_device *dev = obj->base.dev;
-	struct drm_i915_private *dev_priv = to_i915(dev);
-	struct i915_ggtt *ggtt = &dev_priv->ggtt;
 	uint32_t old_write_domain, old_read_domains;
 	struct i915_vma *vma;
 	int ret;
@@ -2970,9 +2963,10 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
 
 	/* And bump the LRU for this access */
 	vma = i915_gem_obj_to_ggtt(obj);
-	if (vma && drm_mm_node_allocated(&vma->node) && !obj->active)
-		list_move_tail(&vma->vm_link,
-			       &ggtt->base.inactive_list);
+	if (vma &&
+	    drm_mm_node_allocated(&vma->node) &&
+	    !i915_vma_is_active(vma))
+		list_move_tail(&vma->vm_link, &vma->vm->inactive_list);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index e099080b3b5b..7b381358512e 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1121,7 +1121,13 @@ void i915_vma_move_to_active(struct i915_vma *vma,
 
 	obj->dirty = 1; /* be paranoid  */
 
-	/* Add a reference if we're newly entering the active list. */
+	/* Add a reference if we're newly entering the active list.
+	 * The order in which we add operations to the retirement queue is
+	 * vital here: mark_active adds to the start of the callback list,
+	 * such that subsequent callbacks are called first. Therefore we
+	 * add the active reference first and queue for it to be dropped
+	 * *last*.
+	 */
 	if (obj->active == 0)
 		i915_gem_object_get(obj);
 	obj->active |= 1 << idx;
@@ -1145,6 +1151,8 @@ void i915_vma_move_to_active(struct i915_vma *vma,
 		}
 	}
 
+	i915_vma_set_active(vma, idx);
+	i915_gem_active_set(&vma->last_read[idx], req);
 	list_move_tail(&vma->vm_link, &vma->vm->active_list);
 }
 
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 57fc84b9b633..4d3179e15b94 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -3281,12 +3281,30 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev)
 	i915_ggtt_flush(dev_priv);
 }
 
+static void
+i915_vma_retire(struct i915_gem_active *active,
+		struct drm_i915_gem_request *rq)
+{
+	const unsigned idx = rq->engine->id;
+	struct i915_vma *vma =
+		container_of(active, struct i915_vma, last_read[idx]);
+
+	GEM_BUG_ON(!i915_vma_has_active_engine(vma, idx));
+
+	i915_vma_unset_active(vma, idx);
+	if (i915_vma_is_active(vma))
+		return;
+
+	list_move_tail(&vma->vm_link, &vma->vm->inactive_list);
+}
+
 static struct i915_vma *
 __i915_gem_vma_create(struct drm_i915_gem_object *obj,
 		      struct i915_address_space *vm,
 		      const struct i915_ggtt_view *ggtt_view)
 {
 	struct i915_vma *vma;
+	int i;
 
 	if (WARN_ON(i915_is_ggtt(vm) != !!ggtt_view))
 		return ERR_PTR(-EINVAL);
@@ -3298,6 +3316,8 @@ __i915_gem_vma_create(struct drm_i915_gem_object *obj,
 	INIT_LIST_HEAD(&vma->vm_link);
 	INIT_LIST_HEAD(&vma->obj_link);
 	INIT_LIST_HEAD(&vma->exec_list);
+	for (i = 0; i < ARRAY_SIZE(vma->last_read); i++)
+		init_request_active(&vma->last_read[i], i915_vma_retire);
 	vma->vm = vm;
 	vma->obj = obj;
 	vma->is_ggtt = i915_is_ggtt(vm);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 4cabf891fd1d..d86b3e4777a7 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -36,6 +36,8 @@
 
 #include <linux/io-mapping.h>
 
+#include "i915_gem_request.h"
+
 struct drm_i915_file_private;
 
 typedef uint32_t gen6_pte_t;
@@ -179,10 +181,13 @@ struct i915_vma {
 	struct i915_address_space *vm;
 	void __iomem *iomap;
 
+	struct i915_gem_active last_read[I915_NUM_ENGINES];
+
 	/** Flags and address space this VMA is bound to */
 #define GLOBAL_BIND	(1<<0)
 #define LOCAL_BIND	(1<<1)
 	unsigned int bound : 4;
+	unsigned int active : I915_NUM_ENGINES;
 	bool is_ggtt : 1;
 
 	/**
@@ -222,6 +227,27 @@ struct i915_vma {
 #define DRM_I915_GEM_OBJECT_MAX_PIN_COUNT 0xf
 };
 
+static inline bool i915_vma_is_active(const struct i915_vma *vma)
+{
+	return vma->active;
+}
+
+static inline void i915_vma_set_active(struct i915_vma *vma, unsigned engine)
+{
+	vma->active |= 1 << engine;
+}
+
+static inline void i915_vma_unset_active(struct i915_vma *vma, unsigned engine)
+{
+	vma->active &= ~(1 << engine);
+}
+
+static inline bool i915_vma_has_active_engine(const struct i915_vma *vma,
+					      unsigned engine)
+{
+	return vma->active & (1 << engine);
+}
+
 struct i915_page_dma {
 	struct page *page;
 	union {
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  parent reply	other threads:[~2016-06-03 16:38 UTC|newest]

Thread overview: 87+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-03 16:36 The vma leak fix from yonder Chris Wilson
2016-06-03 16:36 ` [PATCH 01/62] drm/i915: Only start retire worker when idle Chris Wilson
2016-06-07 11:31   ` Joonas Lahtinen
2016-06-08 10:53     ` Chris Wilson
2016-06-08 11:06       ` Chris Wilson
2016-06-08 12:07         ` Joonas Lahtinen
2016-06-03 16:36 ` [PATCH 02/62] drm/i915: Do not keep postponing the idle-work Chris Wilson
2016-06-07 11:34   ` Joonas Lahtinen
2016-06-03 16:36 ` [PATCH 03/62] drm/i915: Remove redundant queue_delayed_work() from throttle ioctl Chris Wilson
2016-06-07 11:39   ` Joonas Lahtinen
2016-06-03 16:36 ` [PATCH 04/62] drm/i915: Restore waitboost credit to the synchronous waiter Chris Wilson
2016-06-08  9:04   ` Daniel Vetter
2016-06-08 10:38     ` Chris Wilson
2016-06-03 16:36 ` [PATCH 05/62] drm/i915: Add background commentary to "waitboosting" Chris Wilson
2016-06-03 16:36 ` [PATCH 06/62] drm/i915: Flush the RPS bottom-half when the GPU idles Chris Wilson
2016-06-16  8:49   ` Michał Winiarski
2016-06-16 11:09     ` Chris Wilson
2016-06-03 16:36 ` [PATCH 07/62] drm/i915: Remove temporary RPM wakeref assert disables Chris Wilson
2016-06-03 16:36 ` [PATCH 08/62] drm/i915: Remove stop-rings debugfs interface Chris Wilson
2016-06-08 11:50   ` Arun Siluvery
2016-06-03 16:36 ` [PATCH 09/62] drm/i915: Record the ringbuffer associated with the request Chris Wilson
2016-06-03 16:36 ` [PATCH 10/62] drm/i915: Allow userspace to request no-error-capture upon GPU hangs Chris Wilson
2016-06-03 16:36 ` [PATCH 11/62] drm/i915: Clean up GPU hang message Chris Wilson
2016-06-14  8:13   ` Mika Kuoppala
2016-06-03 16:36 ` [PATCH 12/62] drm/i915: Skip capturing an error state if we already have one Chris Wilson
2016-06-08 11:14   ` Arun Siluvery
2016-06-08 12:06     ` Chris Wilson
2016-06-03 16:36 ` [PATCH 13/62] drm/i915: Derive GEM requests from dma-fence Chris Wilson
2016-06-08  9:14   ` Daniel Vetter
2016-06-08 10:33     ` Chris Wilson
2016-06-03 16:36 ` [PATCH 14/62] drm/i915: Rename request reference/unreference to get/put Chris Wilson
2016-06-08  9:15   ` Daniel Vetter
2016-06-03 16:36 ` [PATCH 15/62] drm/i915: Rename i915_gem_context_reference/unreference() Chris Wilson
2016-06-06 12:12   ` Joonas Lahtinen
2016-06-03 16:36 ` [PATCH 16/62] drm/i915: Wrap drm_gem_object_lookup in i915_gem_object_lookup Chris Wilson
2016-06-03 16:36 ` [PATCH 17/62] drm/i915: Wrap drm_gem_object_reference in i915_gem_object_get Chris Wilson
2016-06-03 16:36 ` [PATCH 18/62] drm/i915: Rename drm_gem_object_unreference in preparation for lockless free Chris Wilson
2016-06-03 16:36 ` [PATCH 19/62] drm/i915: Rename drm_gem_object_unreference_unlocked " Chris Wilson
2016-06-03 16:36 ` [PATCH 20/62] drm/i915: Disable waitboosting for fence_wait() Chris Wilson
2016-06-03 16:36 ` [PATCH 21/62] drm/i915: Disable waitboosting for mmioflips/semaphores Chris Wilson
2016-06-03 16:36 ` [PATCH 22/62] drm/i915: Treat ringbuffer writes as write to normal memory Chris Wilson
2016-06-03 16:36 ` [PATCH 23/62] drm/i915: Rename ring->virtual_start as ring->vaddr Chris Wilson
2016-06-03 16:36 ` [PATCH 24/62] drm/i915: Convert i915_semaphores_is_enabled over to early sanitize Chris Wilson
2016-06-03 16:36 ` [PATCH 25/62] drm/i915: Unify intel_logical_ring_emit and intel_ring_emit Chris Wilson
2016-06-03 16:36 ` [PATCH 26/62] drm/i915: Rename request->ring to request->engine Chris Wilson
2016-06-06 13:42   ` Tvrtko Ursulin
2016-06-03 16:36 ` [PATCH 27/62] drm/i915: Rename request->ringbuf to request->ring Chris Wilson
2016-06-06 13:44   ` Tvrtko Ursulin
2016-06-08  9:18     ` Daniel Vetter
2016-06-03 16:36 ` [PATCH 28/62] drm/i915: Rename backpointer from intel_ringbuffer to intel_engine_cs Chris Wilson
2016-06-06 13:45   ` Tvrtko Ursulin
2016-06-03 16:36 ` [PATCH 29/62] drm/i915: Rename intel_context[engine].ringbuf Chris Wilson
2016-06-03 16:36 ` [PATCH 30/62] drm/i915: Rename struct intel_ringbuffer to struct intel_ring Chris Wilson
2016-06-03 16:36 ` [PATCH 31/62] drm/i915: Rename residual ringbuf parameters Chris Wilson
2016-06-03 16:36 ` [PATCH 32/62] drm/i915: Rename intel_pin_and_map_ring() Chris Wilson
2016-06-03 16:36 ` [PATCH 33/62] drm/i915: Remove obsolete engine->gpu_caches_dirty Chris Wilson
2016-06-03 16:36 ` [PATCH 34/62] drm/i915: Simplify request_alloc by returning the allocated request Chris Wilson
2016-06-03 16:37 ` [PATCH 35/62] drm/i915: Unify legacy/execlists emission of MI_BATCHBUFFER_START Chris Wilson
2016-06-03 16:37 ` [PATCH 36/62] drm/i915: Convert engine->write_tail to operate on a request Chris Wilson
2016-06-03 16:37 ` [PATCH 37/62] drm/i915: Unify request submission Chris Wilson
2016-06-03 16:37 ` [PATCH 38/62] drm/i915: Stop passing caller's num_dwords to engine->semaphore.signal() Chris Wilson
2016-06-03 16:37 ` [PATCH 39/62] drm/i915: Reuse legacy breadcrumbs + tail emission Chris Wilson
2016-06-03 16:37 ` [PATCH 40/62] drm/i915: Remove duplicate golden render state init from execlists Chris Wilson
2016-06-03 16:37 ` [PATCH 41/62] drm/i915: Unify legacy/execlists submit_execbuf callbacks Chris Wilson
2016-06-03 16:37 ` [PATCH 42/62] drm/i915: Simplify calling engine->sync_to Chris Wilson
2016-06-03 16:37 ` [PATCH 43/62] drm/i915: Introduce i915_gem_active for request tracking Chris Wilson
2016-06-03 16:37 ` [PATCH 44/62] drm/i915: Prepare i915_gem_active for annotations Chris Wilson
2016-06-03 16:37 ` [PATCH 45/62] drm/i915: Mark up i915_gem_active for locking annotation Chris Wilson
2016-06-03 16:37 ` [PATCH 46/62] drm/i915: Refactor blocking waits Chris Wilson
2016-06-03 16:37 ` [PATCH 47/62] drm/i915: Rename request->list to link for consistency Chris Wilson
2016-06-03 16:37 ` [PATCH 48/62] drm/i915: Remove obsolete i915_gem_object_flush_active() Chris Wilson
2016-06-03 16:37 ` [PATCH 49/62] drm/i915: Refactor activity tracking for requests Chris Wilson
2016-06-03 16:37 ` [PATCH 50/62] drm/i915: Double check activity before relocations Chris Wilson
2016-06-03 16:37 ` [PATCH 51/62] drm/i915: Move request list retirement to i915_gem_request.c Chris Wilson
2016-06-03 16:37 ` [PATCH 52/62] drm/i915: Amalgamate GGTT/ppGTT vma debug list walkers Chris Wilson
2016-06-03 16:37 ` [PATCH 53/62] drm/i915: Split early global GTT initialisation Chris Wilson
2016-06-03 16:37 ` [PATCH 54/62] drm/i915: Store owning file on the i915_address_space Chris Wilson
2016-06-03 16:37 ` [PATCH 55/62] drm/i915: i915_vma_move_to_active prep patch Chris Wilson
2016-06-03 16:37 ` [PATCH 56/62] drm/i915: Count how many VMA are bound for an object Chris Wilson
2016-06-03 16:37 ` [PATCH 57/62] drm/i915: Be more careful when unbinding vma Chris Wilson
2016-06-03 16:37 ` [PATCH 58/62] drm/i915: Kill drop_pages() Chris Wilson
2016-06-03 16:37 ` Chris Wilson [this message]
2016-06-03 16:37 ` [PATCH 60/62] drm/i915: Release vma when the handle is closed Chris Wilson
2016-06-03 16:37 ` [PATCH 61/62] drm/i915: Mark the context and address space as closed Chris Wilson
2016-06-03 16:37 ` [PATCH 62/62] Revert "drm/i915: Clean up associated VMAs on context destruction" Chris Wilson
2016-06-05  5:24 ` ✗ Ro.CI.BAT: failure for series starting with [01/62] drm/i915: Only start retire worker when idle Patchwork
2016-06-08  9:30 ` The vma leak fix from yonder Daniel Vetter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1464971847-15809-60-git-send-email-chris@chris-wilson.co.uk \
    --to=chris@chris-wilson.co.uk \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.