All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 01/11] drm/i915: Introduce drm_i915_gem_request_node for request tracking
@ 2015-12-14 11:36 Chris Wilson
  2015-12-14 11:36 ` [PATCH 02/11] drm/i915: Refactor activity tracking for requests Chris Wilson
                   ` (12 more replies)
  0 siblings, 13 replies; 37+ messages in thread
From: Chris Wilson @ 2015-12-14 11:36 UTC (permalink / raw)
  To: intel-gfx

In the next patch, request tracking is made more generic and for that we
need a new expanded struct and to separate out the logic changes from
the mechanical churn, we split out the structure renaming into this
patch. For extra fun, create a new i915_gem_request.h.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_debugfs.c        | 10 +++---
 drivers/gpu/drm/i915/i915_drv.h            |  9 +++--
 drivers/gpu/drm/i915/i915_gem.c            | 56 +++++++++++++++---------------
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |  4 +--
 drivers/gpu/drm/i915/i915_gem_fence.c      |  6 ++--
 drivers/gpu/drm/i915/i915_gem_request.h    | 11 ++++++
 drivers/gpu/drm/i915/i915_gem_tiling.c     |  2 +-
 drivers/gpu/drm/i915/i915_gpu_error.c      |  6 ++--
 drivers/gpu/drm/i915/intel_display.c       | 10 +++---
 9 files changed, 62 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 77bae3151fca..dafc58b94c9f 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -146,10 +146,10 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
 		   obj->base.write_domain);
 	for_each_ring(ring, dev_priv, i)
 		seq_printf(m, "%x ",
-				i915_gem_request_get_seqno(obj->last_read_req[i]));
+				i915_gem_request_get_seqno(obj->last_read[i].request));
 	seq_printf(m, "] %x %x%s%s%s",
-		   i915_gem_request_get_seqno(obj->last_write_req),
-		   i915_gem_request_get_seqno(obj->last_fenced_req),
+		   i915_gem_request_get_seqno(obj->last_write.request),
+		   i915_gem_request_get_seqno(obj->last_fence.request),
 		   i915_cache_level_str(to_i915(obj->base.dev), obj->cache_level),
 		   obj->dirty ? " dirty" : "",
 		   obj->madv == I915_MADV_DONTNEED ? " purgeable" : "");
@@ -184,8 +184,8 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
 		*t = '\0';
 		seq_printf(m, " (%s mappable)", s);
 	}
-	if (obj->last_write_req != NULL)
-		seq_printf(m, " (%s)", obj->last_write_req->engine->name);
+	if (obj->last_write.request != NULL)
+		seq_printf(m, " (%s)", obj->last_write.request->engine->name);
 	if (obj->frontbuffer_bits)
 		seq_printf(m, " (frontbuffer: 0x%03x)", obj->frontbuffer_bits);
 }
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8d3818cb5815..43de7c2c6b3e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2100,11 +2100,10 @@ struct drm_i915_gem_object {
 	 * requests on one ring where the write request is older than the
 	 * read request. This allows for the CPU to read from an active
 	 * buffer by only waiting for the write to complete.
-	 * */
-	struct drm_i915_gem_request *last_read_req[I915_NUM_RINGS];
-	struct drm_i915_gem_request *last_write_req;
-	/** Breadcrumb of last fenced GPU access to the buffer. */
-	struct drm_i915_gem_request *last_fenced_req;
+	 */
+	struct drm_i915_gem_request_active last_read[I915_NUM_RINGS];
+	struct drm_i915_gem_request_active last_write;
+	struct drm_i915_gem_request_active last_fence;
 
 	/** Current tiling stride for the object, if it's tiled. */
 	uint32_t stride;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 65f40d0e1cb7..b412b9291d91 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1119,23 +1119,23 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
 		return 0;
 
 	if (readonly) {
-		if (obj->last_write_req != NULL) {
-			ret = i915_wait_request(obj->last_write_req);
+		if (obj->last_write.request != NULL) {
+			ret = i915_wait_request(obj->last_write.request);
 			if (ret)
 				return ret;
 
-			i = obj->last_write_req->engine->id;
-			if (obj->last_read_req[i] == obj->last_write_req)
+			i = obj->last_write.request->engine->id;
+			if (obj->last_read[i].request == obj->last_write.request)
 				i915_gem_object_retire__read(obj, i);
 			else
 				i915_gem_object_retire__write(obj);
 		}
 	} else {
 		for (i = 0; i < I915_NUM_RINGS; i++) {
-			if (obj->last_read_req[i] == NULL)
+			if (obj->last_read[i].request == NULL)
 				continue;
 
-			ret = i915_wait_request(obj->last_read_req[i]);
+			ret = i915_wait_request(obj->last_read[i].request);
 			if (ret)
 				return ret;
 
@@ -1153,9 +1153,9 @@ i915_gem_object_retire_request(struct drm_i915_gem_object *obj,
 {
 	int ring = req->engine->id;
 
-	if (obj->last_read_req[ring] == req)
+	if (obj->last_read[ring].request == req)
 		i915_gem_object_retire__read(obj, ring);
-	else if (obj->last_write_req == req)
+	else if (obj->last_write.request == req)
 		i915_gem_object_retire__write(obj);
 
 	i915_gem_request_retire__upto(req);
@@ -1183,7 +1183,7 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj,
 	if (readonly) {
 		struct drm_i915_gem_request *req;
 
-		req = obj->last_write_req;
+		req = obj->last_write.request;
 		if (req == NULL)
 			return 0;
 
@@ -1192,7 +1192,7 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj,
 		for (i = 0; i < I915_NUM_RINGS; i++) {
 			struct drm_i915_gem_request *req;
 
-			req = obj->last_read_req[i];
+			req = obj->last_read[i].request;
 			if (req == NULL)
 				continue;
 
@@ -2062,7 +2062,7 @@ void i915_vma_move_to_active(struct i915_vma *vma,
 	obj->active |= intel_engine_flag(engine);
 
 	list_move_tail(&obj->ring_list[engine->id], &engine->active_list);
-	i915_gem_request_assign(&obj->last_read_req[engine->id], req);
+	i915_gem_request_mark_active(req, &obj->last_read[engine->id]);
 
 	list_move_tail(&vma->mm_list, &vma->vm->active_list);
 }
@@ -2070,10 +2070,10 @@ void i915_vma_move_to_active(struct i915_vma *vma,
 static void
 i915_gem_object_retire__write(struct drm_i915_gem_object *obj)
 {
-	RQ_BUG_ON(obj->last_write_req == NULL);
-	RQ_BUG_ON(!(obj->active & intel_engine_flag(obj->last_write_req->engine)));
+	RQ_BUG_ON(obj->last_write.request == NULL);
+	RQ_BUG_ON(!(obj->active & intel_engine_flag(obj->last_write.request->engine)));
 
-	i915_gem_request_assign(&obj->last_write_req, NULL);
+	i915_gem_request_assign(&obj->last_write.request, NULL);
 	intel_fb_obj_flush(obj, true, ORIGIN_CS);
 }
 
@@ -2082,13 +2082,13 @@ i915_gem_object_retire__read(struct drm_i915_gem_object *obj, int ring)
 {
 	struct i915_vma *vma;
 
-	RQ_BUG_ON(obj->last_read_req[ring] == NULL);
+	RQ_BUG_ON(obj->last_read[ring].request == NULL);
 	RQ_BUG_ON(!(obj->active & (1 << ring)));
 
 	list_del_init(&obj->ring_list[ring]);
-	i915_gem_request_assign(&obj->last_read_req[ring], NULL);
+	i915_gem_request_assign(&obj->last_read[ring].request, NULL);
 
-	if (obj->last_write_req && obj->last_write_req->engine->id == ring)
+	if (obj->last_write.request && obj->last_write.request->engine->id == ring)
 		i915_gem_object_retire__write(obj);
 
 	obj->active &= ~(1 << ring);
@@ -2107,7 +2107,7 @@ i915_gem_object_retire__read(struct drm_i915_gem_object *obj, int ring)
 			list_move_tail(&vma->mm_list, &vma->vm->inactive_list);
 	}
 
-	i915_gem_request_assign(&obj->last_fenced_req, NULL);
+	i915_gem_request_assign(&obj->last_fence.request, NULL);
 	drm_gem_object_unreference(&obj->base);
 }
 
@@ -2339,7 +2339,7 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
 				      struct drm_i915_gem_object,
 				      ring_list[ring->id]);
 
-		if (!list_empty(&obj->last_read_req[ring->id]->list))
+		if (!list_empty(&obj->last_read[ring->id].request->list))
 			break;
 
 		i915_gem_object_retire__read(obj, ring->id);
@@ -2442,7 +2442,7 @@ i915_gem_object_flush_active(struct drm_i915_gem_object *obj)
 	for (i = 0; i < I915_NUM_RINGS; i++) {
 		struct drm_i915_gem_request *req;
 
-		req = obj->last_read_req[i];
+		req = obj->last_read[i].request;
 		if (req == NULL)
 			continue;
 
@@ -2522,10 +2522,10 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
 	drm_gem_object_unreference(&obj->base);
 
 	for (i = 0; i < I915_NUM_RINGS; i++) {
-		if (obj->last_read_req[i] == NULL)
+		if (obj->last_read[i].request == NULL)
 			continue;
 
-		req[n++] = i915_gem_request_reference(obj->last_read_req[i]);
+		req[n++] = i915_gem_request_reference(obj->last_read[i].request);
 	}
 
 	mutex_unlock(&dev->struct_mutex);
@@ -2616,12 +2616,12 @@ i915_gem_object_sync(struct drm_i915_gem_object *obj,
 
 	n = 0;
 	if (readonly) {
-		if (obj->last_write_req)
-			req[n++] = obj->last_write_req;
+		if (obj->last_write.request)
+			req[n++] = obj->last_write.request;
 	} else {
 		for (i = 0; i < I915_NUM_RINGS; i++)
-			if (obj->last_read_req[i])
-				req[n++] = obj->last_read_req[i];
+			if (obj->last_read[i].request)
+				req[n++] = obj->last_read[i].request;
 	}
 	for (i = 0; i < n; i++) {
 		ret = __i915_gem_object_sync(obj, to, req[i]);
@@ -3693,8 +3693,8 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
 
 	BUILD_BUG_ON(I915_NUM_RINGS > 16);
 	args->busy = obj->active << 16;
-	if (obj->last_write_req)
-		args->busy |= obj->last_write_req->engine->id;
+	if (obj->last_write.request)
+		args->busy |= obj->last_write.request->engine->id;
 
 unref:
 	drm_gem_object_unreference(&obj->base);
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 7aea026be126..e9741368972e 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1085,7 +1085,7 @@ i915_gem_execbuffer_move_to_active(struct list_head *vmas,
 
 		i915_vma_move_to_active(vma, req);
 		if (obj->base.write_domain) {
-			i915_gem_request_assign(&obj->last_write_req, req);
+			i915_gem_request_mark_active(req, &obj->last_write);
 
 			intel_fb_obj_invalidate(obj, ORIGIN_CS);
 
@@ -1093,7 +1093,7 @@ i915_gem_execbuffer_move_to_active(struct list_head *vmas,
 			obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS;
 		}
 		if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) {
-			i915_gem_request_assign(&obj->last_fenced_req, req);
+			i915_gem_request_mark_active(req, &obj->last_fence);
 			if (entry->flags & __EXEC_OBJECT_HAS_FENCE) {
 				struct drm_i915_private *dev_priv = req->i915;
 				list_move_tail(&dev_priv->fence_regs[obj->fence_reg].lru_list,
diff --git a/drivers/gpu/drm/i915/i915_gem_fence.c b/drivers/gpu/drm/i915/i915_gem_fence.c
index 598198543dcd..ab29c237ffa9 100644
--- a/drivers/gpu/drm/i915/i915_gem_fence.c
+++ b/drivers/gpu/drm/i915/i915_gem_fence.c
@@ -261,12 +261,12 @@ static inline void i915_gem_object_fence_lost(struct drm_i915_gem_object *obj)
 static int
 i915_gem_object_wait_fence(struct drm_i915_gem_object *obj)
 {
-	if (obj->last_fenced_req) {
-		int ret = i915_wait_request(obj->last_fenced_req);
+	if (obj->last_fence.request) {
+		int ret = i915_wait_request(obj->last_fence.request);
 		if (ret)
 			return ret;
 
-		i915_gem_request_assign(&obj->last_fenced_req, NULL);
+		i915_gem_request_assign(&obj->last_fence.request, NULL);
 	}
 
 	return 0;
diff --git a/drivers/gpu/drm/i915/i915_gem_request.h b/drivers/gpu/drm/i915/i915_gem_request.h
index f6955429499c..90b188545e26 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.h
+++ b/drivers/gpu/drm/i915/i915_gem_request.h
@@ -200,4 +200,15 @@ static inline bool i915_gem_request_completed(struct drm_i915_gem_request *req)
 				 req->fence.seqno);
 }
 
+struct drm_i915_gem_request_active {
+	struct drm_i915_gem_request *request;
+};
+
+static inline void
+i915_gem_request_mark_active(struct drm_i915_gem_request *request,
+			     struct drm_i915_gem_request_active *active)
+{
+	i915_gem_request_assign(&active->request, request);
+}
+
 #endif /* I915_GEM_REQUEST_H */
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index 7410f6c962e7..c7588135a82d 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -242,7 +242,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
 			}
 
 			obj->fence_dirty =
-				obj->last_fenced_req ||
+				obj->last_fence.request ||
 				obj->fence_reg != I915_FENCE_REG_NONE;
 
 			obj->tiling_mode = args->tiling_mode;
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 9b708fa304aa..82baa370ae09 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -708,8 +708,8 @@ static void capture_bo(struct drm_i915_error_buffer *err,
 	err->size = obj->base.size;
 	err->name = obj->base.name;
 	for (i = 0; i < I915_NUM_RINGS; i++)
-		err->rseqno[i] = i915_gem_request_get_seqno(obj->last_read_req[i]);
-	err->wseqno = i915_gem_request_get_seqno(obj->last_write_req);
+		err->rseqno[i] = i915_gem_request_get_seqno(obj->last_read[i].request);
+	err->wseqno = i915_gem_request_get_seqno(obj->last_write.request);
 	err->gtt_offset = vma->node.start;
 	err->read_domains = obj->base.read_domains;
 	err->write_domain = obj->base.write_domain;
@@ -721,7 +721,7 @@ static void capture_bo(struct drm_i915_error_buffer *err,
 	err->dirty = obj->dirty;
 	err->purgeable = obj->madv != I915_MADV_WILLNEED;
 	err->userptr = obj->userptr.mm != NULL;
-	err->ring = obj->last_write_req ?  obj->last_write_req->engine->id : -1;
+	err->ring = obj->last_write.request ? obj->last_write.request->engine->id : -1;
 	err->cache_level = obj->cache_level;
 }
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f6ec3b5d846d..db461b120299 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11246,7 +11246,7 @@ static bool use_mmio_flip(struct intel_engine_cs *ring,
 						       false))
 		return true;
 	else
-		return ring != i915_gem_request_get_engine(obj->last_write_req);
+		return ring != i915_gem_request_get_engine(obj->last_write.request);
 }
 
 static void skl_do_mmio_flip(struct intel_crtc *intel_crtc,
@@ -11391,7 +11391,7 @@ static int intel_queue_mmio_flip(struct drm_device *dev,
 		return -ENOMEM;
 
 	mmio_flip->i915 = to_i915(dev);
-	mmio_flip->req = i915_gem_request_reference(obj->last_write_req);
+	mmio_flip->req = i915_gem_request_reference(obj->last_write.request);
 	mmio_flip->crtc = to_intel_crtc(crtc);
 	mmio_flip->rotation = crtc->primary->state->rotation;
 
@@ -11590,7 +11590,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 	} else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) {
 		ring = &dev_priv->ring[BCS];
 	} else if (INTEL_INFO(dev)->gen >= 7) {
-		ring = i915_gem_request_get_engine(obj->last_write_req);
+		ring = i915_gem_request_get_engine(obj->last_write.request);
 		if (ring == NULL || ring->id != RCS)
 			ring = &dev_priv->ring[BCS];
 	} else {
@@ -11631,7 +11631,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 			goto cleanup_unpin;
 
 		i915_gem_request_assign(&work->flip_queued_req,
-					obj->last_write_req);
+					obj->last_write.request);
 	} else {
 		ret = dev_priv->display.queue_flip(dev, crtc, fb, obj, request,
 						   page_flip_flags);
@@ -13745,7 +13745,7 @@ intel_prepare_plane_fb(struct drm_plane *plane,
 				to_intel_plane_state(new_state);
 
 			i915_gem_request_assign(&plane_state->wait_req,
-						obj->last_write_req);
+						obj->last_write.request);
 		}
 
 		i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit);
-- 
2.6.4

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

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

* [PATCH 02/11] drm/i915: Refactor activity tracking for requests
  2015-12-14 11:36 [PATCH 01/11] drm/i915: Introduce drm_i915_gem_request_node for request tracking Chris Wilson
@ 2015-12-14 11:36 ` Chris Wilson
  2015-12-16 17:16   ` Tvrtko Ursulin
  2015-12-14 11:36 ` [PATCH 03/11] drm/i915: Rename vma->*_list to *_link for consistency Chris Wilson
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 37+ messages in thread
From: Chris Wilson @ 2015-12-14 11:36 UTC (permalink / raw)
  To: intel-gfx

With the introduction of requests, we amplified the number of atomic
refcounted objects we use and update every execbuffer; from none to
several references, and a set of references that need to be changed. We
also introduced interesting side-effects in the order of retiring
requests and objects.

Instead of independently tracking the last request for an object, track
the active objects for each request. The object will reside in the
buffer list of its most recent active request and so we reduce the kref
interchange to a list_move. Now retirements are entirely driven by the
request, dramatically simplifying activity tracking on the object
themselves, and removing the ambiguity between retiring objects and
retiring requests.

All told, less code, simpler and faster, and more extensible.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/Makefile           |   1 -
 drivers/gpu/drm/i915/i915_debugfs.c     |   4 +-
 drivers/gpu/drm/i915/i915_drv.h         |  10 ---
 drivers/gpu/drm/i915/i915_gem.c         | 149 ++++++++------------------------
 drivers/gpu/drm/i915/i915_gem_debug.c   |  70 ---------------
 drivers/gpu/drm/i915/i915_gem_fence.c   |  10 +--
 drivers/gpu/drm/i915/i915_gem_request.c |  39 ++++++---
 drivers/gpu/drm/i915/i915_gem_request.h |  26 +++++-
 drivers/gpu/drm/i915/i915_gpu_error.c   |   4 +-
 drivers/gpu/drm/i915/intel_lrc.c        |   1 -
 drivers/gpu/drm/i915/intel_ringbuffer.c |   7 +-
 drivers/gpu/drm/i915/intel_ringbuffer.h |  12 ---
 12 files changed, 93 insertions(+), 240 deletions(-)
 delete mode 100644 drivers/gpu/drm/i915/i915_gem_debug.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 3df88be4752e..14794370db44 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -21,7 +21,6 @@ i915-$(CONFIG_DEBUG_FS) += i915_debugfs.o
 i915-y += i915_cmd_parser.o \
 	  i915_gem_batch_pool.o \
 	  i915_gem_context.o \
-	  i915_gem_debug.o \
 	  i915_gem_dmabuf.o \
 	  i915_gem_evict.o \
 	  i915_gem_execbuffer.o \
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index dafc58b94c9f..68310ba73d23 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -695,13 +695,13 @@ static int i915_gem_request_info(struct seq_file *m, void *data)
 		int count;
 
 		count = 0;
-		list_for_each_entry(req, &ring->request_list, list)
+		list_for_each_entry(req, &ring->request_list, link)
 			count++;
 		if (count == 0)
 			continue;
 
 		seq_printf(m, "%s requests: %d\n", ring->name, count);
-		list_for_each_entry(req, &ring->request_list, list) {
+		list_for_each_entry(req, &ring->request_list, link) {
 			struct task_struct *task;
 
 			rcu_read_lock();
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 43de7c2c6b3e..dbcb7659ba2b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -444,8 +444,6 @@ void intel_link_compute_m_n(int bpp, int nlanes,
 #define DRIVER_MINOR		6
 #define DRIVER_PATCHLEVEL	0
 
-#define WATCH_LISTS	0
-
 struct opregion_header;
 struct opregion_acpi;
 struct opregion_swsci;
@@ -2014,7 +2012,6 @@ struct drm_i915_gem_object {
 	struct drm_mm_node *stolen;
 	struct list_head global_list;
 
-	struct list_head ring_list[I915_NUM_RINGS];
 	/** Used in execbuf to temporarily hold a ref */
 	struct list_head obj_exec_link;
 
@@ -3079,13 +3076,6 @@ static inline bool i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_objec
 		obj->tiling_mode != I915_TILING_NONE;
 }
 
-/* i915_gem_debug.c */
-#if WATCH_LISTS
-int i915_verify_lists(struct drm_device *dev);
-#else
-#define i915_verify_lists(dev) 0
-#endif
-
 /* i915_debugfs.c */
 int i915_debugfs_init(struct drm_minor *minor);
 void i915_debugfs_cleanup(struct drm_minor *minor);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index b412b9291d91..a7c39d5fbcca 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -38,14 +38,8 @@
 #include <linux/pci.h>
 #include <linux/dma-buf.h>
 
-#define RQ_BUG_ON(expr)
-
 static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj);
 static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj);
-static void
-i915_gem_object_retire__write(struct drm_i915_gem_object *obj);
-static void
-i915_gem_object_retire__read(struct drm_i915_gem_object *obj, int ring);
 
 static bool cpu_cache_is_coherent(struct drm_device *dev,
 				  enum i915_cache_level level)
@@ -119,7 +113,6 @@ int i915_mutex_lock_interruptible(struct drm_device *dev)
 	if (ret)
 		return ret;
 
-	WARN_ON(i915_verify_lists(dev));
 	return 0;
 }
 
@@ -1119,27 +1112,14 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
 		return 0;
 
 	if (readonly) {
-		if (obj->last_write.request != NULL) {
-			ret = i915_wait_request(obj->last_write.request);
-			if (ret)
-				return ret;
-
-			i = obj->last_write.request->engine->id;
-			if (obj->last_read[i].request == obj->last_write.request)
-				i915_gem_object_retire__read(obj, i);
-			else
-				i915_gem_object_retire__write(obj);
-		}
+		ret = i915_wait_request(obj->last_write.request);
+		if (ret)
+			return ret;
 	} else {
 		for (i = 0; i < I915_NUM_RINGS; i++) {
-			if (obj->last_read[i].request == NULL)
-				continue;
-
 			ret = i915_wait_request(obj->last_read[i].request);
 			if (ret)
 				return ret;
-
-			i915_gem_object_retire__read(obj, i);
 		}
 		RQ_BUG_ON(obj->active);
 	}
@@ -1147,20 +1127,6 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
 	return 0;
 }
 
-static void
-i915_gem_object_retire_request(struct drm_i915_gem_object *obj,
-			       struct drm_i915_gem_request *req)
-{
-	int ring = req->engine->id;
-
-	if (obj->last_read[ring].request == req)
-		i915_gem_object_retire__read(obj, ring);
-	else if (obj->last_write.request == req)
-		i915_gem_object_retire__write(obj);
-
-	i915_gem_request_retire__upto(req);
-}
-
 /* A nonblocking variant of the above wait. This is a highly dangerous routine
  * as the object state may change during this call.
  */
@@ -1208,7 +1174,7 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj,
 
 	for (i = 0; i < n; i++) {
 		if (ret == 0)
-			i915_gem_object_retire_request(obj, requests[i]);
+			i915_gem_request_retire__upto(requests[i]);
 		i915_gem_request_unreference(requests[i]);
 	}
 
@@ -2061,35 +2027,37 @@ void i915_vma_move_to_active(struct i915_vma *vma,
 		drm_gem_object_reference(&obj->base);
 	obj->active |= intel_engine_flag(engine);
 
-	list_move_tail(&obj->ring_list[engine->id], &engine->active_list);
 	i915_gem_request_mark_active(req, &obj->last_read[engine->id]);
-
 	list_move_tail(&vma->mm_list, &vma->vm->active_list);
 }
 
 static void
-i915_gem_object_retire__write(struct drm_i915_gem_object *obj)
+i915_gem_object_retire__fence(struct drm_i915_gem_request_active *active,
+			      struct drm_i915_gem_request *req)
 {
-	RQ_BUG_ON(obj->last_write.request == NULL);
-	RQ_BUG_ON(!(obj->active & intel_engine_flag(obj->last_write.request->engine)));
+}
 
-	i915_gem_request_assign(&obj->last_write.request, NULL);
-	intel_fb_obj_flush(obj, true, ORIGIN_CS);
+static void
+i915_gem_object_retire__write(struct drm_i915_gem_request_active *active,
+			      struct drm_i915_gem_request *request)
+{
+	intel_fb_obj_flush(container_of(active,
+					struct drm_i915_gem_object,
+					last_write),
+			   true,
+			   ORIGIN_CS);
 }
 
 static void
-i915_gem_object_retire__read(struct drm_i915_gem_object *obj, int ring)
+i915_gem_object_retire__read(struct drm_i915_gem_request_active *active,
+			     struct drm_i915_gem_request *request)
 {
+	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;
 
-	RQ_BUG_ON(obj->last_read[ring].request == NULL);
-	RQ_BUG_ON(!(obj->active & (1 << ring)));
-
-	list_del_init(&obj->ring_list[ring]);
-	i915_gem_request_assign(&obj->last_read[ring].request, NULL);
-
-	if (obj->last_write.request && obj->last_write.request->engine->id == ring)
-		i915_gem_object_retire__write(obj);
+	RQ_BUG_ON((obj->flags & (1 << (ring + I915_BO_ACTIVE_SHIFT))) == 0);
 
 	obj->active &= ~(1 << ring);
 	if (obj->active)
@@ -2099,15 +2067,13 @@ i915_gem_object_retire__read(struct drm_i915_gem_object *obj, int ring)
 	 * so that we don't steal from recently used but inactive objects
 	 * (unless we are forced to ofc!)
 	 */
-	list_move_tail(&obj->global_list,
-		       &to_i915(obj->base.dev)->mm.bound_list);
+	list_move_tail(&obj->global_list, &request->i915->mm.bound_list);
 
 	list_for_each_entry(vma, &obj->vma_list, vma_link) {
 		if (!list_empty(&vma->mm_list))
 			list_move_tail(&vma->mm_list, &vma->vm->inactive_list);
 	}
 
-	i915_gem_request_assign(&obj->last_fence.request, NULL);
 	drm_gem_object_unreference(&obj->base);
 }
 
@@ -2179,7 +2145,7 @@ i915_gem_find_active_request(struct intel_engine_cs *ring)
 	if (ring->seqno_barrier)
 		ring->seqno_barrier(ring);
 
-	list_for_each_entry(request, &ring->request_list, list) {
+	list_for_each_entry(request, &ring->request_list, link) {
 		if (i915_gem_request_completed(request))
 			continue;
 
@@ -2204,7 +2170,7 @@ static void i915_gem_reset_ring_status(struct intel_engine_cs *ring)
 
 	i915_set_reset_status(dev_priv, request->ctx, ring_hung);
 
-	list_for_each_entry_continue(request, &ring->request_list, list)
+	list_for_each_entry_continue(request, &ring->request_list, link)
 		i915_set_reset_status(dev_priv, request->ctx, false);
 }
 
@@ -2212,16 +2178,6 @@ static void i915_gem_reset_ring_cleanup(struct intel_engine_cs *engine)
 {
 	struct intel_ring *ring;
 
-	while (!list_empty(&engine->active_list)) {
-		struct drm_i915_gem_object *obj;
-
-		obj = list_first_entry(&engine->active_list,
-				       struct drm_i915_gem_object,
-				       ring_list[engine->id]);
-
-		i915_gem_object_retire__read(obj, engine->id);
-	}
-
 	/*
 	 * Clear the execlists queue up before freeing the requests, as those
 	 * are the ones that keep the context and ringbuffer backing objects
@@ -2258,7 +2214,7 @@ static void i915_gem_reset_ring_cleanup(struct intel_engine_cs *engine)
 
 		request = list_last_entry(&engine->request_list,
 					  struct drm_i915_gem_request,
-					  list);
+					  link);
 
 		i915_gem_request_retire__upto(request);
 	}
@@ -2298,8 +2254,6 @@ void i915_gem_reset(struct drm_device *dev)
 	i915_gem_context_reset(dev);
 
 	i915_gem_restore_fences(dev);
-
-	WARN_ON(i915_verify_lists(dev));
 }
 
 /**
@@ -2308,8 +2262,6 @@ void i915_gem_reset(struct drm_device *dev)
 void
 i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
 {
-	WARN_ON(i915_verify_lists(ring->dev));
-
 	/* Retire requests first as we use it above for the early return.
 	 * If we retire requests last, we may use a later seqno and so clear
 	 * the requests lists without clearing the active list, leading to
@@ -2320,32 +2272,13 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
 
 		request = list_first_entry(&ring->request_list,
 					   struct drm_i915_gem_request,
-					   list);
+					   link);
 
 		if (!i915_gem_request_completed(request))
 			break;
 
 		i915_gem_request_retire__upto(request);
 	}
-
-	/* Move any buffers on the active list that are no longer referenced
-	 * by the ringbuffer to the flushing/inactive lists as appropriate,
-	 * before we free the context associated with the requests.
-	 */
-	while (!list_empty(&ring->active_list)) {
-		struct drm_i915_gem_object *obj;
-
-		obj = list_first_entry(&ring->active_list,
-				      struct drm_i915_gem_object,
-				      ring_list[ring->id]);
-
-		if (!list_empty(&obj->last_read[ring->id].request->list))
-			break;
-
-		i915_gem_object_retire__read(obj, ring->id);
-	}
-
-	WARN_ON(i915_verify_lists(ring->dev));
 }
 
 void
@@ -2446,14 +2379,8 @@ i915_gem_object_flush_active(struct drm_i915_gem_object *obj)
 		if (req == NULL)
 			continue;
 
-		if (list_empty(&req->list))
-			goto retire;
-
-		if (i915_gem_request_completed(req)) {
+		if (i915_gem_request_completed(req))
 			i915_gem_request_retire__upto(req);
-retire:
-			i915_gem_object_retire__read(obj, i);
-		}
 	}
 
 	return 0;
@@ -2519,8 +2446,6 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
 		goto out;
 	}
 
-	drm_gem_object_unreference(&obj->base);
-
 	for (i = 0; i < I915_NUM_RINGS; i++) {
 		if (obj->last_read[i].request == NULL)
 			continue;
@@ -2528,6 +2453,8 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
 		req[n++] = i915_gem_request_reference(obj->last_read[i].request);
 	}
 
+out:
+	drm_gem_object_unreference(&obj->base);
 	mutex_unlock(&dev->struct_mutex);
 
 	for (i = 0; i < n; i++) {
@@ -2538,11 +2465,6 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
 		i915_gem_request_unreference(req[i]);
 	}
 	return ret;
-
-out:
-	drm_gem_object_unreference(&obj->base);
-	mutex_unlock(&dev->struct_mutex);
-	return ret;
 }
 
 static int
@@ -2566,7 +2488,7 @@ __i915_gem_object_sync(struct drm_i915_gem_object *obj,
 		if (ret)
 			return ret;
 
-		i915_gem_object_retire_request(obj, from);
+		i915_gem_request_retire__upto(from);
 	} else {
 		int idx = intel_engine_sync_index(from->engine, to->engine);
 		if (from->fence.seqno <= from->engine->semaphore.sync_seqno[idx])
@@ -2763,7 +2685,6 @@ int i915_gpu_idle(struct drm_device *dev)
 			return ret;
 	}
 
-	WARN_ON(i915_verify_lists(dev));
 	return 0;
 }
 
@@ -3774,7 +3695,12 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
 
 	INIT_LIST_HEAD(&obj->global_list);
 	for (i = 0; i < I915_NUM_RINGS; i++)
-		INIT_LIST_HEAD(&obj->ring_list[i]);
+		init_request_active(&obj->last_read[i],
+				    i915_gem_object_retire__read);
+	init_request_active(&obj->last_write,
+			    i915_gem_object_retire__write);
+	init_request_active(&obj->last_fence,
+			    i915_gem_object_retire__fence);
 	INIT_LIST_HEAD(&obj->obj_exec_link);
 	INIT_LIST_HEAD(&obj->vma_list);
 	INIT_LIST_HEAD(&obj->batch_pool_link);
@@ -4341,7 +4267,6 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev)
 static void
 init_ring_lists(struct intel_engine_cs *ring)
 {
-	INIT_LIST_HEAD(&ring->active_list);
 	INIT_LIST_HEAD(&ring->request_list);
 }
 
diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c
deleted file mode 100644
index 17299d04189f..000000000000
--- a/drivers/gpu/drm/i915/i915_gem_debug.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright © 2008 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- * Authors:
- *    Keith Packard <keithp@keithp.com>
- *
- */
-
-#include <drm/drmP.h>
-#include <drm/i915_drm.h>
-#include "i915_drv.h"
-
-#if WATCH_LISTS
-int
-i915_verify_lists(struct drm_device *dev)
-{
-	static int warned;
-	struct drm_i915_private *dev_priv = to_i915(dev);
-	struct drm_i915_gem_object *obj;
-	struct intel_engine_cs *ring;
-	int err = 0;
-	int i;
-
-	if (warned)
-		return 0;
-
-	for_each_ring(ring, dev_priv, i) {
-		list_for_each_entry(obj, &ring->active_list, ring_list[ring->id]) {
-			if (obj->base.dev != dev ||
-			    !atomic_read(&obj->base.refcount.refcount)) {
-				DRM_ERROR("%s: freed active obj %p\n",
-					  ring->name, obj);
-				err++;
-				break;
-			} else if (!obj->active ||
-				   obj->last_read_req[ring->id] == NULL) {
-				DRM_ERROR("%s: invalid active obj %p\n",
-					  ring->name, obj);
-				err++;
-			} else if (obj->base.write_domain) {
-				DRM_ERROR("%s: invalid write obj %p (w %x)\n",
-					  ring->name,
-					  obj, obj->base.write_domain);
-				err++;
-			}
-		}
-	}
-
-	return warned = err;
-}
-#endif /* WATCH_LIST */
diff --git a/drivers/gpu/drm/i915/i915_gem_fence.c b/drivers/gpu/drm/i915/i915_gem_fence.c
index ab29c237ffa9..ff085efcf0e5 100644
--- a/drivers/gpu/drm/i915/i915_gem_fence.c
+++ b/drivers/gpu/drm/i915/i915_gem_fence.c
@@ -261,15 +261,7 @@ static inline void i915_gem_object_fence_lost(struct drm_i915_gem_object *obj)
 static int
 i915_gem_object_wait_fence(struct drm_i915_gem_object *obj)
 {
-	if (obj->last_fence.request) {
-		int ret = i915_wait_request(obj->last_fence.request);
-		if (ret)
-			return ret;
-
-		i915_gem_request_assign(&obj->last_fence.request, NULL);
-	}
-
-	return 0;
+	return i915_wait_request(obj->last_fence.request);
 }
 
 /**
diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index 79c15cdb776b..95b7a993579d 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -236,7 +236,7 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
 		   engine->fence_context,
 		   seqno);
 
-	INIT_LIST_HEAD(&req->list);
+	INIT_LIST_HEAD(&req->active_list);
 	req->i915 = dev_priv;
 	req->engine = engine;
 	req->reset_counter = reset_counter;
@@ -323,7 +323,7 @@ i915_gem_request_remove_from_client(struct drm_i915_gem_request *request)
 
 static void __i915_gem_request_release(struct drm_i915_gem_request *request)
 {
-	list_del_init(&request->list);
+	list_del_init(&request->link);
 
 	i915_gem_request_remove_from_client(request);
 
@@ -343,6 +343,8 @@ void i915_gem_request_cancel(struct drm_i915_gem_request *req)
 
 static void i915_gem_request_retire(struct drm_i915_gem_request *request)
 {
+	struct drm_i915_gem_request_active *node, *next;
+
 	trace_i915_gem_request_retire(request);
 
 	/* We know the GPU must have read the request to have
@@ -354,6 +356,21 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request)
 	 * completion order.
 	 */
 	request->ring->last_retired_head = request->postfix;
+
+	/* Move any buffers on the active list that are no longer referenced
+	 * by the ringbuffer to the flushing/inactive lists as appropriate,
+	 * before we free the context associated with the requests.
+	 */
+	list_for_each_entry_safe(node, next, &request->active_list, link) {
+		/* node->retire() may free the node, so decouple it first
+		 * and pass along the auxiliary information.
+		 */
+		INIT_LIST_HEAD(&node->link);
+		node->request = NULL;
+
+		node->retire(node, request);
+	}
+
 	__i915_gem_request_release(request);
 }
 
@@ -364,18 +381,15 @@ i915_gem_request_retire__upto(struct drm_i915_gem_request *req)
 	struct drm_i915_gem_request *tmp;
 
 	lockdep_assert_held(&engine->dev->struct_mutex);
-
-	if (list_empty(&req->list))
+	if (list_empty(&req->link))
 		return;
 
 	do {
 		tmp = list_first_entry(&engine->request_list,
-				       typeof(*tmp), list);
+				       typeof(*tmp), link);
 
 		i915_gem_request_retire(tmp);
 	} while (tmp != req);
-
-	WARN_ON(i915_verify_lists(engine->dev));
 }
 
 static void i915_gem_mark_busy(struct drm_i915_private *dev_priv)
@@ -467,7 +481,7 @@ void __i915_add_request(struct drm_i915_gem_request *request,
 	request->emitted_jiffies = jiffies;
 	request->previous_seqno = request->engine->last_submitted_seqno;
 	request->engine->last_submitted_seqno = request->fence.seqno;
-	list_add_tail(&request->list, &request->engine->request_list);
+	list_add_tail(&request->link, &request->engine->request_list);
 
 	trace_i915_gem_request_add(request);
 
@@ -581,9 +595,6 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
 
 	might_sleep();
 
-	if (list_empty(&req->list))
-		return 0;
-
 	if (i915_gem_request_completed(req))
 		return 0;
 
@@ -740,10 +751,10 @@ i915_wait_request(struct drm_i915_gem_request *req)
 {
 	int ret;
 
-	BUG_ON(req == NULL);
-
-	BUG_ON(!mutex_is_locked(&req->i915->dev->struct_mutex));
+	if (req == NULL)
+		return 0;
 
+	lockdep_assert_held(&req->i915->dev->struct_mutex);
 	ret = __i915_wait_request(req, req->i915->mm.interruptible, NULL, NULL);
 	if (ret)
 		return ret;
diff --git a/drivers/gpu/drm/i915/i915_gem_request.h b/drivers/gpu/drm/i915/i915_gem_request.h
index 90b188545e26..fa785ce43534 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.h
+++ b/drivers/gpu/drm/i915/i915_gem_request.h
@@ -84,12 +84,13 @@ struct drm_i915_gem_request {
 	/** Batch buffer related to this request if any (used for
 	    error state dump only) */
 	struct drm_i915_gem_object *batch_obj;
+	struct list_head active_list;
 
 	/** Time at which this request was emitted, in jiffies. */
 	unsigned long emitted_jiffies;
 
-	/** global list entry for this request */
-	struct list_head list;
+	/** engine->request_list entry for this request */
+	struct list_head link;
 
 	struct drm_i915_file_private *file_priv;
 	/** file_priv list entry for this request */
@@ -118,9 +119,16 @@ struct drm_i915_gem_request {
 	int elsp_submitted;
 };
 
+#if 0
+#define RQ_BUG_ON(expr) BUG_ON(expr)
+#else
+#define RQ_BUG_ON(expr)
+#endif
+
 struct drm_i915_gem_request *
 i915_gem_request_alloc(struct intel_engine_cs *ring,
 		       struct intel_context *ctx);
+
 void i915_gem_request_cancel(struct drm_i915_gem_request *req);
 int i915_gem_request_add_to_client(struct drm_i915_gem_request *req,
 				   struct drm_file *file);
@@ -202,13 +210,25 @@ static inline bool i915_gem_request_completed(struct drm_i915_gem_request *req)
 
 struct drm_i915_gem_request_active {
 	struct drm_i915_gem_request *request;
+	struct list_head link;
+	void (*retire)(struct drm_i915_gem_request_active *,
+		       struct drm_i915_gem_request *);
 };
 
+inline static void init_request_active(struct drm_i915_gem_request_active *active,
+				       void (*func)(struct drm_i915_gem_request_active *,
+						    struct drm_i915_gem_request *))
+{
+	INIT_LIST_HEAD(&active->link);
+	active->retire = func;
+}
+
 static inline void
 i915_gem_request_mark_active(struct drm_i915_gem_request *request,
 			     struct drm_i915_gem_request_active *active)
 {
-	i915_gem_request_assign(&active->request, request);
+	active->request = request;
+	list_move(&active->link, &request->active_list);
 }
 
 #endif /* I915_GEM_REQUEST_H */
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 82baa370ae09..d27c07982c89 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -1058,7 +1058,7 @@ static void i915_gem_record_rings(struct drm_device *dev,
 		i915_gem_record_active_context(engine, error, &error->ring[i]);
 
 		count = 0;
-		list_for_each_entry(request, &engine->request_list, list)
+		list_for_each_entry(request, &engine->request_list, link)
 			count++;
 
 		error->ring[i].num_requests = count;
@@ -1071,7 +1071,7 @@ static void i915_gem_record_rings(struct drm_device *dev,
 		}
 
 		count = 0;
-		list_for_each_entry(request, &engine->request_list, list) {
+		list_for_each_entry(request, &engine->request_list, link) {
 			struct drm_i915_error_request *erq;
 
 			if (count >= error->ring[i].num_requests) {
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 3c1d96b83491..db7061fac0db 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -1527,7 +1527,6 @@ static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *rin
 	ring->dev = dev;
 	ring->i915 = to_i915(dev);
 	ring->fence_context = fence_context_alloc(1);
-	INIT_LIST_HEAD(&ring->active_list);
 	INIT_LIST_HEAD(&ring->request_list);
 	i915_gem_batch_pool_init(dev, &ring->batch_pool);
 	intel_engine_init_breadcrumbs(ring);
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 3c0c97e0dff5..83641dc0125a 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1976,7 +1976,6 @@ static int intel_init_engine(struct drm_device *dev,
 	engine->dev = dev;
 	engine->i915 = to_i915(dev);
 	engine->fence_context = fence_context_alloc(1);
-	INIT_LIST_HEAD(&engine->active_list);
 	INIT_LIST_HEAD(&engine->request_list);
 	INIT_LIST_HEAD(&engine->execlist_queue);
 	INIT_LIST_HEAD(&engine->buffers);
@@ -2060,7 +2059,7 @@ int intel_engine_idle(struct intel_engine_cs *ring)
 
 	req = list_entry(ring->request_list.prev,
 			struct drm_i915_gem_request,
-			list);
+			link);
 
 	/* Make sure we do not trigger any retires */
 	return __i915_wait_request(req,
@@ -2135,7 +2134,7 @@ static int wait_for_space(struct drm_i915_gem_request *req, int bytes)
 	/* The whole point of reserving space is to not wait! */
 	WARN_ON(ring->reserved_in_use);
 
-	list_for_each_entry(target, &engine->request_list, list) {
+	list_for_each_entry(target, &engine->request_list, link) {
 		/*
 		 * The request queue is per-engine, so can contain requests
 		 * from multiple ringbuffers. Here, we must ignore any that
@@ -2151,7 +2150,7 @@ static int wait_for_space(struct drm_i915_gem_request *req, int bytes)
 			break;
 	}
 
-	if (WARN_ON(&target->list == &engine->request_list))
+	if (WARN_ON(&target->link == &engine->request_list))
 		return -ENOSPC;
 
 	ret = i915_wait_request(target);
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 004054bf85a7..968c1db71da0 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -299,18 +299,6 @@ struct intel_engine_cs {
 #define I915_DISPATCH_RS     0x4
 
 	/**
-	 * List of objects currently involved in rendering from the
-	 * ringbuffer.
-	 *
-	 * Includes buffers having the contents of their GPU caches
-	 * flushed, not necessarily primitives.  last_read_req
-	 * represents when the rendering involved will be completed.
-	 *
-	 * A reference is held on the buffer while on this list.
-	 */
-	struct list_head active_list;
-
-	/**
 	 * List of breadcrumbs associated with GPU requests currently
 	 * outstanding.
 	 */
-- 
2.6.4

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

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

* [PATCH 03/11] drm/i915: Rename vma->*_list to *_link for consistency
  2015-12-14 11:36 [PATCH 01/11] drm/i915: Introduce drm_i915_gem_request_node for request tracking Chris Wilson
  2015-12-14 11:36 ` [PATCH 02/11] drm/i915: Refactor activity tracking for requests Chris Wilson
@ 2015-12-14 11:36 ` Chris Wilson
  2015-12-17 11:14   ` Tvrtko Ursulin
  2015-12-14 11:36 ` [PATCH 04/11] drm/i915: Amalgamate GGTT/ppGTT vma debug list walkers Chris Wilson
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 37+ messages in thread
From: Chris Wilson @ 2015-12-14 11:36 UTC (permalink / raw)
  To: intel-gfx

Elsewhere we have adopted the convention of using '_link' to denote
elements in the list (and '_list' for the actual list_head itself), and
that the name should indicate which list the link belongs to (and
preferrably not just where the link is being stored).

s/vma_link/obj_link/ (we iterate over obj->vma_list)
s/mm_list/vm_link/ (we iterate over vm->[in]active_list)

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_debugfs.c      | 17 +++++------
 drivers/gpu/drm/i915/i915_gem.c          | 50 ++++++++++++++++----------------
 drivers/gpu/drm/i915/i915_gem_context.c  |  2 +-
 drivers/gpu/drm/i915/i915_gem_evict.c    |  6 ++--
 drivers/gpu/drm/i915/i915_gem_gtt.c      | 10 +++----
 drivers/gpu/drm/i915/i915_gem_gtt.h      |  4 +--
 drivers/gpu/drm/i915/i915_gem_shrinker.c |  4 +--
 drivers/gpu/drm/i915/i915_gem_stolen.c   |  2 +-
 drivers/gpu/drm/i915/i915_gem_userptr.c  |  2 +-
 drivers/gpu/drm/i915/i915_gpu_error.c    |  8 ++---
 10 files changed, 52 insertions(+), 53 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 68310ba73d23..fdcf90757eb0 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -117,9 +117,8 @@ static u64 i915_gem_obj_total_ggtt_size(struct drm_i915_gem_object *obj)
 	u64 size = 0;
 	struct i915_vma *vma;
 
-	list_for_each_entry(vma, &obj->vma_list, vma_link) {
-		if (i915_is_ggtt(vma->vm) &&
-		    drm_mm_node_allocated(&vma->node))
+	list_for_each_entry(vma, &obj->vma_list, obj_link) {
+		if (i915_is_ggtt(vma->vm) && drm_mm_node_allocated(&vma->node))
 			size += vma->node.size;
 	}
 
@@ -155,7 +154,7 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
 		   obj->madv == I915_MADV_DONTNEED ? " purgeable" : "");
 	if (obj->base.name)
 		seq_printf(m, " (name: %d)", obj->base.name);
-	list_for_each_entry(vma, &obj->vma_list, vma_link) {
+	list_for_each_entry(vma, &obj->vma_list, obj_link) {
 		if (vma->pin_count > 0)
 			pin_count++;
 	}
@@ -164,7 +163,7 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
 		seq_printf(m, " (display)");
 	if (obj->fence_reg != I915_FENCE_REG_NONE)
 		seq_printf(m, " (fence: %d)", obj->fence_reg);
-	list_for_each_entry(vma, &obj->vma_list, vma_link) {
+	list_for_each_entry(vma, &obj->vma_list, obj_link) {
 		seq_printf(m, " (%sgtt offset: %08llx, size: %08llx",
 			   i915_is_ggtt(vma->vm) ? "g" : "pp",
 			   vma->node.start, vma->node.size);
@@ -229,7 +228,7 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data)
 	}
 
 	total_obj_size = total_gtt_size = count = 0;
-	list_for_each_entry(vma, head, mm_list) {
+	list_for_each_entry(vma, head, vm_link) {
 		seq_printf(m, "   ");
 		describe_obj(m, vma->obj);
 		seq_printf(m, "\n");
@@ -341,7 +340,7 @@ static int per_file_stats(int id, void *ptr, void *data)
 		stats->shared += obj->base.size;
 
 	if (USES_FULL_PPGTT(obj->base.dev)) {
-		list_for_each_entry(vma, &obj->vma_list, vma_link) {
+		list_for_each_entry(vma, &obj->vma_list, obj_link) {
 			struct i915_hw_ppgtt *ppgtt;
 
 			if (!drm_mm_node_allocated(&vma->node))
@@ -453,12 +452,12 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
 		   count, mappable_count, size, mappable_size);
 
 	size = count = mappable_size = mappable_count = 0;
-	count_vmas(&vm->active_list, mm_list);
+	count_vmas(&vm->active_list, vm_link);
 	seq_printf(m, "  %u [%u] active objects, %llu [%llu] bytes\n",
 		   count, mappable_count, size, mappable_size);
 
 	size = count = mappable_size = mappable_count = 0;
-	count_vmas(&vm->inactive_list, mm_list);
+	count_vmas(&vm->inactive_list, vm_link);
 	seq_printf(m, "  %u [%u] inactive objects, %llu [%llu] bytes\n",
 		   count, mappable_count, size, mappable_size);
 
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index a7c39d5fbcca..e6ace74616b2 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -128,10 +128,10 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
 
 	pinned = 0;
 	mutex_lock(&dev->struct_mutex);
-	list_for_each_entry(vma, &ggtt->base.active_list, mm_list)
+	list_for_each_entry(vma, &ggtt->base.active_list, vm_link)
 		if (vma->pin_count)
 			pinned += vma->node.size;
-	list_for_each_entry(vma, &ggtt->base.inactive_list, mm_list)
+	list_for_each_entry(vma, &ggtt->base.inactive_list, vm_link)
 		if (vma->pin_count)
 			pinned += vma->node.size;
 	mutex_unlock(&dev->struct_mutex);
@@ -261,7 +261,7 @@ drop_pages(struct drm_i915_gem_object *obj)
 	int ret;
 
 	drm_gem_object_reference(&obj->base);
-	list_for_each_entry_safe(vma, next, &obj->vma_list, vma_link)
+	list_for_each_entry_safe(vma, next, &obj->vma_list, obj_link)
 		if (i915_vma_unbind(vma))
 			break;
 
@@ -2028,7 +2028,7 @@ void i915_vma_move_to_active(struct i915_vma *vma,
 	obj->active |= intel_engine_flag(engine);
 
 	i915_gem_request_mark_active(req, &obj->last_read[engine->id]);
-	list_move_tail(&vma->mm_list, &vma->vm->active_list);
+	list_move_tail(&vma->vm_link, &vma->vm->active_list);
 }
 
 static void
@@ -2069,9 +2069,9 @@ i915_gem_object_retire__read(struct drm_i915_gem_request_active *active,
 	 */
 	list_move_tail(&obj->global_list, &request->i915->mm.bound_list);
 
-	list_for_each_entry(vma, &obj->vma_list, vma_link) {
-		if (!list_empty(&vma->mm_list))
-			list_move_tail(&vma->mm_list, &vma->vm->inactive_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);
 	}
 
 	drm_gem_object_unreference(&obj->base);
@@ -2584,7 +2584,7 @@ static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
 	struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
 	int ret;
 
-	if (list_empty(&vma->vma_link))
+	if (list_empty(&vma->obj_link))
 		return 0;
 
 	if (!drm_mm_node_allocated(&vma->node)) {
@@ -2618,7 +2618,7 @@ static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
 	vma->vm->unbind_vma(vma);
 	vma->bound = 0;
 
-	list_del_init(&vma->mm_list);
+	list_del_init(&vma->vm_link);
 	if (i915_is_ggtt(vma->vm)) {
 		if (vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) {
 			obj->map_and_fenceable = false;
@@ -2875,7 +2875,7 @@ search_free:
 		goto err_remove_node;
 
 	list_move_tail(&obj->global_list, &dev_priv->mm.bound_list);
-	list_add_tail(&vma->mm_list, &vm->inactive_list);
+	list_add_tail(&vma->vm_link, &vm->inactive_list);
 
 	return vma;
 
@@ -3040,7 +3040,7 @@ 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->mm_list,
+		list_move_tail(&vma->vm_link,
 			       &to_i915(obj->base.dev)->gtt.base.inactive_list);
 
 	return 0;
@@ -3075,7 +3075,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
 	 * catch the issue of the CS prefetch crossing page boundaries and
 	 * reading an invalid PTE on older architectures.
 	 */
-	list_for_each_entry_safe(vma, next, &obj->vma_list, vma_link) {
+	list_for_each_entry_safe(vma, next, &obj->vma_list, obj_link) {
 		if (!drm_mm_node_allocated(&vma->node))
 			continue;
 
@@ -3138,7 +3138,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
 			 */
 		}
 
-		list_for_each_entry(vma, &obj->vma_list, vma_link) {
+		list_for_each_entry(vma, &obj->vma_list, obj_link) {
 			if (!drm_mm_node_allocated(&vma->node))
 				continue;
 
@@ -3148,7 +3148,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
 		}
 	}
 
-	list_for_each_entry(vma, &obj->vma_list, vma_link)
+	list_for_each_entry(vma, &obj->vma_list, obj_link)
 		vma->node.color = cache_level;
 	obj->cache_level = cache_level;
 
@@ -3806,7 +3806,7 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
 
 	trace_i915_gem_object_destroy(obj);
 
-	list_for_each_entry_safe(vma, next, &obj->vma_list, vma_link) {
+	list_for_each_entry_safe(vma, next, &obj->vma_list, obj_link) {
 		int ret;
 
 		vma->pin_count = 0;
@@ -3863,7 +3863,7 @@ struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj,
 				     struct i915_address_space *vm)
 {
 	struct i915_vma *vma;
-	list_for_each_entry(vma, &obj->vma_list, vma_link) {
+	list_for_each_entry(vma, &obj->vma_list, obj_link) {
 		if (vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL &&
 		    vma->vm == vm)
 			return vma;
@@ -3880,7 +3880,7 @@ struct i915_vma *i915_gem_obj_to_ggtt_view(struct drm_i915_gem_object *obj,
 	if (WARN_ONCE(!view, "no view specified"))
 		return ERR_PTR(-EINVAL);
 
-	list_for_each_entry(vma, &obj->vma_list, vma_link)
+	list_for_each_entry(vma, &obj->vma_list, obj_link)
 		if (vma->vm == ggtt &&
 		    i915_ggtt_view_equal(&vma->ggtt_view, view))
 			return vma;
@@ -3901,7 +3901,7 @@ void i915_gem_vma_destroy(struct i915_vma *vma)
 	if (!i915_is_ggtt(vm))
 		i915_ppgtt_put(i915_vm_to_ppgtt(vm));
 
-	list_del(&vma->vma_link);
+	list_del(&vma->obj_link);
 
 	kmem_cache_free(to_i915(vma->obj->base.dev)->vmas, vma);
 }
@@ -4424,7 +4424,7 @@ u64 i915_gem_obj_offset(struct drm_i915_gem_object *o,
 
 	WARN_ON(vm == &dev_priv->mm.aliasing_ppgtt->base);
 
-	list_for_each_entry(vma, &o->vma_list, vma_link) {
+	list_for_each_entry(vma, &o->vma_list, obj_link) {
 		if (i915_is_ggtt(vma->vm) &&
 		    vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
 			continue;
@@ -4443,7 +4443,7 @@ u64 i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o,
 	struct i915_address_space *ggtt = i915_obj_to_ggtt(o);
 	struct i915_vma *vma;
 
-	list_for_each_entry(vma, &o->vma_list, vma_link)
+	list_for_each_entry(vma, &o->vma_list, obj_link)
 		if (vma->vm == ggtt &&
 		    i915_ggtt_view_equal(&vma->ggtt_view, view))
 			return vma->node.start;
@@ -4457,7 +4457,7 @@ bool i915_gem_obj_bound(struct drm_i915_gem_object *o,
 {
 	struct i915_vma *vma;
 
-	list_for_each_entry(vma, &o->vma_list, vma_link) {
+	list_for_each_entry(vma, &o->vma_list, obj_link) {
 		if (i915_is_ggtt(vma->vm) &&
 		    vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
 			continue;
@@ -4474,7 +4474,7 @@ bool i915_gem_obj_ggtt_bound_view(struct drm_i915_gem_object *o,
 	struct i915_address_space *ggtt = i915_obj_to_ggtt(o);
 	struct i915_vma *vma;
 
-	list_for_each_entry(vma, &o->vma_list, vma_link)
+	list_for_each_entry(vma, &o->vma_list, obj_link)
 		if (vma->vm == ggtt &&
 		    i915_ggtt_view_equal(&vma->ggtt_view, view) &&
 		    drm_mm_node_allocated(&vma->node))
@@ -4487,7 +4487,7 @@ bool i915_gem_obj_bound_any(struct drm_i915_gem_object *o)
 {
 	struct i915_vma *vma;
 
-	list_for_each_entry(vma, &o->vma_list, vma_link)
+	list_for_each_entry(vma, &o->vma_list, obj_link)
 		if (drm_mm_node_allocated(&vma->node))
 			return true;
 
@@ -4504,7 +4504,7 @@ unsigned long i915_gem_obj_size(struct drm_i915_gem_object *o,
 
 	BUG_ON(list_empty(&o->vma_list));
 
-	list_for_each_entry(vma, &o->vma_list, vma_link) {
+	list_for_each_entry(vma, &o->vma_list, obj_link) {
 		if (i915_is_ggtt(vma->vm) &&
 		    vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
 			continue;
@@ -4517,7 +4517,7 @@ unsigned long i915_gem_obj_size(struct drm_i915_gem_object *o,
 bool i915_gem_obj_is_pinned(struct drm_i915_gem_object *obj)
 {
 	struct i915_vma *vma;
-	list_for_each_entry(vma, &obj->vma_list, vma_link)
+	list_for_each_entry(vma, &obj->vma_list, obj_link)
 		if (vma->pin_count > 0)
 			return true;
 
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 1a30452ec5fb..25a8498f0b5a 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -142,7 +142,7 @@ static void i915_gem_context_clean(struct intel_context *ctx)
 		return;
 
 	list_for_each_entry_safe(vma, next, &ppgtt->base.inactive_list,
-				 mm_list) {
+				 vm_link) {
 		if (WARN_ON(__i915_vma_unbind_no_wait(vma)))
 			break;
 	}
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
index 07c6e4d320c9..ea1f8d1bd228 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -116,7 +116,7 @@ i915_gem_evict_something(struct drm_device *dev, struct i915_address_space *vm,
 
 search_again:
 	/* First see if there is a large enough contiguous idle region... */
-	list_for_each_entry(vma, &vm->inactive_list, mm_list) {
+	list_for_each_entry(vma, &vm->inactive_list, vm_link) {
 		if (mark_free(vma, &unwind_list))
 			goto found;
 	}
@@ -125,7 +125,7 @@ search_again:
 		goto none;
 
 	/* Now merge in the soon-to-be-expired objects... */
-	list_for_each_entry(vma, &vm->active_list, mm_list) {
+	list_for_each_entry(vma, &vm->active_list, vm_link) {
 		if (mark_free(vma, &unwind_list))
 			goto found;
 	}
@@ -270,7 +270,7 @@ int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle)
 		WARN_ON(!list_empty(&vm->active_list));
 	}
 
-	list_for_each_entry_safe(vma, next, &vm->inactive_list, mm_list)
+	list_for_each_entry_safe(vma, next, &vm->inactive_list, vm_link)
 		if (vma->pin_count == 0)
 			WARN_ON(i915_vma_unbind(vma));
 
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index cc4d54b4043e..25bcea3e6ab6 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2696,7 +2696,7 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
 			return ret;
 		}
 		vma->bound |= GLOBAL_BIND;
-		list_add_tail(&vma->mm_list, &ggtt_vm->inactive_list);
+		list_add_tail(&vma->vm_link, &ggtt_vm->inactive_list);
 	}
 
 	/* Clear any non-preallocated blocks */
@@ -3181,7 +3181,7 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev)
 	vm = &dev_priv->gtt.base;
 	list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
 		flush = false;
-		list_for_each_entry(vma, &obj->vma_list, vma_link) {
+		list_for_each_entry(vma, &obj->vma_list, obj_link) {
 			if (vma->vm != vm)
 				continue;
 
@@ -3237,8 +3237,8 @@ __i915_gem_vma_create(struct drm_i915_gem_object *obj,
 	if (vma == NULL)
 		return ERR_PTR(-ENOMEM);
 
-	INIT_LIST_HEAD(&vma->vma_link);
-	INIT_LIST_HEAD(&vma->mm_list);
+	INIT_LIST_HEAD(&vma->vm_link);
+	INIT_LIST_HEAD(&vma->obj_link);
 	INIT_LIST_HEAD(&vma->exec_list);
 	vma->vm = vm;
 	vma->obj = obj;
@@ -3246,7 +3246,7 @@ __i915_gem_vma_create(struct drm_i915_gem_object *obj,
 	if (i915_is_ggtt(vm))
 		vma->ggtt_view = *ggtt_view;
 
-	list_add_tail(&vma->vma_link, &obj->vma_list);
+	list_add_tail(&vma->obj_link, &obj->vma_list);
 	if (!i915_is_ggtt(vm))
 		i915_ppgtt_get(i915_vm_to_ppgtt(vm));
 
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index b448ad832dcf..2497671d1e1a 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -195,9 +195,9 @@ struct i915_vma {
 	struct i915_ggtt_view ggtt_view;
 
 	/** This object's place on the active/inactive lists */
-	struct list_head mm_list;
+	struct list_head vm_link;
 
-	struct list_head vma_link; /* Link in the object's VMA list */
+	struct list_head obj_link; /* Link in the object's VMA list */
 
 	/** This vma's place in the batchbuffer or on the eviction list */
 	struct list_head exec_list;
diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c
index f7df54a8ee2b..2ef7a158b510 100644
--- a/drivers/gpu/drm/i915/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c
@@ -133,7 +133,7 @@ i915_gem_shrink(struct drm_i915_private *dev_priv,
 
 			/* For the unbound phase, this should be a no-op! */
 			list_for_each_entry_safe(vma, v,
-						 &obj->vma_list, vma_link)
+						 &obj->vma_list, obj_link)
 				if (i915_vma_unbind(vma))
 					break;
 
@@ -193,7 +193,7 @@ static int num_vma_bound(struct drm_i915_gem_object *obj)
 	struct i915_vma *vma;
 	int count = 0;
 
-	list_for_each_entry(vma, &obj->vma_list, vma_link) {
+	list_for_each_entry(vma, &obj->vma_list, obj_link) {
 		if (drm_mm_node_allocated(&vma->node))
 			count++;
 		if (vma->pin_count)
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index 598ed2facf85..305d58a5f745 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -688,7 +688,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
 		}
 
 		vma->bound |= GLOBAL_BIND;
-		list_add_tail(&vma->mm_list, &ggtt->inactive_list);
+		list_add_tail(&vma->vm_link, &ggtt->inactive_list);
 	}
 
 	list_add_tail(&obj->global_list, &dev_priv->mm.bound_list);
diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c
index 251e81c4b0ea..2f3638d02bdd 100644
--- a/drivers/gpu/drm/i915/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
@@ -81,7 +81,7 @@ static void __cancel_userptr__worker(struct work_struct *work)
 		was_interruptible = dev_priv->mm.interruptible;
 		dev_priv->mm.interruptible = false;
 
-		list_for_each_entry_safe(vma, tmp, &obj->vma_list, vma_link)
+		list_for_each_entry_safe(vma, tmp, &obj->vma_list, obj_link)
 			WARN_ON(i915_vma_unbind(vma));
 		WARN_ON(i915_gem_object_put_pages(obj));
 
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index d27c07982c89..9ab77875ecbd 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -731,7 +731,7 @@ static u32 capture_active_bo(struct drm_i915_error_buffer *err,
 	struct i915_vma *vma;
 	int i = 0;
 
-	list_for_each_entry(vma, head, mm_list) {
+	list_for_each_entry(vma, head, vm_link) {
 		capture_bo(err++, vma);
 		if (++i == count)
 			break;
@@ -754,7 +754,7 @@ static u32 capture_pinned_bo(struct drm_i915_error_buffer *err,
 		if (err == last)
 			break;
 
-		list_for_each_entry(vma, &obj->vma_list, vma_link)
+		list_for_each_entry(vma, &obj->vma_list, obj_link)
 			if (vma->vm == vm && vma->pin_count > 0)
 				capture_bo(err++, vma);
 	}
@@ -1115,12 +1115,12 @@ static void i915_gem_capture_vm(struct drm_i915_private *dev_priv,
 	int i;
 
 	i = 0;
-	list_for_each_entry(vma, &vm->active_list, mm_list)
+	list_for_each_entry(vma, &vm->active_list, vm_link)
 		i++;
 	error->active_bo_count[ndx] = i;
 
 	list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
-		list_for_each_entry(vma, &obj->vma_list, vma_link)
+		list_for_each_entry(vma, &obj->vma_list, obj_link)
 			if (vma->vm == vm && vma->pin_count > 0)
 				i++;
 	}
-- 
2.6.4

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

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

* [PATCH 04/11] drm/i915: Amalgamate GGTT/ppGTT vma debug list walkers
  2015-12-14 11:36 [PATCH 01/11] drm/i915: Introduce drm_i915_gem_request_node for request tracking Chris Wilson
  2015-12-14 11:36 ` [PATCH 02/11] drm/i915: Refactor activity tracking for requests Chris Wilson
  2015-12-14 11:36 ` [PATCH 03/11] drm/i915: Rename vma->*_list to *_link for consistency Chris Wilson
@ 2015-12-14 11:36 ` Chris Wilson
  2015-12-17 11:21   ` Tvrtko Ursulin
  2015-12-14 11:36 ` [PATCH 05/11] drm/i915: Reduce the pointer dance of i915_is_ggtt() Chris Wilson
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 37+ messages in thread
From: Chris Wilson @ 2015-12-14 11:36 UTC (permalink / raw)
  To: intel-gfx

As we can now have multiple VMA inside the global GTT (with partial
mappings, rotations, etc), it is no longer true that there may just be a
single GGTT entry and so we should walk the full vma_list to count up
the actual usage. In addition to unifying the two walkers, switch from
multiplying the object size for each vma to summing the bound vma sizes.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 46 +++++++++++++++----------------------
 1 file changed, 18 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index fdcf90757eb0..c04ba9981e9b 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -332,6 +332,7 @@ static int per_file_stats(int id, void *ptr, void *data)
 	struct drm_i915_gem_object *obj = ptr;
 	struct file_stats *stats = data;
 	struct i915_vma *vma;
+	int bound = 0;
 
 	stats->count++;
 	stats->total += obj->base.size;
@@ -339,41 +340,30 @@ static int per_file_stats(int id, void *ptr, void *data)
 	if (obj->base.name || obj->base.dma_buf)
 		stats->shared += obj->base.size;
 
-	if (USES_FULL_PPGTT(obj->base.dev)) {
-		list_for_each_entry(vma, &obj->vma_list, obj_link) {
-			struct i915_hw_ppgtt *ppgtt;
+	list_for_each_entry(vma, &obj->vma_list, obj_link) {
+		if (!drm_mm_node_allocated(&vma->node))
+			continue;
 
-			if (!drm_mm_node_allocated(&vma->node))
-				continue;
+		bound++;
 
-			if (i915_is_ggtt(vma->vm)) {
-				stats->global += obj->base.size;
-				continue;
-			}
-
-			ppgtt = container_of(vma->vm, struct i915_hw_ppgtt, base);
+		if (i915_is_ggtt(vma->vm)) {
+			stats->global += vma->node.size;
+		} else {
+			struct i915_hw_ppgtt *ppgtt
+				= container_of(vma->vm,
+					       struct i915_hw_ppgtt,
+					       base);
 			if (ppgtt->file_priv != stats->file_priv)
 				continue;
-
-			if (obj->active) /* XXX per-vma statistic */
-				stats->active += obj->base.size;
-			else
-				stats->inactive += obj->base.size;
-
-			return 0;
-		}
-	} else {
-		if (i915_gem_obj_ggtt_bound(obj)) {
-			stats->global += obj->base.size;
-			if (obj->active)
-				stats->active += obj->base.size;
-			else
-				stats->inactive += obj->base.size;
-			return 0;
 		}
+
+		if (obj->active) /* XXX per-vma statistic */
+			stats->active += vma->node.size;
+		else
+			stats->inactive += vma->node.size;
 	}
 
-	if (!list_empty(&obj->global_list))
+	if (!bound)
 		stats->unbound += obj->base.size;
 
 	return 0;
-- 
2.6.4

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

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

* [PATCH 05/11] drm/i915: Reduce the pointer dance of i915_is_ggtt()
  2015-12-14 11:36 [PATCH 01/11] drm/i915: Introduce drm_i915_gem_request_node for request tracking Chris Wilson
                   ` (2 preceding siblings ...)
  2015-12-14 11:36 ` [PATCH 04/11] drm/i915: Amalgamate GGTT/ppGTT vma debug list walkers Chris Wilson
@ 2015-12-14 11:36 ` Chris Wilson
  2015-12-17 11:31   ` Tvrtko Ursulin
  2015-12-14 11:36 ` [PATCH 06/11] drm/i915: Store owning file on the i915_address_space Chris Wilson
                   ` (8 subsequent siblings)
  12 siblings, 1 reply; 37+ messages in thread
From: Chris Wilson @ 2015-12-14 11:36 UTC (permalink / raw)
  To: intel-gfx

The multiple levels of indirect do nothing but hinder the compiler and
the pointer chasing turns to be quite painful but painless to fix.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_debugfs.c        | 13 ++++++-------
 drivers/gpu/drm/i915/i915_drv.h            |  7 -------
 drivers/gpu/drm/i915/i915_gem.c            | 18 +++++++-----------
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |  5 ++---
 drivers/gpu/drm/i915/i915_gem_gtt.c        | 12 +++++-------
 drivers/gpu/drm/i915/i915_gem_gtt.h        |  5 +++++
 drivers/gpu/drm/i915/i915_trace.h          | 27 ++++++++-------------------
 7 files changed, 33 insertions(+), 54 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index c04ba9981e9b..9ec133f5af00 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -118,7 +118,7 @@ static u64 i915_gem_obj_total_ggtt_size(struct drm_i915_gem_object *obj)
 	struct i915_vma *vma;
 
 	list_for_each_entry(vma, &obj->vma_list, obj_link) {
-		if (i915_is_ggtt(vma->vm) && drm_mm_node_allocated(&vma->node))
+		if (vma->is_ggtt && drm_mm_node_allocated(&vma->node))
 			size += vma->node.size;
 	}
 
@@ -165,12 +165,11 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
 		seq_printf(m, " (fence: %d)", obj->fence_reg);
 	list_for_each_entry(vma, &obj->vma_list, obj_link) {
 		seq_printf(m, " (%sgtt offset: %08llx, size: %08llx",
-			   i915_is_ggtt(vma->vm) ? "g" : "pp",
+			   vma->is_ggtt ? "g" : "pp",
 			   vma->node.start, vma->node.size);
-		if (i915_is_ggtt(vma->vm))
-			seq_printf(m, ", type: %u)", vma->ggtt_view.type);
-		else
-			seq_puts(m, ")");
+		if (vma->is_ggtt)
+			seq_printf(m, ", type: %u", vma->ggtt_view.type);
+		seq_puts(m, ")");
 	}
 	if (obj->stolen)
 		seq_printf(m, " (stolen: %08llx)", obj->stolen->start);
@@ -346,7 +345,7 @@ static int per_file_stats(int id, void *ptr, void *data)
 
 		bound++;
 
-		if (i915_is_ggtt(vma->vm)) {
+		if (vma->is_ggtt) {
 			stats->global += vma->node.size;
 		} else {
 			struct i915_hw_ppgtt *ppgtt
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index dbcb7659ba2b..6ce163a681f2 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2916,18 +2916,11 @@ bool i915_gem_obj_is_pinned(struct drm_i915_gem_object *obj);
 /* Some GGTT VM helpers */
 #define i915_obj_to_ggtt(obj) \
 	(&((struct drm_i915_private *)(obj)->base.dev->dev_private)->gtt.base)
-static inline bool i915_is_ggtt(struct i915_address_space *vm)
-{
-	struct i915_address_space *ggtt =
-		&((struct drm_i915_private *)(vm)->dev->dev_private)->gtt.base;
-	return vm == ggtt;
-}
 
 static inline struct i915_hw_ppgtt *
 i915_vm_to_ppgtt(struct i915_address_space *vm)
 {
 	WARN_ON(i915_is_ggtt(vm));
-
 	return container_of(vm, struct i915_hw_ppgtt, base);
 }
 
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index e6ace74616b2..144e92df8137 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2603,8 +2603,7 @@ static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
 			return ret;
 	}
 
-	if (i915_is_ggtt(vma->vm) &&
-	    vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) {
+	if (vma->is_ggtt && vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) {
 		i915_gem_object_finish_gtt(obj);
 
 		/* release the fence reg _after_ flushing */
@@ -2619,7 +2618,7 @@ static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
 	vma->bound = 0;
 
 	list_del_init(&vma->vm_link);
-	if (i915_is_ggtt(vma->vm)) {
+	if (vma->is_ggtt) {
 		if (vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) {
 			obj->map_and_fenceable = false;
 		} else if (vma->ggtt_view.pages) {
@@ -3889,17 +3888,14 @@ struct i915_vma *i915_gem_obj_to_ggtt_view(struct drm_i915_gem_object *obj,
 
 void i915_gem_vma_destroy(struct i915_vma *vma)
 {
-	struct i915_address_space *vm = NULL;
 	WARN_ON(vma->node.allocated);
 
 	/* Keep the vma as a placeholder in the execbuffer reservation lists */
 	if (!list_empty(&vma->exec_list))
 		return;
 
-	vm = vma->vm;
-
-	if (!i915_is_ggtt(vm))
-		i915_ppgtt_put(i915_vm_to_ppgtt(vm));
+	if (!vma->is_ggtt)
+		i915_ppgtt_put(i915_vm_to_ppgtt(vma->vm));
 
 	list_del(&vma->obj_link);
 
@@ -4425,7 +4421,7 @@ u64 i915_gem_obj_offset(struct drm_i915_gem_object *o,
 	WARN_ON(vm == &dev_priv->mm.aliasing_ppgtt->base);
 
 	list_for_each_entry(vma, &o->vma_list, obj_link) {
-		if (i915_is_ggtt(vma->vm) &&
+		if (vma->is_ggtt &&
 		    vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
 			continue;
 		if (vma->vm == vm)
@@ -4458,7 +4454,7 @@ bool i915_gem_obj_bound(struct drm_i915_gem_object *o,
 	struct i915_vma *vma;
 
 	list_for_each_entry(vma, &o->vma_list, obj_link) {
-		if (i915_is_ggtt(vma->vm) &&
+		if (vma->is_ggtt &&
 		    vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
 			continue;
 		if (vma->vm == vm && drm_mm_node_allocated(&vma->node))
@@ -4505,7 +4501,7 @@ unsigned long i915_gem_obj_size(struct drm_i915_gem_object *o,
 	BUG_ON(list_empty(&o->vma_list));
 
 	list_for_each_entry(vma, &o->vma_list, obj_link) {
-		if (i915_is_ggtt(vma->vm) &&
+		if (vma->is_ggtt &&
 		    vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
 			continue;
 		if (vma->vm == vm)
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index e9741368972e..6788f71ad989 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -658,7 +658,7 @@ need_reloc_mappable(struct i915_vma *vma)
 	if (entry->relocation_count == 0)
 		return false;
 
-	if (!i915_is_ggtt(vma->vm))
+	if (!vma->is_ggtt)
 		return false;
 
 	/* See also use_cpu_reloc() */
@@ -677,8 +677,7 @@ eb_vma_misplaced(struct i915_vma *vma)
 	struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
 	struct drm_i915_gem_object *obj = vma->obj;
 
-	WARN_ON(entry->flags & __EXEC_OBJECT_NEEDS_MAP &&
-	       !i915_is_ggtt(vma->vm));
+	WARN_ON(entry->flags & __EXEC_OBJECT_NEEDS_MAP && !vma->is_ggtt);
 
 	if (entry->alignment &&
 	    vma->node.start & (entry->alignment - 1))
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 25bcea3e6ab6..da150c27a76c 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -3134,6 +3134,7 @@ int i915_gem_gtt_init(struct drm_device *dev)
 	}
 
 	gtt->base.dev = dev;
+	gtt->base.is_ggtt = true;
 
 	ret = gtt->gtt_probe(dev, &gtt->base.total, &gtt->stolen_size,
 			     &gtt->mappable_base, &gtt->mappable_end);
@@ -3242,13 +3243,14 @@ __i915_gem_vma_create(struct drm_i915_gem_object *obj,
 	INIT_LIST_HEAD(&vma->exec_list);
 	vma->vm = vm;
 	vma->obj = obj;
+	vma->is_ggtt = i915_is_ggtt(vm);
 
 	if (i915_is_ggtt(vm))
 		vma->ggtt_view = *ggtt_view;
+	else
+		i915_ppgtt_get(i915_vm_to_ppgtt(vm));
 
 	list_add_tail(&vma->obj_link, &obj->vma_list);
-	if (!i915_is_ggtt(vm))
-		i915_ppgtt_get(i915_vm_to_ppgtt(vm));
 
 	return vma;
 }
@@ -3520,13 +3522,9 @@ int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level,
 		return 0;
 
 	if (vma->bound == 0 && vma->vm->allocate_va_range) {
-		trace_i915_va_alloc(vma->vm,
-				    vma->node.start,
-				    vma->node.size,
-				    VM_TO_TRACE_NAME(vma->vm));
-
 		/* XXX: i915_vma_pin() will fix this +- hack */
 		vma->pin_count++;
+		trace_i915_va_alloc(vma);
 		ret = vma->vm->allocate_va_range(vma->vm,
 						 vma->node.start,
 						 vma->node.size);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 2497671d1e1a..bae005a62cfc 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -184,6 +184,7 @@ struct i915_vma {
 #define GLOBAL_BIND	(1<<0)
 #define LOCAL_BIND	(1<<1)
 	unsigned int bound : 4;
+	bool is_ggtt : 1;
 
 	/**
 	 * Support different GGTT views into the same object.
@@ -276,6 +277,8 @@ struct i915_address_space {
 	u64 start;		/* Start offset always 0 for dri2 */
 	u64 total;		/* size addr space maps (ex. 2GB for ggtt) */
 
+	bool is_ggtt;
+
 	struct i915_page_scratch *scratch_page;
 	struct i915_page_table *scratch_pt;
 	struct i915_page_directory *scratch_pd;
@@ -331,6 +334,8 @@ struct i915_address_space {
 			u32 flags);
 };
 
+#define i915_is_ggtt(V) ((V)->is_ggtt)
+
 /* The Graphics Translation Table is the way in which GEN hardware translates a
  * Graphics Virtual Address into a Physical Address. In addition to the normal
  * collateral associated with any va->pa translations GEN hardware also has a
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h
index 85469e3c740a..e486dcef508d 100644
--- a/drivers/gpu/drm/i915/i915_trace.h
+++ b/drivers/gpu/drm/i915/i915_trace.h
@@ -175,35 +175,24 @@ TRACE_EVENT(i915_vma_unbind,
 		      __entry->obj, __entry->offset, __entry->size, __entry->vm)
 );
 
-#define VM_TO_TRACE_NAME(vm) \
-	(i915_is_ggtt(vm) ? "G" : \
-		      "P")
-
-DECLARE_EVENT_CLASS(i915_va,
-	TP_PROTO(struct i915_address_space *vm, u64 start, u64 length, const char *name),
-	TP_ARGS(vm, start, length, name),
+TRACE_EVENT(i915_va_alloc,
+	TP_PROTO(struct i915_vma *vma),
+	TP_ARGS(vma),
 
 	TP_STRUCT__entry(
 		__field(struct i915_address_space *, vm)
 		__field(u64, start)
 		__field(u64, end)
-		__string(name, name)
 	),
 
 	TP_fast_assign(
-		__entry->vm = vm;
-		__entry->start = start;
-		__entry->end = start + length - 1;
-		__assign_str(name, name);
+		__entry->vm = vma->vm;
+		__entry->start = vma->node.start;
+		__entry->end = vma->node.start + vma->node.size - 1;
 	),
 
-	TP_printk("vm=%p (%s), 0x%llx-0x%llx",
-		  __entry->vm, __get_str(name),  __entry->start, __entry->end)
-);
-
-DEFINE_EVENT(i915_va, i915_va_alloc,
-	     TP_PROTO(struct i915_address_space *vm, u64 start, u64 length, const char *name),
-	     TP_ARGS(vm, start, length, name)
+	TP_printk("vm=%p (%c), 0x%llx-0x%llx",
+		  __entry->vm, i915_is_ggtt(__entry->vm) ? 'G' : 'P',  __entry->start, __entry->end)
 );
 
 DECLARE_EVENT_CLASS(i915_px_entry,
-- 
2.6.4

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

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

* [PATCH 06/11] drm/i915: Store owning file on the i915_address_space
  2015-12-14 11:36 [PATCH 01/11] drm/i915: Introduce drm_i915_gem_request_node for request tracking Chris Wilson
                   ` (3 preceding siblings ...)
  2015-12-14 11:36 ` [PATCH 05/11] drm/i915: Reduce the pointer dance of i915_is_ggtt() Chris Wilson
@ 2015-12-14 11:36 ` Chris Wilson
  2015-12-17 11:52   ` Tvrtko Ursulin
  2015-12-14 11:36 ` [PATCH 07/11] drm/i915: i915_vma_move_to_active prep patch Chris Wilson
                   ` (7 subsequent siblings)
  12 siblings, 1 reply; 37+ messages in thread
From: Chris Wilson @ 2015-12-14 11:36 UTC (permalink / raw)
  To: intel-gfx

For the global GTT (and aliasing GTT), the address space is owned by the
device (it is a global resource) and so the per-file owner field is
NULL. For per-process GTT (where we create an address space per
context), each is owned by the opening file. We can use this ownership
information to both distinguish GGTT and ppGTT address spaces, as well
as occasionally inspect the owner.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_debugfs.c     |  2 +-
 drivers/gpu/drm/i915/i915_drv.h         |  1 -
 drivers/gpu/drm/i915/i915_gem_context.c |  3 ++-
 drivers/gpu/drm/i915/i915_gem_gtt.c     | 25 +++++++++++++------------
 drivers/gpu/drm/i915/i915_gem_gtt.h     | 13 ++++++-------
 5 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 9ec133f5af00..179e3c5c5022 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -352,7 +352,7 @@ static int per_file_stats(int id, void *ptr, void *data)
 				= container_of(vma->vm,
 					       struct i915_hw_ppgtt,
 					       base);
-			if (ppgtt->file_priv != stats->file_priv)
+			if (ppgtt->base.file != stats->file_priv)
 				continue;
 		}
 
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 6ce163a681f2..b32a00f60e98 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2924,7 +2924,6 @@ i915_vm_to_ppgtt(struct i915_address_space *vm)
 	return container_of(vm, struct i915_hw_ppgtt, base);
 }
 
-
 static inline bool i915_gem_obj_ggtt_bound(struct drm_i915_gem_object *obj)
 {
 	return i915_gem_obj_ggtt_bound_view(obj, &i915_ggtt_view_normal);
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 25a8498f0b5a..dcb4603a7f03 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -296,7 +296,8 @@ i915_gem_create_context(struct drm_device *dev,
 	}
 
 	if (USES_FULL_PPGTT(dev)) {
-		struct i915_hw_ppgtt *ppgtt = i915_ppgtt_create(dev, file_priv);
+		struct i915_hw_ppgtt *ppgtt =
+			i915_ppgtt_create(to_i915(dev), file_priv);
 
 		if (IS_ERR_OR_NULL(ppgtt)) {
 			DRM_DEBUG_DRIVER("PPGTT setup failed (%ld)\n",
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index da150c27a76c..130ccefb2491 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2112,11 +2112,12 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
 	return 0;
 }
 
-static int __hw_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt)
+static int __hw_ppgtt_init(struct i915_hw_ppgtt *ppgtt,
+			   struct drm_i915_private *dev_priv)
 {
-	ppgtt->base.dev = dev;
+	ppgtt->base.dev = dev_priv->dev;
 
-	if (INTEL_INFO(dev)->gen < 8)
+	if (INTEL_INFO(dev_priv)->gen < 8)
 		return gen6_ppgtt_init(ppgtt);
 	else
 		return gen8_ppgtt_init(ppgtt);
@@ -2132,15 +2133,17 @@ static void i915_address_space_init(struct i915_address_space *vm,
 	list_add_tail(&vm->global_link, &dev_priv->vm_list);
 }
 
-int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt)
+int i915_ppgtt_init(struct i915_hw_ppgtt *ppgtt,
+		    struct drm_i915_private *dev_priv,
+		    struct drm_i915_file_private *file_priv)
 {
-	struct drm_i915_private *dev_priv = dev->dev_private;
 	int ret = 0;
 
-	ret = __hw_ppgtt_init(dev, ppgtt);
+	ret = __hw_ppgtt_init(ppgtt, dev_priv);
 	if (ret == 0) {
 		kref_init(&ppgtt->ref);
 		i915_address_space_init(&ppgtt->base, dev_priv);
+		ppgtt->base.file = file_priv;
 	}
 
 	return ret;
@@ -2183,7 +2186,8 @@ int i915_ppgtt_init_ring(struct drm_i915_gem_request *req)
 }
 
 struct i915_hw_ppgtt *
-i915_ppgtt_create(struct drm_device *dev, struct drm_i915_file_private *fpriv)
+i915_ppgtt_create(struct drm_i915_private *dev_priv,
+		  struct drm_i915_file_private *fpriv)
 {
 	struct i915_hw_ppgtt *ppgtt;
 	int ret;
@@ -2192,14 +2196,12 @@ i915_ppgtt_create(struct drm_device *dev, struct drm_i915_file_private *fpriv)
 	if (!ppgtt)
 		return ERR_PTR(-ENOMEM);
 
-	ret = i915_ppgtt_init(dev, ppgtt);
+	ret = i915_ppgtt_init(ppgtt, dev_priv, fpriv);
 	if (ret) {
 		kfree(ppgtt);
 		return ERR_PTR(ret);
 	}
 
-	ppgtt->file_priv = fpriv;
-
 	trace_i915_ppgtt_create(&ppgtt->base);
 
 	return ppgtt;
@@ -2717,7 +2719,7 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
 		if (!ppgtt)
 			return -ENOMEM;
 
-		ret = __hw_ppgtt_init(dev, ppgtt);
+		ret = __hw_ppgtt_init(ppgtt, dev_priv);
 		if (ret) {
 			ppgtt->base.cleanup(&ppgtt->base);
 			kfree(ppgtt);
@@ -3134,7 +3136,6 @@ int i915_gem_gtt_init(struct drm_device *dev)
 	}
 
 	gtt->base.dev = dev;
-	gtt->base.is_ggtt = true;
 
 	ret = gtt->gtt_probe(dev, &gtt->base.total, &gtt->stolen_size,
 			     &gtt->mappable_base, &gtt->mappable_end);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index bae005a62cfc..4e9553ace33f 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -273,12 +273,11 @@ struct i915_pml4 {
 struct i915_address_space {
 	struct drm_mm mm;
 	struct drm_device *dev;
+	struct drm_i915_file_private *file;
 	struct list_head global_link;
 	u64 start;		/* Start offset always 0 for dri2 */
 	u64 total;		/* size addr space maps (ex. 2GB for ggtt) */
 
-	bool is_ggtt;
-
 	struct i915_page_scratch *scratch_page;
 	struct i915_page_table *scratch_pt;
 	struct i915_page_directory *scratch_pd;
@@ -334,7 +333,7 @@ struct i915_address_space {
 			u32 flags);
 };
 
-#define i915_is_ggtt(V) ((V)->is_ggtt)
+#define i915_is_ggtt(V) ((V)->file == NULL)
 
 /* The Graphics Translation Table is the way in which GEN hardware translates a
  * Graphics Virtual Address into a Physical Address. In addition to the normal
@@ -376,8 +375,6 @@ struct i915_hw_ppgtt {
 		struct i915_page_directory pd;		/* GEN6-7 */
 	};
 
-	struct drm_i915_file_private *file_priv;
-
 	gen6_pte_t __iomem *pd_addr;
 
 	int (*enable)(struct i915_hw_ppgtt *ppgtt);
@@ -522,11 +519,13 @@ void i915_gem_init_global_gtt(struct drm_device *dev);
 void i915_global_gtt_cleanup(struct drm_device *dev);
 
 
-int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt);
+int i915_ppgtt_init(struct i915_hw_ppgtt *ppgtt,
+		    struct drm_i915_private *dev_priv,
+		    struct drm_i915_file_private *file_priv);
 int i915_ppgtt_init_hw(struct drm_device *dev);
 int i915_ppgtt_init_ring(struct drm_i915_gem_request *req);
 void i915_ppgtt_release(struct kref *kref);
-struct i915_hw_ppgtt *i915_ppgtt_create(struct drm_device *dev,
+struct i915_hw_ppgtt *i915_ppgtt_create(struct drm_i915_private *dev_priv,
 					struct drm_i915_file_private *fpriv);
 static inline void i915_ppgtt_get(struct i915_hw_ppgtt *ppgtt)
 {
-- 
2.6.4

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

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

* [PATCH 07/11] drm/i915: i915_vma_move_to_active prep patch
  2015-12-14 11:36 [PATCH 01/11] drm/i915: Introduce drm_i915_gem_request_node for request tracking Chris Wilson
                   ` (4 preceding siblings ...)
  2015-12-14 11:36 ` [PATCH 06/11] drm/i915: Store owning file on the i915_address_space Chris Wilson
@ 2015-12-14 11:36 ` Chris Wilson
  2015-12-17 12:04   ` Tvrtko Ursulin
  2015-12-14 11:36 ` [PATCH 08/11] drm/i915: Track active vma requests Chris Wilson
                   ` (6 subsequent siblings)
  12 siblings, 1 reply; 37+ messages in thread
From: Chris Wilson @ 2015-12-14 11:36 UTC (permalink / raw)
  To: intel-gfx

This patch is broken out of the next just to remove the code motion from
that patch and make it more readable. What we do here is move the
i915_vma_move_to_active() to i915_gem_execbuffer.c and put the three
stages (read, write, fenced) together so that future modifications to
active handling are all located in the same spot. The importance of this
is so that we can more simply control the order in which the requests
are place in the retirement list (i.e. control the order at which we
retire and so control the lifetimes to avoid having to hold onto
references).

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_drv.h              |  3 +-
 drivers/gpu/drm/i915/i915_gem.c              | 15 -------
 drivers/gpu/drm/i915/i915_gem_context.c      |  7 ++--
 drivers/gpu/drm/i915/i915_gem_execbuffer.c   | 63 ++++++++++++++++++----------
 drivers/gpu/drm/i915/i915_gem_render_state.c |  2 +-
 5 files changed, 49 insertions(+), 41 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b32a00f60e98..eb775eb1c693 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2775,7 +2775,8 @@ int __must_check i915_mutex_lock_interruptible(struct drm_device *dev);
 int i915_gem_object_sync(struct drm_i915_gem_object *obj,
 			 struct drm_i915_gem_request *to);
 void i915_vma_move_to_active(struct i915_vma *vma,
-			     struct drm_i915_gem_request *req);
+			     struct drm_i915_gem_request *req,
+			     unsigned flags);
 int i915_gem_dumb_create(struct drm_file *file_priv,
 			 struct drm_device *dev,
 			 struct drm_mode_create_dumb *args);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 144e92df8137..8a824c5d5348 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2016,21 +2016,6 @@ void *i915_gem_object_pin_vmap(struct drm_i915_gem_object *obj)
 	return obj->vmapping;
 }
 
-void i915_vma_move_to_active(struct i915_vma *vma,
-			     struct drm_i915_gem_request *req)
-{
-	struct drm_i915_gem_object *obj = vma->obj;
-	struct intel_engine_cs *engine = req->engine;
-
-	/* Add a reference if we're newly entering the active list. */
-	if (obj->active == 0)
-		drm_gem_object_reference(&obj->base);
-	obj->active |= intel_engine_flag(engine);
-
-	i915_gem_request_mark_active(req, &obj->last_read[engine->id]);
-	list_move_tail(&vma->vm_link, &vma->vm->active_list);
-}
-
 static void
 i915_gem_object_retire__fence(struct drm_i915_gem_request_active *active,
 			      struct drm_i915_gem_request *req)
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index dcb4603a7f03..c4a8a64cd1b2 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -766,8 +766,8 @@ static int do_switch(struct drm_i915_gem_request *req)
 	 * MI_SET_CONTEXT instead of when the next seqno has completed.
 	 */
 	if (from != NULL) {
-		from->legacy_hw_ctx.rcs_state->base.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
-		i915_vma_move_to_active(i915_gem_obj_to_ggtt(from->legacy_hw_ctx.rcs_state), req);
+		struct drm_i915_gem_object *obj = from->legacy_hw_ctx.rcs_state;
+
 		/* As long as MI_SET_CONTEXT is serializing, ie. it flushes the
 		 * whole damn pipeline, we don't need to explicitly mark the
 		 * object dirty. The only exception is that the context must be
@@ -775,7 +775,8 @@ static int do_switch(struct drm_i915_gem_request *req)
 		 * able to defer doing this until we know the object would be
 		 * swapped, but there is no way to do that yet.
 		 */
-		from->legacy_hw_ctx.rcs_state->dirty = 1;
+		obj->base.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
+		i915_vma_move_to_active(i915_gem_obj_to_ggtt(obj), req, 0);
 
 		/* obj is kept alive until the next request by its active ref */
 		i915_gem_object_ggtt_unpin(from->legacy_hw_ctx.rcs_state);
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 6788f71ad989..6de8681bb64c 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1064,6 +1064,44 @@ i915_gem_validate_context(struct drm_device *dev, struct drm_file *file,
 	return ctx;
 }
 
+void i915_vma_move_to_active(struct i915_vma *vma,
+			     struct drm_i915_gem_request *req,
+			     unsigned flags)
+{
+	struct drm_i915_gem_object *obj = vma->obj;
+	const unsigned engine = req->engine->id;
+
+	RQ_BUG_ON(!drm_mm_node_allocated(&vma->node));
+
+	obj->dirty = 1; /* be paranoid  */
+
+	/* Add a reference if we're newly entering the active list. */
+	if (obj->active == 0)
+		drm_gem_object_reference(&obj->base);
+	obj->active |= 1 << engine;
+	i915_gem_request_mark_active(req, &obj->last_read[engine]);
+
+	if (flags & EXEC_OBJECT_WRITE) {
+		i915_gem_request_mark_active(req, &obj->last_write);
+
+		intel_fb_obj_invalidate(obj, ORIGIN_CS);
+
+		/* update for the implicit flush after a batch */
+		obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS;
+	}
+
+	if (flags & EXEC_OBJECT_NEEDS_FENCE) {
+		i915_gem_request_mark_active(req, &obj->last_fence);
+		if (flags & __EXEC_OBJECT_HAS_FENCE) {
+			struct drm_i915_private *dev_priv = req->i915;
+			list_move_tail(&dev_priv->fence_regs[obj->fence_reg].lru_list,
+				       &dev_priv->mm.fence_list);
+		}
+	}
+
+	list_move_tail(&vma->vm_link, &vma->vm->active_list);
+}
+
 static void
 i915_gem_execbuffer_move_to_active(struct list_head *vmas,
 				   struct drm_i915_gem_request *req)
@@ -1071,35 +1109,18 @@ i915_gem_execbuffer_move_to_active(struct list_head *vmas,
 	struct i915_vma *vma;
 
 	list_for_each_entry(vma, vmas, exec_list) {
-		struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
 		struct drm_i915_gem_object *obj = vma->obj;
 		u32 old_read = obj->base.read_domains;
 		u32 old_write = obj->base.write_domain;
 
-		obj->dirty = 1; /* be paranoid  */
 		obj->base.write_domain = obj->base.pending_write_domain;
-		if (obj->base.write_domain == 0)
+		if (obj->base.write_domain)
+			vma->exec_entry->flags |= EXEC_OBJECT_WRITE;
+		else
 			obj->base.pending_read_domains |= obj->base.read_domains;
 		obj->base.read_domains = obj->base.pending_read_domains;
 
-		i915_vma_move_to_active(vma, req);
-		if (obj->base.write_domain) {
-			i915_gem_request_mark_active(req, &obj->last_write);
-
-			intel_fb_obj_invalidate(obj, ORIGIN_CS);
-
-			/* update for the implicit flush after a batch */
-			obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS;
-		}
-		if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) {
-			i915_gem_request_mark_active(req, &obj->last_fence);
-			if (entry->flags & __EXEC_OBJECT_HAS_FENCE) {
-				struct drm_i915_private *dev_priv = req->i915;
-				list_move_tail(&dev_priv->fence_regs[obj->fence_reg].lru_list,
-					       &dev_priv->mm.fence_list);
-			}
-		}
-
+		i915_vma_move_to_active(vma, req, vma->exec_entry->flags);
 		trace_i915_gem_object_change_domain(obj, old_read, old_write);
 	}
 }
diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c
index 630e748c991d..d5a87c4ff0f7 100644
--- a/drivers/gpu/drm/i915/i915_gem_render_state.c
+++ b/drivers/gpu/drm/i915/i915_gem_render_state.c
@@ -221,7 +221,7 @@ int i915_gem_render_state_init(struct drm_i915_gem_request *req)
 			goto out;
 	}
 
-	i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), req);
+	i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), req, 0);
 
 out:
 	i915_gem_render_state_fini(&so);
-- 
2.6.4

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

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

* [PATCH 08/11] drm/i915: Track active vma requests
  2015-12-14 11:36 [PATCH 01/11] drm/i915: Introduce drm_i915_gem_request_node for request tracking Chris Wilson
                   ` (5 preceding siblings ...)
  2015-12-14 11:36 ` [PATCH 07/11] drm/i915: i915_vma_move_to_active prep patch Chris Wilson
@ 2015-12-14 11:36 ` Chris Wilson
  2015-12-17 12:26   ` Tvrtko Ursulin
  2015-12-14 11:36 ` [PATCH 09/11] drm/i915: Release vma when the handle is closed Chris Wilson
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 37+ messages in thread
From: Chris Wilson @ 2015-12-14 11:36 UTC (permalink / raw)
  To: intel-gfx

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.

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            | 36 ++++++++++++++++--------------
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |  2 ++
 drivers/gpu/drm/i915/i915_gem_gtt.c        | 20 +++++++++++++++++
 drivers/gpu/drm/i915/i915_gem_gtt.h        |  5 +++++
 5 files changed, 47 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 179e3c5c5022..4df4ebbd56d6 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -356,7 +356,7 @@ static int per_file_stats(int id, void *ptr, void *data)
 				continue;
 		}
 
-		if (obj->active) /* XXX per-vma statistic */
+		if (vma->active)
 			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 8a824c5d5348..1d21c5b79215 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2040,7 +2040,6 @@ i915_gem_object_retire__read(struct drm_i915_gem_request_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;
 
 	RQ_BUG_ON((obj->flags & (1 << (ring + I915_BO_ACTIVE_SHIFT))) == 0);
 
@@ -2052,12 +2051,9 @@ i915_gem_object_retire__read(struct drm_i915_gem_request_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 (!list_empty(&obj->vma_list))
+		list_move_tail(&obj->global_list,
+			       &request->i915->mm.bound_list);
 
 	drm_gem_object_unreference(&obj->base);
 }
@@ -2567,7 +2563,19 @@ static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
 {
 	struct drm_i915_gem_object *obj = vma->obj;
 	struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
-	int ret;
+	int ret, i;
+
+	/* First wait upon any activity as retiring the request may
+	 * have side-effects such as unpinning or even unbinding this vma.
+	 */
+	if (vma->active && wait) {
+		for (i = 0; i < ARRAY_SIZE(vma->last_read); i++) {
+			ret = i915_wait_request(vma->last_read[i].request);
+			if (ret)
+				return ret;
+		}
+		RQ_BUG_ON(vma->active);
+	}
 
 	if (list_empty(&vma->obj_link))
 		return 0;
@@ -2582,12 +2590,6 @@ static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
 
 	BUG_ON(obj->pages == NULL);
 
-	if (wait) {
-		ret = i915_gem_object_wait_rendering(obj, false);
-		if (ret)
-			return ret;
-	}
-
 	if (vma->is_ggtt && vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) {
 		i915_gem_object_finish_gtt(obj);
 
@@ -3023,9 +3025,8 @@ 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,
-			       &to_i915(obj->base.dev)->gtt.base.inactive_list);
+	if (vma && drm_mm_node_allocated(&vma->node) && !vma->active)
+		list_move_tail(&vma->vm_link, &vma->vm->inactive_list);
 
 	return 0;
 }
@@ -3874,6 +3875,7 @@ struct i915_vma *i915_gem_obj_to_ggtt_view(struct drm_i915_gem_object *obj,
 void i915_gem_vma_destroy(struct i915_vma *vma)
 {
 	WARN_ON(vma->node.allocated);
+	RQ_BUG_ON(vma->active);
 
 	/* Keep the vma as a placeholder in the execbuffer reservation lists */
 	if (!list_empty(&vma->exec_list))
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 6de8681bb64c..1d4378a4501e 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1099,6 +1099,8 @@ void i915_vma_move_to_active(struct i915_vma *vma,
 		}
 	}
 
+	vma->active |= 1 << engine;
+	i915_gem_request_mark_active(req, &vma->last_read[engine]);
 	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 130ccefb2491..5505603f52af 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -3225,12 +3225,30 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev)
 	i915_ggtt_flush(dev_priv);
 }
 
+static void
+i915_vma_retire(struct drm_i915_gem_request_active *active,
+		struct drm_i915_gem_request *rq)
+{
+	const unsigned engine = rq->engine->id;
+	struct i915_vma *vma =
+		container_of(active, struct i915_vma, last_read[engine]);
+
+	RQ_BUG_ON((vma->obj->active & (1 << engine)) == 0);
+
+	vma->active &= ~(1 << engine);
+	if (vma->active)
+		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);
@@ -3242,6 +3260,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 4e9553ace33f..c2f2c62ac88d 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -34,6 +34,8 @@
 #ifndef __I915_GEM_GTT_H__
 #define __I915_GEM_GTT_H__
 
+#include "i915_gem_request.h"
+
 struct drm_i915_file_private;
 
 typedef uint32_t gen6_pte_t;
@@ -180,10 +182,13 @@ struct i915_vma {
 	struct drm_i915_gem_object *obj;
 	struct i915_address_space *vm;
 
+	struct drm_i915_gem_request_active last_read[I915_NUM_RINGS];
+
 	/** 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_RINGS;
 	bool is_ggtt : 1;
 
 	/**
-- 
2.6.4

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

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

* [PATCH 09/11] drm/i915: Release vma when the handle is closed
  2015-12-14 11:36 [PATCH 01/11] drm/i915: Introduce drm_i915_gem_request_node for request tracking Chris Wilson
                   ` (6 preceding siblings ...)
  2015-12-14 11:36 ` [PATCH 08/11] drm/i915: Track active vma requests Chris Wilson
@ 2015-12-14 11:36 ` Chris Wilson
  2015-12-17 13:46   ` Tvrtko Ursulin
  2015-12-14 11:36 ` [PATCH 10/11] drm/i915: Mark the context and address space as closed Chris Wilson
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 37+ messages in thread
From: Chris Wilson @ 2015-12-14 11:36 UTC (permalink / raw)
  To: intel-gfx

In order to prevent a leak of the vma on shared objects, we need to
hook into the object_close callback to destroy the vma on the object for
this file. However, if we destroyed that vma immediately we may cause
unexpected application stalls as we try to unbind a busy vma - hence we
defer the unbind to when we retire the vma.

Testcase: igt/gem_ppggtt/flink-and-close-vma-leak
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com
---
 drivers/gpu/drm/i915/i915_drv.c     |  1 +
 drivers/gpu/drm/i915/i915_drv.h     |  1 +
 drivers/gpu/drm/i915/i915_gem.c     | 41 ++++++++++++++++++++++---------------
 drivers/gpu/drm/i915/i915_gem_gtt.c |  2 ++
 drivers/gpu/drm/i915/i915_gem_gtt.h |  1 +
 5 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index e7eef5fd6918..70979339d58a 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1656,6 +1656,7 @@ static struct drm_driver driver = {
 	.debugfs_init = i915_debugfs_init,
 	.debugfs_cleanup = i915_debugfs_cleanup,
 #endif
+	.gem_close_object = i915_gem_close_object,
 	.gem_free_object = i915_gem_free_object,
 	.gem_vm_ops = &i915_gem_vm_ops,
 
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index eb775eb1c693..696469a06715 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2686,6 +2686,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
 						  size_t size);
 struct drm_i915_gem_object *i915_gem_object_create_from_data(
 		struct drm_device *dev, const void *data, size_t size);
+void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file);
 void i915_gem_free_object(struct drm_gem_object *obj);
 void i915_gem_vma_destroy(struct i915_vma *vma);
 
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 1d21c5b79215..7c13c27a6470 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2367,6 +2367,30 @@ i915_gem_object_flush_active(struct drm_i915_gem_object *obj)
 	return 0;
 }
 
+static void i915_vma_close(struct i915_vma *vma)
+{
+	RQ_BUG_ON(vma->closed);
+	vma->closed = true;
+
+	list_del_init(&vma->obj_link);
+	if (!vma->active)
+		WARN_ON(i915_vma_unbind(vma));
+}
+
+void i915_gem_close_object(struct drm_gem_object *gem,
+			   struct drm_file *file)
+{
+	struct drm_i915_gem_object *obj = to_intel_bo(gem);
+	struct drm_i915_file_private *fpriv = file->driver_priv;
+	struct i915_vma *vma, *vn;
+
+	mutex_lock(&obj->base.dev->struct_mutex);
+	list_for_each_entry_safe(vma, vn, &obj->vma_list, obj_link)
+		if (vma->vm->file == fpriv)
+			i915_vma_close(vma);
+	mutex_unlock(&obj->base.dev->struct_mutex);
+}
+
 /**
  * i915_gem_wait_ioctl - implements DRM_IOCTL_I915_GEM_WAIT
  * @DRM_IOCTL_ARGS: standard ioctl arguments
@@ -2577,9 +2601,6 @@ static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
 		RQ_BUG_ON(vma->active);
 	}
 
-	if (list_empty(&vma->obj_link))
-		return 0;
-
 	if (!drm_mm_node_allocated(&vma->node)) {
 		i915_gem_vma_destroy(vma);
 		return 0;
@@ -3792,20 +3813,8 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
 	trace_i915_gem_object_destroy(obj);
 
 	list_for_each_entry_safe(vma, next, &obj->vma_list, obj_link) {
-		int ret;
-
 		vma->pin_count = 0;
-		ret = i915_vma_unbind(vma);
-		if (WARN_ON(ret == -ERESTARTSYS)) {
-			bool was_interruptible;
-
-			was_interruptible = dev_priv->mm.interruptible;
-			dev_priv->mm.interruptible = false;
-
-			WARN_ON(i915_vma_unbind(vma));
-
-			dev_priv->mm.interruptible = was_interruptible;
-		}
+		i915_vma_close(vma);
 	}
 
 	/* Stolen objects don't hold a ref, but do hold pin count. Fix that up
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 5505603f52af..9f594c33bd0a 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -3240,6 +3240,8 @@ i915_vma_retire(struct drm_i915_gem_request_active *active,
 		return;
 
 	list_move_tail(&vma->vm_link, &vma->vm->inactive_list);
+	if (unlikely(vma->closed))
+		WARN_ON(i915_vma_unbind(vma));
 }
 
 static struct i915_vma *
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index c2f2c62ac88d..be7e8526b219 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -190,6 +190,7 @@ struct i915_vma {
 	unsigned int bound : 4;
 	unsigned int active : I915_NUM_RINGS;
 	bool is_ggtt : 1;
+	bool closed : 1;
 
 	/**
 	 * Support different GGTT views into the same object.
-- 
2.6.4

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

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

* [PATCH 10/11] drm/i915: Mark the context and address space as closed
  2015-12-14 11:36 [PATCH 01/11] drm/i915: Introduce drm_i915_gem_request_node for request tracking Chris Wilson
                   ` (7 preceding siblings ...)
  2015-12-14 11:36 ` [PATCH 09/11] drm/i915: Release vma when the handle is closed Chris Wilson
@ 2015-12-14 11:36 ` Chris Wilson
  2015-12-17 12:37   ` Tvrtko Ursulin
  2015-12-17 14:15   ` Tvrtko Ursulin
  2015-12-14 11:36 ` [PATCH 11/11] Revert "drm/i915: Clean up associated VMAs on context destruction" Chris Wilson
                   ` (3 subsequent siblings)
  12 siblings, 2 replies; 37+ messages in thread
From: Chris Wilson @ 2015-12-14 11:36 UTC (permalink / raw)
  To: intel-gfx

When the user closes the context mark it and the dependent address space
as closed. As we use an asynchronous destruct method, this has two purposes.
First it allows us to flag the closed context and detect internal errors if
we to create any new objects for it (as it is removed from the user's
namespace, these should be internal bugs only). And secondly, it allows
us to immediately reap stale vma.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_drv.h         |  4 ++++
 drivers/gpu/drm/i915/i915_gem.c         | 15 ++++++++-----
 drivers/gpu/drm/i915/i915_gem_context.c | 39 +++++++++++++++++++++++++++++----
 drivers/gpu/drm/i915/i915_gem_gtt.c     | 11 +++++++---
 drivers/gpu/drm/i915/i915_gem_gtt.h     |  9 ++++++++
 drivers/gpu/drm/i915/i915_gem_stolen.c  |  2 +-
 6 files changed, 66 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 696469a06715..66ecd6b3df95 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -892,6 +892,8 @@ struct intel_context {
 	} engine[I915_NUM_RINGS];
 
 	struct list_head link;
+
+	bool closed:1;
 };
 
 enum fb_op_origin {
@@ -2720,6 +2722,8 @@ int __must_check i915_vma_unbind(struct i915_vma *vma);
  * _guarantee_ VMA in question is _not in use_ anywhere.
  */
 int __must_check __i915_vma_unbind_no_wait(struct i915_vma *vma);
+void i915_vma_close(struct i915_vma *vma);
+
 int i915_gem_object_put_pages(struct drm_i915_gem_object *obj);
 void i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv);
 void i915_gem_release_mmap(struct drm_i915_gem_object *obj);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 7c13c27a6470..08ea0b7eda8b 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2367,12 +2367,13 @@ i915_gem_object_flush_active(struct drm_i915_gem_object *obj)
 	return 0;
 }
 
-static void i915_vma_close(struct i915_vma *vma)
+void i915_vma_close(struct i915_vma *vma)
 {
 	RQ_BUG_ON(vma->closed);
 	vma->closed = true;
 
 	list_del_init(&vma->obj_link);
+	list_del_init(&vma->vm_link);
 	if (!vma->active)
 		WARN_ON(i915_vma_unbind(vma));
 }
@@ -2620,12 +2621,13 @@ static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
 			return ret;
 	}
 
-	trace_i915_vma_unbind(vma);
-
-	vma->vm->unbind_vma(vma);
+	if (likely(!vma->vm->closed)) {
+		trace_i915_vma_unbind(vma);
+		vma->vm->unbind_vma(vma);
+	}
 	vma->bound = 0;
 
-	list_del_init(&vma->vm_link);
+	list_move_tail(&vma->vm_link, &vma->vm->unbound_list);
 	if (vma->is_ggtt) {
 		if (vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) {
 			obj->map_and_fenceable = false;
@@ -2882,7 +2884,7 @@ search_free:
 		goto err_remove_node;
 
 	list_move_tail(&obj->global_list, &dev_priv->mm.bound_list);
-	list_add_tail(&vma->vm_link, &vm->inactive_list);
+	list_move_tail(&vma->vm_link, &vm->inactive_list);
 
 	return vma;
 
@@ -3890,6 +3892,7 @@ void i915_gem_vma_destroy(struct i915_vma *vma)
 	if (!list_empty(&vma->exec_list))
 		return;
 
+	list_del(&vma->vm_link);
 	if (!vma->is_ggtt)
 		i915_ppgtt_put(i915_vm_to_ppgtt(vma->vm));
 
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index c4a8a64cd1b2..9669547c7c2d 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -153,6 +153,7 @@ void i915_gem_context_free(struct kref *ctx_ref)
 	struct intel_context *ctx = container_of(ctx_ref, typeof(*ctx), ref);
 
 	trace_i915_context_free(ctx);
+	RQ_BUG_ON(!ctx->closed);
 
 	if (i915.enable_execlists)
 		intel_lr_context_free(ctx);
@@ -209,6 +210,36 @@ i915_gem_alloc_context_obj(struct drm_device *dev, size_t size)
 	return obj;
 }
 
+static void i915_ppgtt_close(struct i915_address_space *vm)
+{
+	struct list_head *phases[] = {
+		&vm->active_list,
+		&vm->inactive_list,
+		&vm->unbound_list,
+		NULL,
+	}, **phase;
+
+	RQ_BUG_ON(vm->is_ggtt);
+	RQ_BUG_ON(vm->closed);
+	vm->closed = true;
+
+	for (phase = phases; *phase; phase++) {
+		struct i915_vma *vma, *vn;
+
+		list_for_each_entry_safe(vma, vn, *phase, vm_link)
+			i915_vma_close(vma);
+	}
+}
+
+static void context_close(struct intel_context *ctx)
+{
+	RQ_BUG_ON(ctx->closed);
+	ctx->closed = true;
+	if (ctx->ppgtt)
+		i915_ppgtt_close(&ctx->ppgtt->base);
+	i915_gem_context_unreference(ctx);
+}
+
 static struct intel_context *
 __create_hw_context(struct drm_device *dev,
 		    struct drm_i915_file_private *file_priv)
@@ -256,7 +287,7 @@ __create_hw_context(struct drm_device *dev,
 	return ctx;
 
 err_out:
-	i915_gem_context_unreference(ctx);
+	context_close(ctx);
 	return ERR_PTR(ret);
 }
 
@@ -318,7 +349,7 @@ err_unpin:
 		i915_gem_object_ggtt_unpin(ctx->legacy_hw_ctx.rcs_state);
 err_destroy:
 	idr_remove(&file_priv->context_idr, ctx->user_handle);
-	i915_gem_context_unreference(ctx);
+	context_close(ctx);
 	return ERR_PTR(ret);
 }
 
@@ -470,7 +501,7 @@ static int context_idr_cleanup(int id, void *p, void *data)
 {
 	struct intel_context *ctx = p;
 
-	i915_gem_context_unreference(ctx);
+	context_close(ctx);
 	return 0;
 }
 
@@ -894,7 +925,7 @@ int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
 	}
 
 	idr_remove(&ctx->file_priv->context_idr, ctx->user_handle);
-	i915_gem_context_unreference(ctx);
+	context_close(ctx);
 	mutex_unlock(&dev->struct_mutex);
 
 	DRM_DEBUG_DRIVER("HW context %d destroyed\n", args->ctx_id);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 9f594c33bd0a..354236d72432 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2130,6 +2130,7 @@ static void i915_address_space_init(struct i915_address_space *vm,
 	vm->dev = dev_priv->dev;
 	INIT_LIST_HEAD(&vm->active_list);
 	INIT_LIST_HEAD(&vm->inactive_list);
+	INIT_LIST_HEAD(&vm->unbound_list);
 	list_add_tail(&vm->global_link, &dev_priv->vm_list);
 }
 
@@ -2214,9 +2215,10 @@ void  i915_ppgtt_release(struct kref *kref)
 
 	trace_i915_ppgtt_release(&ppgtt->base);
 
-	/* vmas should already be unbound */
+	/* vmas should already be unbound and destroyed */
 	WARN_ON(!list_empty(&ppgtt->base.active_list));
 	WARN_ON(!list_empty(&ppgtt->base.inactive_list));
+	WARN_ON(!list_empty(&ppgtt->base.unbound_list));
 
 	list_del(&ppgtt->base.global_link);
 	drm_mm_takedown(&ppgtt->base.mm);
@@ -2698,7 +2700,7 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
 			return ret;
 		}
 		vma->bound |= GLOBAL_BIND;
-		list_add_tail(&vma->vm_link, &ggtt_vm->inactive_list);
+		list_move_tail(&vma->vm_link, &ggtt_vm->inactive_list);
 	}
 
 	/* Clear any non-preallocated blocks */
@@ -3252,6 +3254,8 @@ __i915_gem_vma_create(struct drm_i915_gem_object *obj,
 	struct i915_vma *vma;
 	int i;
 
+	RQ_BUG_ON(vm->closed);
+
 	if (WARN_ON(i915_is_ggtt(vm) != !!ggtt_view))
 		return ERR_PTR(-EINVAL);
 
@@ -3259,11 +3263,11 @@ __i915_gem_vma_create(struct drm_i915_gem_object *obj,
 	if (vma == NULL)
 		return ERR_PTR(-ENOMEM);
 
-	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);
+	list_add(&vma->vm_link, &vm->unbound_list);
 	vma->vm = vm;
 	vma->obj = obj;
 	vma->is_ggtt = i915_is_ggtt(vm);
@@ -3310,6 +3314,7 @@ i915_gem_obj_lookup_or_create_ggtt_vma(struct drm_i915_gem_object *obj,
 	if (!vma)
 		vma = __i915_gem_vma_create(obj, ggtt, view);
 
+	RQ_BUG_ON(vma->closed);
 	return vma;
 
 }
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index be7e8526b219..3bd2a4f4990c 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -284,6 +284,8 @@ struct i915_address_space {
 	u64 start;		/* Start offset always 0 for dri2 */
 	u64 total;		/* size addr space maps (ex. 2GB for ggtt) */
 
+	bool closed;
+
 	struct i915_page_scratch *scratch_page;
 	struct i915_page_table *scratch_pt;
 	struct i915_page_directory *scratch_pd;
@@ -312,6 +314,13 @@ struct i915_address_space {
 	 */
 	struct list_head inactive_list;
 
+	/**
+	 * List of vma that have been unbound.
+	 *
+	 * A reference is not held on the buffer while on this list.
+	 */
+	struct list_head unbound_list;
+
 	/* FIXME: Need a more generic return type */
 	gen6_pte_t (*pte_encode)(dma_addr_t addr,
 				 enum i915_cache_level level,
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index 305d58a5f745..4a803311f5bf 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -688,7 +688,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
 		}
 
 		vma->bound |= GLOBAL_BIND;
-		list_add_tail(&vma->vm_link, &ggtt->inactive_list);
+		list_move_tail(&vma->vm_link, &ggtt->inactive_list);
 	}
 
 	list_add_tail(&obj->global_list, &dev_priv->mm.bound_list);
-- 
2.6.4

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

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

* [PATCH 11/11] Revert "drm/i915: Clean up associated VMAs on context destruction"
  2015-12-14 11:36 [PATCH 01/11] drm/i915: Introduce drm_i915_gem_request_node for request tracking Chris Wilson
                   ` (8 preceding siblings ...)
  2015-12-14 11:36 ` [PATCH 10/11] drm/i915: Mark the context and address space as closed Chris Wilson
@ 2015-12-14 11:36 ` Chris Wilson
  2015-12-14 15:58 ` [PATCH 01/11] drm/i915: Introduce drm_i915_gem_request_node for request tracking Tvrtko Ursulin
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 37+ messages in thread
From: Chris Wilson @ 2015-12-14 11:36 UTC (permalink / raw)
  To: intel-gfx

This reverts commit e9f24d5fb7cf3628b195b18ff3ac4e37937ceeae.

The patch was incomplete, introduced more problems of greater severity
than it solved and worse the solution was known and available at the
time of the patch.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_drv.h         |  5 -----
 drivers/gpu/drm/i915/i915_gem.c         | 14 ++------------
 drivers/gpu/drm/i915/i915_gem_context.c | 22 ----------------------
 3 files changed, 2 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 66ecd6b3df95..32427a063213 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2717,11 +2717,6 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
 int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level,
 		  u32 flags);
 int __must_check i915_vma_unbind(struct i915_vma *vma);
-/*
- * BEWARE: Do not use the function below unless you can _absolutely_
- * _guarantee_ VMA in question is _not in use_ anywhere.
- */
-int __must_check __i915_vma_unbind_no_wait(struct i915_vma *vma);
 void i915_vma_close(struct i915_vma *vma);
 
 int i915_gem_object_put_pages(struct drm_i915_gem_object *obj);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 08ea0b7eda8b..566eb4338497 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2584,7 +2584,7 @@ static void i915_gem_object_finish_gtt(struct drm_i915_gem_object *obj)
 					    old_write_domain);
 }
 
-static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
+int i915_vma_unbind(struct i915_vma *vma)
 {
 	struct drm_i915_gem_object *obj = vma->obj;
 	struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
@@ -2593,7 +2593,7 @@ static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
 	/* First wait upon any activity as retiring the request may
 	 * have side-effects such as unpinning or even unbinding this vma.
 	 */
-	if (vma->active && wait) {
+	if (vma->active) {
 		for (i = 0; i < ARRAY_SIZE(vma->last_read); i++) {
 			ret = i915_wait_request(vma->last_read[i].request);
 			if (ret)
@@ -2655,16 +2655,6 @@ static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
 	return 0;
 }
 
-int i915_vma_unbind(struct i915_vma *vma)
-{
-	return __i915_vma_unbind(vma, true);
-}
-
-int __i915_vma_unbind_no_wait(struct i915_vma *vma)
-{
-	return __i915_vma_unbind(vma, false);
-}
-
 int i915_gpu_idle(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 9669547c7c2d..40250667fcf2 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -133,21 +133,6 @@ static int get_context_size(struct drm_device *dev)
 	return ret;
 }
 
-static void i915_gem_context_clean(struct intel_context *ctx)
-{
-	struct i915_hw_ppgtt *ppgtt = ctx->ppgtt;
-	struct i915_vma *vma, *next;
-
-	if (!ppgtt)
-		return;
-
-	list_for_each_entry_safe(vma, next, &ppgtt->base.inactive_list,
-				 vm_link) {
-		if (WARN_ON(__i915_vma_unbind_no_wait(vma)))
-			break;
-	}
-}
-
 void i915_gem_context_free(struct kref *ctx_ref)
 {
 	struct intel_context *ctx = container_of(ctx_ref, typeof(*ctx), ref);
@@ -158,13 +143,6 @@ void i915_gem_context_free(struct kref *ctx_ref)
 	if (i915.enable_execlists)
 		intel_lr_context_free(ctx);
 
-	/*
-	 * This context is going away and we need to remove all VMAs still
-	 * around. This is to handle imported shared objects for which
-	 * destructor did not run when their handles were closed.
-	 */
-	i915_gem_context_clean(ctx);
-
 	i915_ppgtt_put(ctx->ppgtt);
 
 	if (ctx->legacy_hw_ctx.rcs_state)
-- 
2.6.4

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

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

* Re: [PATCH 01/11] drm/i915: Introduce drm_i915_gem_request_node for request tracking
  2015-12-14 11:36 [PATCH 01/11] drm/i915: Introduce drm_i915_gem_request_node for request tracking Chris Wilson
                   ` (9 preceding siblings ...)
  2015-12-14 11:36 ` [PATCH 11/11] Revert "drm/i915: Clean up associated VMAs on context destruction" Chris Wilson
@ 2015-12-14 15:58 ` Tvrtko Ursulin
  2015-12-14 16:11   ` Chris Wilson
  2015-12-15 10:51 ` [PATCH v2] drm/i915: Introduce drm_i915_gem_request_active " Chris Wilson
  2015-12-17 14:48 ` ✗ failure: UK.CI.checkpatch.pl Patchwork
  12 siblings, 1 reply; 37+ messages in thread
From: Tvrtko Ursulin @ 2015-12-14 15:58 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


Hi,


On 14/12/15 11:36, Chris Wilson wrote:
> In the next patch, request tracking is made more generic and for that we
> need a new expanded struct and to separate out the logic changes from
> the mechanical churn, we split out the structure renaming into this
> patch. For extra fun, create a new i915_gem_request.h.

Subject and patch disagree on the new structure name. :)

Could you draw a nice diagram demonstrating the new design? It is not 
straightforward to derive it from the patch series.

Emphasis on relationships between engines, requests and request_active etc.

Also I notice even though you later add vma->last_read, I don't see that 
obj->last_read is never removed.

Regards,

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

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

* Re: [PATCH 01/11] drm/i915: Introduce drm_i915_gem_request_node for request tracking
  2015-12-14 15:58 ` [PATCH 01/11] drm/i915: Introduce drm_i915_gem_request_node for request tracking Tvrtko Ursulin
@ 2015-12-14 16:11   ` Chris Wilson
  0 siblings, 0 replies; 37+ messages in thread
From: Chris Wilson @ 2015-12-14 16:11 UTC (permalink / raw)
  To: Tvrtko Ursulin; +Cc: intel-gfx

On Mon, Dec 14, 2015 at 03:58:42PM +0000, Tvrtko Ursulin wrote:
> 
> Hi,
> 
> 
> On 14/12/15 11:36, Chris Wilson wrote:
> >In the next patch, request tracking is made more generic and for that we
> >need a new expanded struct and to separate out the logic changes from
> >the mechanical churn, we split out the structure renaming into this
> >patch. For extra fun, create a new i915_gem_request.h.
> 
> Subject and patch disagree on the new structure name. :)
> 
> Could you draw a nice diagram demonstrating the new design? It is
> not straightforward to derive it from the patch series.
>
> Emphasis on relationships between engines, requests and request_active etc.

It's the same as before. Instead of explicitly named functions to call
on retiring, you have a list of callbacks.
 
> Also I notice even though you later add vma->last_read, I don't see
> that obj->last_read is never removed.

Why would it? obj is for the GEM api, vma is for internal - they have
different lifetimes and track different state as I thought I explained.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH v2] drm/i915: Introduce drm_i915_gem_request_active for request tracking
  2015-12-14 11:36 [PATCH 01/11] drm/i915: Introduce drm_i915_gem_request_node for request tracking Chris Wilson
                   ` (10 preceding siblings ...)
  2015-12-14 15:58 ` [PATCH 01/11] drm/i915: Introduce drm_i915_gem_request_node for request tracking Tvrtko Ursulin
@ 2015-12-15 10:51 ` Chris Wilson
  2015-12-17 14:48 ` ✗ failure: UK.CI.checkpatch.pl Patchwork
  12 siblings, 0 replies; 37+ messages in thread
From: Chris Wilson @ 2015-12-15 10:51 UTC (permalink / raw)
  To: intel-gfx

In the next patch, request tracking is made more generic and for that we
need a new expanded struct and to separate out the logic changes from
the mechanical churn, we split out the structure renaming into this
patch.

v2: Writer's block. Add some spiel about why we track requests.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_debugfs.c        | 10 +++---
 drivers/gpu/drm/i915/i915_drv.h            |  9 +++--
 drivers/gpu/drm/i915/i915_gem.c            | 56 +++++++++++++++---------------
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |  4 +--
 drivers/gpu/drm/i915/i915_gem_fence.c      |  6 ++--
 drivers/gpu/drm/i915/i915_gem_request.h    | 37 ++++++++++++++++++++
 drivers/gpu/drm/i915/i915_gem_tiling.c     |  2 +-
 drivers/gpu/drm/i915/i915_gpu_error.c      |  6 ++--
 drivers/gpu/drm/i915/intel_display.c       | 10 +++---
 9 files changed, 88 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 77bae3151fca..dafc58b94c9f 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -146,10 +146,10 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
 		   obj->base.write_domain);
 	for_each_ring(ring, dev_priv, i)
 		seq_printf(m, "%x ",
-				i915_gem_request_get_seqno(obj->last_read_req[i]));
+				i915_gem_request_get_seqno(obj->last_read[i].request));
 	seq_printf(m, "] %x %x%s%s%s",
-		   i915_gem_request_get_seqno(obj->last_write_req),
-		   i915_gem_request_get_seqno(obj->last_fenced_req),
+		   i915_gem_request_get_seqno(obj->last_write.request),
+		   i915_gem_request_get_seqno(obj->last_fence.request),
 		   i915_cache_level_str(to_i915(obj->base.dev), obj->cache_level),
 		   obj->dirty ? " dirty" : "",
 		   obj->madv == I915_MADV_DONTNEED ? " purgeable" : "");
@@ -184,8 +184,8 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
 		*t = '\0';
 		seq_printf(m, " (%s mappable)", s);
 	}
-	if (obj->last_write_req != NULL)
-		seq_printf(m, " (%s)", obj->last_write_req->engine->name);
+	if (obj->last_write.request != NULL)
+		seq_printf(m, " (%s)", obj->last_write.request->engine->name);
 	if (obj->frontbuffer_bits)
 		seq_printf(m, " (frontbuffer: 0x%03x)", obj->frontbuffer_bits);
 }
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 426a0eade0f8..49ef9b04456e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2102,11 +2102,10 @@ struct drm_i915_gem_object {
 	 * requests on one ring where the write request is older than the
 	 * read request. This allows for the CPU to read from an active
 	 * buffer by only waiting for the write to complete.
-	 * */
-	struct drm_i915_gem_request *last_read_req[I915_NUM_RINGS];
-	struct drm_i915_gem_request *last_write_req;
-	/** Breadcrumb of last fenced GPU access to the buffer. */
-	struct drm_i915_gem_request *last_fenced_req;
+	 */
+	struct drm_i915_gem_request_active last_read[I915_NUM_RINGS];
+	struct drm_i915_gem_request_active last_write;
+	struct drm_i915_gem_request_active last_fence;
 
 	/** Current tiling stride for the object, if it's tiled. */
 	uint32_t stride;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index e85fd7746171..d46dc7f348a0 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1119,23 +1119,23 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
 		return 0;
 
 	if (readonly) {
-		if (obj->last_write_req != NULL) {
-			ret = i915_wait_request(obj->last_write_req);
+		if (obj->last_write.request != NULL) {
+			ret = i915_wait_request(obj->last_write.request);
 			if (ret)
 				return ret;
 
-			i = obj->last_write_req->engine->id;
-			if (obj->last_read_req[i] == obj->last_write_req)
+			i = obj->last_write.request->engine->id;
+			if (obj->last_read[i].request == obj->last_write.request)
 				i915_gem_object_retire__read(obj, i);
 			else
 				i915_gem_object_retire__write(obj);
 		}
 	} else {
 		for (i = 0; i < I915_NUM_RINGS; i++) {
-			if (obj->last_read_req[i] == NULL)
+			if (obj->last_read[i].request == NULL)
 				continue;
 
-			ret = i915_wait_request(obj->last_read_req[i]);
+			ret = i915_wait_request(obj->last_read[i].request);
 			if (ret)
 				return ret;
 
@@ -1153,9 +1153,9 @@ i915_gem_object_retire_request(struct drm_i915_gem_object *obj,
 {
 	int ring = req->engine->id;
 
-	if (obj->last_read_req[ring] == req)
+	if (obj->last_read[ring].request == req)
 		i915_gem_object_retire__read(obj, ring);
-	else if (obj->last_write_req == req)
+	else if (obj->last_write.request == req)
 		i915_gem_object_retire__write(obj);
 
 	i915_gem_request_retire_upto(req);
@@ -1183,7 +1183,7 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj,
 	if (readonly) {
 		struct drm_i915_gem_request *req;
 
-		req = obj->last_write_req;
+		req = obj->last_write.request;
 		if (req == NULL)
 			return 0;
 
@@ -1192,7 +1192,7 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj,
 		for (i = 0; i < I915_NUM_RINGS; i++) {
 			struct drm_i915_gem_request *req;
 
-			req = obj->last_read_req[i];
+			req = obj->last_read[i].request;
 			if (req == NULL)
 				continue;
 
@@ -2062,7 +2062,7 @@ void i915_vma_move_to_active(struct i915_vma *vma,
 	obj->active |= intel_engine_flag(engine);
 
 	list_move_tail(&obj->ring_list[engine->id], &engine->active_list);
-	i915_gem_request_assign(&obj->last_read_req[engine->id], req);
+	i915_gem_request_mark_active(req, &obj->last_read[engine->id]);
 
 	list_move_tail(&vma->mm_list, &vma->vm->active_list);
 }
@@ -2070,10 +2070,10 @@ void i915_vma_move_to_active(struct i915_vma *vma,
 static void
 i915_gem_object_retire__write(struct drm_i915_gem_object *obj)
 {
-	RQ_BUG_ON(obj->last_write_req == NULL);
-	RQ_BUG_ON(!(obj->active & intel_engine_flag(obj->last_write_req->engine)));
+	RQ_BUG_ON(obj->last_write.request == NULL);
+	RQ_BUG_ON(!(obj->active & intel_engine_flag(obj->last_write.request->engine)));
 
-	i915_gem_request_assign(&obj->last_write_req, NULL);
+	i915_gem_request_assign(&obj->last_write.request, NULL);
 	intel_fb_obj_flush(obj, true, ORIGIN_CS);
 }
 
@@ -2082,13 +2082,13 @@ i915_gem_object_retire__read(struct drm_i915_gem_object *obj, int ring)
 {
 	struct i915_vma *vma;
 
-	RQ_BUG_ON(obj->last_read_req[ring] == NULL);
+	RQ_BUG_ON(obj->last_read[ring].request == NULL);
 	RQ_BUG_ON(!(obj->active & (1 << ring)));
 
 	list_del_init(&obj->ring_list[ring]);
-	i915_gem_request_assign(&obj->last_read_req[ring], NULL);
+	i915_gem_request_assign(&obj->last_read[ring].request, NULL);
 
-	if (obj->last_write_req && obj->last_write_req->engine->id == ring)
+	if (obj->last_write.request && obj->last_write.request->engine->id == ring)
 		i915_gem_object_retire__write(obj);
 
 	obj->active &= ~(1 << ring);
@@ -2107,7 +2107,7 @@ i915_gem_object_retire__read(struct drm_i915_gem_object *obj, int ring)
 			list_move_tail(&vma->mm_list, &vma->vm->inactive_list);
 	}
 
-	i915_gem_request_assign(&obj->last_fenced_req, NULL);
+	i915_gem_request_assign(&obj->last_fence.request, NULL);
 	drm_gem_object_unreference(&obj->base);
 }
 
@@ -2334,7 +2334,7 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
 				      struct drm_i915_gem_object,
 				      ring_list[ring->id]);
 
-		if (!list_empty(&obj->last_read_req[ring->id]->list))
+		if (!list_empty(&obj->last_read[ring->id].request->list))
 			break;
 
 		i915_gem_object_retire__read(obj, ring->id);
@@ -2437,7 +2437,7 @@ i915_gem_object_flush_active(struct drm_i915_gem_object *obj)
 	for (i = 0; i < I915_NUM_RINGS; i++) {
 		struct drm_i915_gem_request *req;
 
-		req = obj->last_read_req[i];
+		req = obj->last_read[i].request;
 		if (req == NULL)
 			continue;
 
@@ -2517,10 +2517,10 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
 	drm_gem_object_unreference(&obj->base);
 
 	for (i = 0; i < I915_NUM_RINGS; i++) {
-		if (obj->last_read_req[i] == NULL)
+		if (obj->last_read[i].request == NULL)
 			continue;
 
-		req[n++] = i915_gem_request_reference(obj->last_read_req[i]);
+		req[n++] = i915_gem_request_reference(obj->last_read[i].request);
 	}
 
 	mutex_unlock(&dev->struct_mutex);
@@ -2611,12 +2611,12 @@ i915_gem_object_sync(struct drm_i915_gem_object *obj,
 
 	n = 0;
 	if (readonly) {
-		if (obj->last_write_req)
-			req[n++] = obj->last_write_req;
+		if (obj->last_write.request)
+			req[n++] = obj->last_write.request;
 	} else {
 		for (i = 0; i < I915_NUM_RINGS; i++)
-			if (obj->last_read_req[i])
-				req[n++] = obj->last_read_req[i];
+			if (obj->last_read[i].request)
+				req[n++] = obj->last_read[i].request;
 	}
 	for (i = 0; i < n; i++) {
 		ret = __i915_gem_object_sync(obj, to, req[i]);
@@ -3688,8 +3688,8 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
 
 	BUILD_BUG_ON(I915_NUM_RINGS > 16);
 	args->busy = obj->active << 16;
-	if (obj->last_write_req)
-		args->busy |= obj->last_write_req->engine->id;
+	if (obj->last_write.request)
+		args->busy |= obj->last_write.request->engine->id;
 
 unref:
 	drm_gem_object_unreference(&obj->base);
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 9b5f63f118bb..667b9b1e8700 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1085,7 +1085,7 @@ i915_gem_execbuffer_move_to_active(struct list_head *vmas,
 
 		i915_vma_move_to_active(vma, req);
 		if (obj->base.write_domain) {
-			i915_gem_request_assign(&obj->last_write_req, req);
+			i915_gem_request_mark_active(req, &obj->last_write);
 
 			intel_fb_obj_invalidate(obj, ORIGIN_CS);
 
@@ -1093,7 +1093,7 @@ i915_gem_execbuffer_move_to_active(struct list_head *vmas,
 			obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS;
 		}
 		if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) {
-			i915_gem_request_assign(&obj->last_fenced_req, req);
+			i915_gem_request_mark_active(req, &obj->last_fence);
 			if (entry->flags & __EXEC_OBJECT_HAS_FENCE) {
 				struct drm_i915_private *dev_priv = req->i915;
 				list_move_tail(&dev_priv->fence_regs[obj->fence_reg].lru_list,
diff --git a/drivers/gpu/drm/i915/i915_gem_fence.c b/drivers/gpu/drm/i915/i915_gem_fence.c
index 598198543dcd..ab29c237ffa9 100644
--- a/drivers/gpu/drm/i915/i915_gem_fence.c
+++ b/drivers/gpu/drm/i915/i915_gem_fence.c
@@ -261,12 +261,12 @@ static inline void i915_gem_object_fence_lost(struct drm_i915_gem_object *obj)
 static int
 i915_gem_object_wait_fence(struct drm_i915_gem_object *obj)
 {
-	if (obj->last_fenced_req) {
-		int ret = i915_wait_request(obj->last_fenced_req);
+	if (obj->last_fence.request) {
+		int ret = i915_wait_request(obj->last_fence.request);
 		if (ret)
 			return ret;
 
-		i915_gem_request_assign(&obj->last_fenced_req, NULL);
+		i915_gem_request_assign(&obj->last_fence.request, NULL);
 	}
 
 	return 0;
diff --git a/drivers/gpu/drm/i915/i915_gem_request.h b/drivers/gpu/drm/i915/i915_gem_request.h
index 83a8115d9b96..ae8eed22e294 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.h
+++ b/drivers/gpu/drm/i915/i915_gem_request.h
@@ -200,4 +200,41 @@ static inline bool i915_gem_request_completed(struct drm_i915_gem_request *req)
 				 req->fence.seqno);
 }
 
+/* We treat requests as fences. This is not be to confused with our
+ * "fence registers" but pipeline synchronisation objects ala GL_ARB_sync.
+ * We use the fences to synchronize access from the CPU with activity on the
+ * GPU, for example, we should not rewrite an object's PTE whilst the GPU
+ * is reading them. We also track fences at a higher level to provide
+ * implicit synchronisation around GEM objects, e.g. set-domain will wait
+ * for outstanding GPU rendering before marking the object ready for CPU
+ * access.
+ *
+ * In order to use a fence, the object must track the fence it needs to
+ * serialise with. For example, GEM objects want to track both read and
+ * write access so that we can perform concurrent read operations between
+ * the CPU and GPU engines, as well as waiting for all rendering to
+ * complete or waiting for the last GPU user of a "fence register". The object
+ * then embeds a @drm_i915_gem_request_active to track the most recent (in
+ * retirment order) request relevant for the desired mode of access.
+ * The @drm_i915_gem_request_active is updated with
+ * i915_gem_request_mark_active() to track the most recent fence request,
+ * typically this is done as part of i915_vma_move_to_active().
+ *
+ * When the @drm_i915_gem_request_active completes (is retired), it will
+ * signal its completion to the owner through a callback as well as mark
+ * itself as idle (drm_i915_gem_request_active.request == NULL). The owner
+ * can then perform any action, such as delayed freeing of an active
+ * resource including itself.
+ */
+struct drm_i915_gem_request_active {
+	struct drm_i915_gem_request *request;
+};
+
+static inline void
+i915_gem_request_mark_active(struct drm_i915_gem_request *request,
+			     struct drm_i915_gem_request_active *active)
+{
+	i915_gem_request_assign(&active->request, request);
+}
+
 #endif /* I915_GEM_REQUEST_H */
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index 7410f6c962e7..c7588135a82d 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -242,7 +242,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
 			}
 
 			obj->fence_dirty =
-				obj->last_fenced_req ||
+				obj->last_fence.request ||
 				obj->fence_reg != I915_FENCE_REG_NONE;
 
 			obj->tiling_mode = args->tiling_mode;
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 9b708fa304aa..82baa370ae09 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -708,8 +708,8 @@ static void capture_bo(struct drm_i915_error_buffer *err,
 	err->size = obj->base.size;
 	err->name = obj->base.name;
 	for (i = 0; i < I915_NUM_RINGS; i++)
-		err->rseqno[i] = i915_gem_request_get_seqno(obj->last_read_req[i]);
-	err->wseqno = i915_gem_request_get_seqno(obj->last_write_req);
+		err->rseqno[i] = i915_gem_request_get_seqno(obj->last_read[i].request);
+	err->wseqno = i915_gem_request_get_seqno(obj->last_write.request);
 	err->gtt_offset = vma->node.start;
 	err->read_domains = obj->base.read_domains;
 	err->write_domain = obj->base.write_domain;
@@ -721,7 +721,7 @@ static void capture_bo(struct drm_i915_error_buffer *err,
 	err->dirty = obj->dirty;
 	err->purgeable = obj->madv != I915_MADV_WILLNEED;
 	err->userptr = obj->userptr.mm != NULL;
-	err->ring = obj->last_write_req ?  obj->last_write_req->engine->id : -1;
+	err->ring = obj->last_write.request ? obj->last_write.request->engine->id : -1;
 	err->cache_level = obj->cache_level;
 }
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f6ec3b5d846d..db461b120299 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11246,7 +11246,7 @@ static bool use_mmio_flip(struct intel_engine_cs *ring,
 						       false))
 		return true;
 	else
-		return ring != i915_gem_request_get_engine(obj->last_write_req);
+		return ring != i915_gem_request_get_engine(obj->last_write.request);
 }
 
 static void skl_do_mmio_flip(struct intel_crtc *intel_crtc,
@@ -11391,7 +11391,7 @@ static int intel_queue_mmio_flip(struct drm_device *dev,
 		return -ENOMEM;
 
 	mmio_flip->i915 = to_i915(dev);
-	mmio_flip->req = i915_gem_request_reference(obj->last_write_req);
+	mmio_flip->req = i915_gem_request_reference(obj->last_write.request);
 	mmio_flip->crtc = to_intel_crtc(crtc);
 	mmio_flip->rotation = crtc->primary->state->rotation;
 
@@ -11590,7 +11590,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 	} else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) {
 		ring = &dev_priv->ring[BCS];
 	} else if (INTEL_INFO(dev)->gen >= 7) {
-		ring = i915_gem_request_get_engine(obj->last_write_req);
+		ring = i915_gem_request_get_engine(obj->last_write.request);
 		if (ring == NULL || ring->id != RCS)
 			ring = &dev_priv->ring[BCS];
 	} else {
@@ -11631,7 +11631,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 			goto cleanup_unpin;
 
 		i915_gem_request_assign(&work->flip_queued_req,
-					obj->last_write_req);
+					obj->last_write.request);
 	} else {
 		ret = dev_priv->display.queue_flip(dev, crtc, fb, obj, request,
 						   page_flip_flags);
@@ -13745,7 +13745,7 @@ intel_prepare_plane_fb(struct drm_plane *plane,
 				to_intel_plane_state(new_state);
 
 			i915_gem_request_assign(&plane_state->wait_req,
-						obj->last_write_req);
+						obj->last_write.request);
 		}
 
 		i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit);
-- 
2.6.4

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

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

* Re: [PATCH 02/11] drm/i915: Refactor activity tracking for requests
  2015-12-14 11:36 ` [PATCH 02/11] drm/i915: Refactor activity tracking for requests Chris Wilson
@ 2015-12-16 17:16   ` Tvrtko Ursulin
  2015-12-16 17:31     ` Chris Wilson
  0 siblings, 1 reply; 37+ messages in thread
From: Tvrtko Ursulin @ 2015-12-16 17:16 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


Hi,

On 14/12/15 11:36, Chris Wilson wrote:
> With the introduction of requests, we amplified the number of atomic
> refcounted objects we use and update every execbuffer; from none to
> several references, and a set of references that need to be changed. We
> also introduced interesting side-effects in the order of retiring
> requests and objects.
>
> Instead of independently tracking the last request for an object, track
> the active objects for each request. The object will reside in the
> buffer list of its most recent active request and so we reduce the kref
> interchange to a list_move. Now retirements are entirely driven by the
> request, dramatically simplifying activity tracking on the object
> themselves, and removing the ambiguity between retiring objects and
> retiring requests.
>
> All told, less code, simpler and faster, and more extensible.

I get the general idea but it seems unfinished. For example there is no 
handling for last_write and last_fence. So as for bisectability 
requirement it does not seem appropriate.

I also wanted to suggest splitting out the req->list to link renaming 
but see you've already done it in your branch.

I915_BO_ACTIVE_SHIFT is undefined up to and including this patch.

Variable naming conventions for requests is still a mess but whatever.

And I don't like drm_i915_gem_request_active, wouldn't 
drm_i915_gem_active_request be better?

Regards,

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

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

* Re: [PATCH 02/11] drm/i915: Refactor activity tracking for requests
  2015-12-16 17:16   ` Tvrtko Ursulin
@ 2015-12-16 17:31     ` Chris Wilson
  0 siblings, 0 replies; 37+ messages in thread
From: Chris Wilson @ 2015-12-16 17:31 UTC (permalink / raw)
  To: Tvrtko Ursulin; +Cc: intel-gfx

On Wed, Dec 16, 2015 at 05:16:19PM +0000, Tvrtko Ursulin wrote:
> 
> Hi,
> 
> On 14/12/15 11:36, Chris Wilson wrote:
> >With the introduction of requests, we amplified the number of atomic
> >refcounted objects we use and update every execbuffer; from none to
> >several references, and a set of references that need to be changed. We
> >also introduced interesting side-effects in the order of retiring
> >requests and objects.
> >
> >Instead of independently tracking the last request for an object, track
> >the active objects for each request. The object will reside in the
> >buffer list of its most recent active request and so we reduce the kref
> >interchange to a list_move. Now retirements are entirely driven by the
> >request, dramatically simplifying activity tracking on the object
> >themselves, and removing the ambiguity between retiring objects and
> >retiring requests.
> >
> >All told, less code, simpler and faster, and more extensible.
> 
> I get the general idea but it seems unfinished. For example there is
> no handling for last_write and last_fence. So as for bisectability
> requirement it does not seem appropriate.

Pardon. It is there, working and complete. If it wasn't for rebasing, it
would have ~10 months of testing behind it. Plus comparable
implementations in userspace.

last_fence is no a no-op (we just need to track the request, we don't
need to anything special when it completes, I provided a stub callback
for the rare case rather than have a conditional function call),
last_write just needs to update the status on the framebuffer object.
 
> I also wanted to suggest splitting out the req->list to link
> renaming but see you've already done it in your branch.
> 
> I915_BO_ACTIVE_SHIFT is undefined up to and including this patch.

The curse of rebasing.

> Variable naming conventions for requests is still a mess but whatever.

I know, I am slowly fixing it up.
 
> And I don't like drm_i915_gem_request_active, wouldn't
> drm_i915_gem_active_request be better?

Yeah, active_request is better. Still lacks something.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 03/11] drm/i915: Rename vma->*_list to *_link for consistency
  2015-12-14 11:36 ` [PATCH 03/11] drm/i915: Rename vma->*_list to *_link for consistency Chris Wilson
@ 2015-12-17 11:14   ` Tvrtko Ursulin
  2015-12-17 11:24     ` Chris Wilson
  0 siblings, 1 reply; 37+ messages in thread
From: Tvrtko Ursulin @ 2015-12-17 11:14 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


On 14/12/15 11:36, Chris Wilson wrote:
> Elsewhere we have adopted the convention of using '_link' to denote
> elements in the list (and '_list' for the actual list_head itself), and
> that the name should indicate which list the link belongs to (and
> preferrably not just where the link is being stored).
>
> s/vma_link/obj_link/ (we iterate over obj->vma_list)
> s/mm_list/vm_link/ (we iterate over vm->[in]active_list)

A little bit of pain for the established muscle memory but I think good 
in general. Assuming you compile tested it:

Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

Btw perhaps rename the link in  i915_gem_active to request_link so that 
the good initiative is not questioned. :)

Regards,

Tvrtko

>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>   drivers/gpu/drm/i915/i915_debugfs.c      | 17 +++++------
>   drivers/gpu/drm/i915/i915_gem.c          | 50 ++++++++++++++++----------------
>   drivers/gpu/drm/i915/i915_gem_context.c  |  2 +-
>   drivers/gpu/drm/i915/i915_gem_evict.c    |  6 ++--
>   drivers/gpu/drm/i915/i915_gem_gtt.c      | 10 +++----
>   drivers/gpu/drm/i915/i915_gem_gtt.h      |  4 +--
>   drivers/gpu/drm/i915/i915_gem_shrinker.c |  4 +--
>   drivers/gpu/drm/i915/i915_gem_stolen.c   |  2 +-
>   drivers/gpu/drm/i915/i915_gem_userptr.c  |  2 +-
>   drivers/gpu/drm/i915/i915_gpu_error.c    |  8 ++---
>   10 files changed, 52 insertions(+), 53 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 68310ba73d23..fdcf90757eb0 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -117,9 +117,8 @@ static u64 i915_gem_obj_total_ggtt_size(struct drm_i915_gem_object *obj)
>   	u64 size = 0;
>   	struct i915_vma *vma;
>
> -	list_for_each_entry(vma, &obj->vma_list, vma_link) {
> -		if (i915_is_ggtt(vma->vm) &&
> -		    drm_mm_node_allocated(&vma->node))
> +	list_for_each_entry(vma, &obj->vma_list, obj_link) {
> +		if (i915_is_ggtt(vma->vm) && drm_mm_node_allocated(&vma->node))
>   			size += vma->node.size;
>   	}
>
> @@ -155,7 +154,7 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
>   		   obj->madv == I915_MADV_DONTNEED ? " purgeable" : "");
>   	if (obj->base.name)
>   		seq_printf(m, " (name: %d)", obj->base.name);
> -	list_for_each_entry(vma, &obj->vma_list, vma_link) {
> +	list_for_each_entry(vma, &obj->vma_list, obj_link) {
>   		if (vma->pin_count > 0)
>   			pin_count++;
>   	}
> @@ -164,7 +163,7 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
>   		seq_printf(m, " (display)");
>   	if (obj->fence_reg != I915_FENCE_REG_NONE)
>   		seq_printf(m, " (fence: %d)", obj->fence_reg);
> -	list_for_each_entry(vma, &obj->vma_list, vma_link) {
> +	list_for_each_entry(vma, &obj->vma_list, obj_link) {
>   		seq_printf(m, " (%sgtt offset: %08llx, size: %08llx",
>   			   i915_is_ggtt(vma->vm) ? "g" : "pp",
>   			   vma->node.start, vma->node.size);
> @@ -229,7 +228,7 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data)
>   	}
>
>   	total_obj_size = total_gtt_size = count = 0;
> -	list_for_each_entry(vma, head, mm_list) {
> +	list_for_each_entry(vma, head, vm_link) {
>   		seq_printf(m, "   ");
>   		describe_obj(m, vma->obj);
>   		seq_printf(m, "\n");
> @@ -341,7 +340,7 @@ static int per_file_stats(int id, void *ptr, void *data)
>   		stats->shared += obj->base.size;
>
>   	if (USES_FULL_PPGTT(obj->base.dev)) {
> -		list_for_each_entry(vma, &obj->vma_list, vma_link) {
> +		list_for_each_entry(vma, &obj->vma_list, obj_link) {
>   			struct i915_hw_ppgtt *ppgtt;
>
>   			if (!drm_mm_node_allocated(&vma->node))
> @@ -453,12 +452,12 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
>   		   count, mappable_count, size, mappable_size);
>
>   	size = count = mappable_size = mappable_count = 0;
> -	count_vmas(&vm->active_list, mm_list);
> +	count_vmas(&vm->active_list, vm_link);
>   	seq_printf(m, "  %u [%u] active objects, %llu [%llu] bytes\n",
>   		   count, mappable_count, size, mappable_size);
>
>   	size = count = mappable_size = mappable_count = 0;
> -	count_vmas(&vm->inactive_list, mm_list);
> +	count_vmas(&vm->inactive_list, vm_link);
>   	seq_printf(m, "  %u [%u] inactive objects, %llu [%llu] bytes\n",
>   		   count, mappable_count, size, mappable_size);
>
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index a7c39d5fbcca..e6ace74616b2 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -128,10 +128,10 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
>
>   	pinned = 0;
>   	mutex_lock(&dev->struct_mutex);
> -	list_for_each_entry(vma, &ggtt->base.active_list, mm_list)
> +	list_for_each_entry(vma, &ggtt->base.active_list, vm_link)
>   		if (vma->pin_count)
>   			pinned += vma->node.size;
> -	list_for_each_entry(vma, &ggtt->base.inactive_list, mm_list)
> +	list_for_each_entry(vma, &ggtt->base.inactive_list, vm_link)
>   		if (vma->pin_count)
>   			pinned += vma->node.size;
>   	mutex_unlock(&dev->struct_mutex);
> @@ -261,7 +261,7 @@ drop_pages(struct drm_i915_gem_object *obj)
>   	int ret;
>
>   	drm_gem_object_reference(&obj->base);
> -	list_for_each_entry_safe(vma, next, &obj->vma_list, vma_link)
> +	list_for_each_entry_safe(vma, next, &obj->vma_list, obj_link)
>   		if (i915_vma_unbind(vma))
>   			break;
>
> @@ -2028,7 +2028,7 @@ void i915_vma_move_to_active(struct i915_vma *vma,
>   	obj->active |= intel_engine_flag(engine);
>
>   	i915_gem_request_mark_active(req, &obj->last_read[engine->id]);
> -	list_move_tail(&vma->mm_list, &vma->vm->active_list);
> +	list_move_tail(&vma->vm_link, &vma->vm->active_list);
>   }
>
>   static void
> @@ -2069,9 +2069,9 @@ i915_gem_object_retire__read(struct drm_i915_gem_request_active *active,
>   	 */
>   	list_move_tail(&obj->global_list, &request->i915->mm.bound_list);
>
> -	list_for_each_entry(vma, &obj->vma_list, vma_link) {
> -		if (!list_empty(&vma->mm_list))
> -			list_move_tail(&vma->mm_list, &vma->vm->inactive_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);
>   	}
>
>   	drm_gem_object_unreference(&obj->base);
> @@ -2584,7 +2584,7 @@ static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
>   	struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
>   	int ret;
>
> -	if (list_empty(&vma->vma_link))
> +	if (list_empty(&vma->obj_link))
>   		return 0;
>
>   	if (!drm_mm_node_allocated(&vma->node)) {
> @@ -2618,7 +2618,7 @@ static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
>   	vma->vm->unbind_vma(vma);
>   	vma->bound = 0;
>
> -	list_del_init(&vma->mm_list);
> +	list_del_init(&vma->vm_link);
>   	if (i915_is_ggtt(vma->vm)) {
>   		if (vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) {
>   			obj->map_and_fenceable = false;
> @@ -2875,7 +2875,7 @@ search_free:
>   		goto err_remove_node;
>
>   	list_move_tail(&obj->global_list, &dev_priv->mm.bound_list);
> -	list_add_tail(&vma->mm_list, &vm->inactive_list);
> +	list_add_tail(&vma->vm_link, &vm->inactive_list);
>
>   	return vma;
>
> @@ -3040,7 +3040,7 @@ 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->mm_list,
> +		list_move_tail(&vma->vm_link,
>   			       &to_i915(obj->base.dev)->gtt.base.inactive_list);
>
>   	return 0;
> @@ -3075,7 +3075,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
>   	 * catch the issue of the CS prefetch crossing page boundaries and
>   	 * reading an invalid PTE on older architectures.
>   	 */
> -	list_for_each_entry_safe(vma, next, &obj->vma_list, vma_link) {
> +	list_for_each_entry_safe(vma, next, &obj->vma_list, obj_link) {
>   		if (!drm_mm_node_allocated(&vma->node))
>   			continue;
>
> @@ -3138,7 +3138,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
>   			 */
>   		}
>
> -		list_for_each_entry(vma, &obj->vma_list, vma_link) {
> +		list_for_each_entry(vma, &obj->vma_list, obj_link) {
>   			if (!drm_mm_node_allocated(&vma->node))
>   				continue;
>
> @@ -3148,7 +3148,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
>   		}
>   	}
>
> -	list_for_each_entry(vma, &obj->vma_list, vma_link)
> +	list_for_each_entry(vma, &obj->vma_list, obj_link)
>   		vma->node.color = cache_level;
>   	obj->cache_level = cache_level;
>
> @@ -3806,7 +3806,7 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
>
>   	trace_i915_gem_object_destroy(obj);
>
> -	list_for_each_entry_safe(vma, next, &obj->vma_list, vma_link) {
> +	list_for_each_entry_safe(vma, next, &obj->vma_list, obj_link) {
>   		int ret;
>
>   		vma->pin_count = 0;
> @@ -3863,7 +3863,7 @@ struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj,
>   				     struct i915_address_space *vm)
>   {
>   	struct i915_vma *vma;
> -	list_for_each_entry(vma, &obj->vma_list, vma_link) {
> +	list_for_each_entry(vma, &obj->vma_list, obj_link) {
>   		if (vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL &&
>   		    vma->vm == vm)
>   			return vma;
> @@ -3880,7 +3880,7 @@ struct i915_vma *i915_gem_obj_to_ggtt_view(struct drm_i915_gem_object *obj,
>   	if (WARN_ONCE(!view, "no view specified"))
>   		return ERR_PTR(-EINVAL);
>
> -	list_for_each_entry(vma, &obj->vma_list, vma_link)
> +	list_for_each_entry(vma, &obj->vma_list, obj_link)
>   		if (vma->vm == ggtt &&
>   		    i915_ggtt_view_equal(&vma->ggtt_view, view))
>   			return vma;
> @@ -3901,7 +3901,7 @@ void i915_gem_vma_destroy(struct i915_vma *vma)
>   	if (!i915_is_ggtt(vm))
>   		i915_ppgtt_put(i915_vm_to_ppgtt(vm));
>
> -	list_del(&vma->vma_link);
> +	list_del(&vma->obj_link);
>
>   	kmem_cache_free(to_i915(vma->obj->base.dev)->vmas, vma);
>   }
> @@ -4424,7 +4424,7 @@ u64 i915_gem_obj_offset(struct drm_i915_gem_object *o,
>
>   	WARN_ON(vm == &dev_priv->mm.aliasing_ppgtt->base);
>
> -	list_for_each_entry(vma, &o->vma_list, vma_link) {
> +	list_for_each_entry(vma, &o->vma_list, obj_link) {
>   		if (i915_is_ggtt(vma->vm) &&
>   		    vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
>   			continue;
> @@ -4443,7 +4443,7 @@ u64 i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o,
>   	struct i915_address_space *ggtt = i915_obj_to_ggtt(o);
>   	struct i915_vma *vma;
>
> -	list_for_each_entry(vma, &o->vma_list, vma_link)
> +	list_for_each_entry(vma, &o->vma_list, obj_link)
>   		if (vma->vm == ggtt &&
>   		    i915_ggtt_view_equal(&vma->ggtt_view, view))
>   			return vma->node.start;
> @@ -4457,7 +4457,7 @@ bool i915_gem_obj_bound(struct drm_i915_gem_object *o,
>   {
>   	struct i915_vma *vma;
>
> -	list_for_each_entry(vma, &o->vma_list, vma_link) {
> +	list_for_each_entry(vma, &o->vma_list, obj_link) {
>   		if (i915_is_ggtt(vma->vm) &&
>   		    vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
>   			continue;
> @@ -4474,7 +4474,7 @@ bool i915_gem_obj_ggtt_bound_view(struct drm_i915_gem_object *o,
>   	struct i915_address_space *ggtt = i915_obj_to_ggtt(o);
>   	struct i915_vma *vma;
>
> -	list_for_each_entry(vma, &o->vma_list, vma_link)
> +	list_for_each_entry(vma, &o->vma_list, obj_link)
>   		if (vma->vm == ggtt &&
>   		    i915_ggtt_view_equal(&vma->ggtt_view, view) &&
>   		    drm_mm_node_allocated(&vma->node))
> @@ -4487,7 +4487,7 @@ bool i915_gem_obj_bound_any(struct drm_i915_gem_object *o)
>   {
>   	struct i915_vma *vma;
>
> -	list_for_each_entry(vma, &o->vma_list, vma_link)
> +	list_for_each_entry(vma, &o->vma_list, obj_link)
>   		if (drm_mm_node_allocated(&vma->node))
>   			return true;
>
> @@ -4504,7 +4504,7 @@ unsigned long i915_gem_obj_size(struct drm_i915_gem_object *o,
>
>   	BUG_ON(list_empty(&o->vma_list));
>
> -	list_for_each_entry(vma, &o->vma_list, vma_link) {
> +	list_for_each_entry(vma, &o->vma_list, obj_link) {
>   		if (i915_is_ggtt(vma->vm) &&
>   		    vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
>   			continue;
> @@ -4517,7 +4517,7 @@ unsigned long i915_gem_obj_size(struct drm_i915_gem_object *o,
>   bool i915_gem_obj_is_pinned(struct drm_i915_gem_object *obj)
>   {
>   	struct i915_vma *vma;
> -	list_for_each_entry(vma, &obj->vma_list, vma_link)
> +	list_for_each_entry(vma, &obj->vma_list, obj_link)
>   		if (vma->pin_count > 0)
>   			return true;
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
> index 1a30452ec5fb..25a8498f0b5a 100644
> --- a/drivers/gpu/drm/i915/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/i915_gem_context.c
> @@ -142,7 +142,7 @@ static void i915_gem_context_clean(struct intel_context *ctx)
>   		return;
>
>   	list_for_each_entry_safe(vma, next, &ppgtt->base.inactive_list,
> -				 mm_list) {
> +				 vm_link) {
>   		if (WARN_ON(__i915_vma_unbind_no_wait(vma)))
>   			break;
>   	}
> diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
> index 07c6e4d320c9..ea1f8d1bd228 100644
> --- a/drivers/gpu/drm/i915/i915_gem_evict.c
> +++ b/drivers/gpu/drm/i915/i915_gem_evict.c
> @@ -116,7 +116,7 @@ i915_gem_evict_something(struct drm_device *dev, struct i915_address_space *vm,
>
>   search_again:
>   	/* First see if there is a large enough contiguous idle region... */
> -	list_for_each_entry(vma, &vm->inactive_list, mm_list) {
> +	list_for_each_entry(vma, &vm->inactive_list, vm_link) {
>   		if (mark_free(vma, &unwind_list))
>   			goto found;
>   	}
> @@ -125,7 +125,7 @@ search_again:
>   		goto none;
>
>   	/* Now merge in the soon-to-be-expired objects... */
> -	list_for_each_entry(vma, &vm->active_list, mm_list) {
> +	list_for_each_entry(vma, &vm->active_list, vm_link) {
>   		if (mark_free(vma, &unwind_list))
>   			goto found;
>   	}
> @@ -270,7 +270,7 @@ int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle)
>   		WARN_ON(!list_empty(&vm->active_list));
>   	}
>
> -	list_for_each_entry_safe(vma, next, &vm->inactive_list, mm_list)
> +	list_for_each_entry_safe(vma, next, &vm->inactive_list, vm_link)
>   		if (vma->pin_count == 0)
>   			WARN_ON(i915_vma_unbind(vma));
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index cc4d54b4043e..25bcea3e6ab6 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -2696,7 +2696,7 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
>   			return ret;
>   		}
>   		vma->bound |= GLOBAL_BIND;
> -		list_add_tail(&vma->mm_list, &ggtt_vm->inactive_list);
> +		list_add_tail(&vma->vm_link, &ggtt_vm->inactive_list);
>   	}
>
>   	/* Clear any non-preallocated blocks */
> @@ -3181,7 +3181,7 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev)
>   	vm = &dev_priv->gtt.base;
>   	list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
>   		flush = false;
> -		list_for_each_entry(vma, &obj->vma_list, vma_link) {
> +		list_for_each_entry(vma, &obj->vma_list, obj_link) {
>   			if (vma->vm != vm)
>   				continue;
>
> @@ -3237,8 +3237,8 @@ __i915_gem_vma_create(struct drm_i915_gem_object *obj,
>   	if (vma == NULL)
>   		return ERR_PTR(-ENOMEM);
>
> -	INIT_LIST_HEAD(&vma->vma_link);
> -	INIT_LIST_HEAD(&vma->mm_list);
> +	INIT_LIST_HEAD(&vma->vm_link);
> +	INIT_LIST_HEAD(&vma->obj_link);
>   	INIT_LIST_HEAD(&vma->exec_list);
>   	vma->vm = vm;
>   	vma->obj = obj;
> @@ -3246,7 +3246,7 @@ __i915_gem_vma_create(struct drm_i915_gem_object *obj,
>   	if (i915_is_ggtt(vm))
>   		vma->ggtt_view = *ggtt_view;
>
> -	list_add_tail(&vma->vma_link, &obj->vma_list);
> +	list_add_tail(&vma->obj_link, &obj->vma_list);
>   	if (!i915_is_ggtt(vm))
>   		i915_ppgtt_get(i915_vm_to_ppgtt(vm));
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
> index b448ad832dcf..2497671d1e1a 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.h
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
> @@ -195,9 +195,9 @@ struct i915_vma {
>   	struct i915_ggtt_view ggtt_view;
>
>   	/** This object's place on the active/inactive lists */
> -	struct list_head mm_list;
> +	struct list_head vm_link;
>
> -	struct list_head vma_link; /* Link in the object's VMA list */
> +	struct list_head obj_link; /* Link in the object's VMA list */
>
>   	/** This vma's place in the batchbuffer or on the eviction list */
>   	struct list_head exec_list;
> diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c
> index f7df54a8ee2b..2ef7a158b510 100644
> --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c
> +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c
> @@ -133,7 +133,7 @@ i915_gem_shrink(struct drm_i915_private *dev_priv,
>
>   			/* For the unbound phase, this should be a no-op! */
>   			list_for_each_entry_safe(vma, v,
> -						 &obj->vma_list, vma_link)
> +						 &obj->vma_list, obj_link)
>   				if (i915_vma_unbind(vma))
>   					break;
>
> @@ -193,7 +193,7 @@ static int num_vma_bound(struct drm_i915_gem_object *obj)
>   	struct i915_vma *vma;
>   	int count = 0;
>
> -	list_for_each_entry(vma, &obj->vma_list, vma_link) {
> +	list_for_each_entry(vma, &obj->vma_list, obj_link) {
>   		if (drm_mm_node_allocated(&vma->node))
>   			count++;
>   		if (vma->pin_count)
> diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
> index 598ed2facf85..305d58a5f745 100644
> --- a/drivers/gpu/drm/i915/i915_gem_stolen.c
> +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
> @@ -688,7 +688,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
>   		}
>
>   		vma->bound |= GLOBAL_BIND;
> -		list_add_tail(&vma->mm_list, &ggtt->inactive_list);
> +		list_add_tail(&vma->vm_link, &ggtt->inactive_list);
>   	}
>
>   	list_add_tail(&obj->global_list, &dev_priv->mm.bound_list);
> diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c
> index 251e81c4b0ea..2f3638d02bdd 100644
> --- a/drivers/gpu/drm/i915/i915_gem_userptr.c
> +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
> @@ -81,7 +81,7 @@ static void __cancel_userptr__worker(struct work_struct *work)
>   		was_interruptible = dev_priv->mm.interruptible;
>   		dev_priv->mm.interruptible = false;
>
> -		list_for_each_entry_safe(vma, tmp, &obj->vma_list, vma_link)
> +		list_for_each_entry_safe(vma, tmp, &obj->vma_list, obj_link)
>   			WARN_ON(i915_vma_unbind(vma));
>   		WARN_ON(i915_gem_object_put_pages(obj));
>
> diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
> index d27c07982c89..9ab77875ecbd 100644
> --- a/drivers/gpu/drm/i915/i915_gpu_error.c
> +++ b/drivers/gpu/drm/i915/i915_gpu_error.c
> @@ -731,7 +731,7 @@ static u32 capture_active_bo(struct drm_i915_error_buffer *err,
>   	struct i915_vma *vma;
>   	int i = 0;
>
> -	list_for_each_entry(vma, head, mm_list) {
> +	list_for_each_entry(vma, head, vm_link) {
>   		capture_bo(err++, vma);
>   		if (++i == count)
>   			break;
> @@ -754,7 +754,7 @@ static u32 capture_pinned_bo(struct drm_i915_error_buffer *err,
>   		if (err == last)
>   			break;
>
> -		list_for_each_entry(vma, &obj->vma_list, vma_link)
> +		list_for_each_entry(vma, &obj->vma_list, obj_link)
>   			if (vma->vm == vm && vma->pin_count > 0)
>   				capture_bo(err++, vma);
>   	}
> @@ -1115,12 +1115,12 @@ static void i915_gem_capture_vm(struct drm_i915_private *dev_priv,
>   	int i;
>
>   	i = 0;
> -	list_for_each_entry(vma, &vm->active_list, mm_list)
> +	list_for_each_entry(vma, &vm->active_list, vm_link)
>   		i++;
>   	error->active_bo_count[ndx] = i;
>
>   	list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
> -		list_for_each_entry(vma, &obj->vma_list, vma_link)
> +		list_for_each_entry(vma, &obj->vma_list, obj_link)
>   			if (vma->vm == vm && vma->pin_count > 0)
>   				i++;
>   	}
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 04/11] drm/i915: Amalgamate GGTT/ppGTT vma debug list walkers
  2015-12-14 11:36 ` [PATCH 04/11] drm/i915: Amalgamate GGTT/ppGTT vma debug list walkers Chris Wilson
@ 2015-12-17 11:21   ` Tvrtko Ursulin
  0 siblings, 0 replies; 37+ messages in thread
From: Tvrtko Ursulin @ 2015-12-17 11:21 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


On 14/12/15 11:36, Chris Wilson wrote:
> As we can now have multiple VMA inside the global GTT (with partial
> mappings, rotations, etc), it is no longer true that there may just be a
> single GGTT entry and so we should walk the full vma_list to count up
> the actual usage. In addition to unifying the two walkers, switch from
> multiplying the object size for each vma to summing the bound vma sizes.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>   drivers/gpu/drm/i915/i915_debugfs.c | 46 +++++++++++++++----------------------
>   1 file changed, 18 insertions(+), 28 deletions(-)

Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

Regards,

Tvrtko

>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index fdcf90757eb0..c04ba9981e9b 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -332,6 +332,7 @@ static int per_file_stats(int id, void *ptr, void *data)
>   	struct drm_i915_gem_object *obj = ptr;
>   	struct file_stats *stats = data;
>   	struct i915_vma *vma;
> +	int bound = 0;
>
>   	stats->count++;
>   	stats->total += obj->base.size;
> @@ -339,41 +340,30 @@ static int per_file_stats(int id, void *ptr, void *data)
>   	if (obj->base.name || obj->base.dma_buf)
>   		stats->shared += obj->base.size;
>
> -	if (USES_FULL_PPGTT(obj->base.dev)) {
> -		list_for_each_entry(vma, &obj->vma_list, obj_link) {
> -			struct i915_hw_ppgtt *ppgtt;
> +	list_for_each_entry(vma, &obj->vma_list, obj_link) {
> +		if (!drm_mm_node_allocated(&vma->node))
> +			continue;
>
> -			if (!drm_mm_node_allocated(&vma->node))
> -				continue;
> +		bound++;
>
> -			if (i915_is_ggtt(vma->vm)) {
> -				stats->global += obj->base.size;
> -				continue;
> -			}
> -
> -			ppgtt = container_of(vma->vm, struct i915_hw_ppgtt, base);
> +		if (i915_is_ggtt(vma->vm)) {
> +			stats->global += vma->node.size;
> +		} else {
> +			struct i915_hw_ppgtt *ppgtt
> +				= container_of(vma->vm,
> +					       struct i915_hw_ppgtt,
> +					       base);
>   			if (ppgtt->file_priv != stats->file_priv)
>   				continue;
> -
> -			if (obj->active) /* XXX per-vma statistic */
> -				stats->active += obj->base.size;
> -			else
> -				stats->inactive += obj->base.size;
> -
> -			return 0;
> -		}
> -	} else {
> -		if (i915_gem_obj_ggtt_bound(obj)) {
> -			stats->global += obj->base.size;
> -			if (obj->active)
> -				stats->active += obj->base.size;
> -			else
> -				stats->inactive += obj->base.size;
> -			return 0;
>   		}
> +
> +		if (obj->active) /* XXX per-vma statistic */
> +			stats->active += vma->node.size;
> +		else
> +			stats->inactive += vma->node.size;
>   	}
>
> -	if (!list_empty(&obj->global_list))
> +	if (!bound)
>   		stats->unbound += obj->base.size;
>
>   	return 0;
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 03/11] drm/i915: Rename vma->*_list to *_link for consistency
  2015-12-17 11:14   ` Tvrtko Ursulin
@ 2015-12-17 11:24     ` Chris Wilson
  2015-12-17 11:45       ` Chris Wilson
  0 siblings, 1 reply; 37+ messages in thread
From: Chris Wilson @ 2015-12-17 11:24 UTC (permalink / raw)
  To: Tvrtko Ursulin; +Cc: intel-gfx

On Thu, Dec 17, 2015 at 11:14:54AM +0000, Tvrtko Ursulin wrote:
> 
> On 14/12/15 11:36, Chris Wilson wrote:
> >Elsewhere we have adopted the convention of using '_link' to denote
> >elements in the list (and '_list' for the actual list_head itself), and
> >that the name should indicate which list the link belongs to (and
> >preferrably not just where the link is being stored).
> >
> >s/vma_link/obj_link/ (we iterate over obj->vma_list)
> >s/mm_list/vm_link/ (we iterate over vm->[in]active_list)
> 
> A little bit of pain for the established muscle memory but I think
> good in general. Assuming you compile tested it:
> 
> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> 
> Btw perhaps rename the link in  i915_gem_active to request_link so
> that the good initiative is not questioned. :)

I think I have:

	drm_i915_gem_request.active_list
	i915_gem_active.link

There's still a drm_i915_gem_request.client_list to be fixed up, but I
can do that when I show off a scary patch to do lock-free client tracking.

I've read LWN today, my brian is mush. But at least I learnt about the
term lock-free locking.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 05/11] drm/i915: Reduce the pointer dance of i915_is_ggtt()
  2015-12-14 11:36 ` [PATCH 05/11] drm/i915: Reduce the pointer dance of i915_is_ggtt() Chris Wilson
@ 2015-12-17 11:31   ` Tvrtko Ursulin
  0 siblings, 0 replies; 37+ messages in thread
From: Tvrtko Ursulin @ 2015-12-17 11:31 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


Hi,

On 14/12/15 11:36, Chris Wilson wrote:
> The multiple levels of indirect do nothing but hinder the compiler and
> the pointer chasing turns to be quite painful but painless to fix.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>   drivers/gpu/drm/i915/i915_debugfs.c        | 13 ++++++-------
>   drivers/gpu/drm/i915/i915_drv.h            |  7 -------
>   drivers/gpu/drm/i915/i915_gem.c            | 18 +++++++-----------
>   drivers/gpu/drm/i915/i915_gem_execbuffer.c |  5 ++---
>   drivers/gpu/drm/i915/i915_gem_gtt.c        | 12 +++++-------
>   drivers/gpu/drm/i915/i915_gem_gtt.h        |  5 +++++
>   drivers/gpu/drm/i915/i915_trace.h          | 27 ++++++++-------------------
>   7 files changed, 33 insertions(+), 54 deletions(-)

Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

Regards,

Tvrtko


> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index c04ba9981e9b..9ec133f5af00 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -118,7 +118,7 @@ static u64 i915_gem_obj_total_ggtt_size(struct drm_i915_gem_object *obj)
>   	struct i915_vma *vma;
>
>   	list_for_each_entry(vma, &obj->vma_list, obj_link) {
> -		if (i915_is_ggtt(vma->vm) && drm_mm_node_allocated(&vma->node))
> +		if (vma->is_ggtt && drm_mm_node_allocated(&vma->node))
>   			size += vma->node.size;
>   	}
>
> @@ -165,12 +165,11 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
>   		seq_printf(m, " (fence: %d)", obj->fence_reg);
>   	list_for_each_entry(vma, &obj->vma_list, obj_link) {
>   		seq_printf(m, " (%sgtt offset: %08llx, size: %08llx",
> -			   i915_is_ggtt(vma->vm) ? "g" : "pp",
> +			   vma->is_ggtt ? "g" : "pp",
>   			   vma->node.start, vma->node.size);
> -		if (i915_is_ggtt(vma->vm))
> -			seq_printf(m, ", type: %u)", vma->ggtt_view.type);
> -		else
> -			seq_puts(m, ")");
> +		if (vma->is_ggtt)
> +			seq_printf(m, ", type: %u", vma->ggtt_view.type);
> +		seq_puts(m, ")");
>   	}
>   	if (obj->stolen)
>   		seq_printf(m, " (stolen: %08llx)", obj->stolen->start);
> @@ -346,7 +345,7 @@ static int per_file_stats(int id, void *ptr, void *data)
>
>   		bound++;
>
> -		if (i915_is_ggtt(vma->vm)) {
> +		if (vma->is_ggtt) {
>   			stats->global += vma->node.size;
>   		} else {
>   			struct i915_hw_ppgtt *ppgtt
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index dbcb7659ba2b..6ce163a681f2 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2916,18 +2916,11 @@ bool i915_gem_obj_is_pinned(struct drm_i915_gem_object *obj);
>   /* Some GGTT VM helpers */
>   #define i915_obj_to_ggtt(obj) \
>   	(&((struct drm_i915_private *)(obj)->base.dev->dev_private)->gtt.base)
> -static inline bool i915_is_ggtt(struct i915_address_space *vm)
> -{
> -	struct i915_address_space *ggtt =
> -		&((struct drm_i915_private *)(vm)->dev->dev_private)->gtt.base;
> -	return vm == ggtt;
> -}
>
>   static inline struct i915_hw_ppgtt *
>   i915_vm_to_ppgtt(struct i915_address_space *vm)
>   {
>   	WARN_ON(i915_is_ggtt(vm));
> -
>   	return container_of(vm, struct i915_hw_ppgtt, base);
>   }
>
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index e6ace74616b2..144e92df8137 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -2603,8 +2603,7 @@ static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
>   			return ret;
>   	}
>
> -	if (i915_is_ggtt(vma->vm) &&
> -	    vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) {
> +	if (vma->is_ggtt && vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) {
>   		i915_gem_object_finish_gtt(obj);
>
>   		/* release the fence reg _after_ flushing */
> @@ -2619,7 +2618,7 @@ static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
>   	vma->bound = 0;
>
>   	list_del_init(&vma->vm_link);
> -	if (i915_is_ggtt(vma->vm)) {
> +	if (vma->is_ggtt) {
>   		if (vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) {
>   			obj->map_and_fenceable = false;
>   		} else if (vma->ggtt_view.pages) {
> @@ -3889,17 +3888,14 @@ struct i915_vma *i915_gem_obj_to_ggtt_view(struct drm_i915_gem_object *obj,
>
>   void i915_gem_vma_destroy(struct i915_vma *vma)
>   {
> -	struct i915_address_space *vm = NULL;
>   	WARN_ON(vma->node.allocated);
>
>   	/* Keep the vma as a placeholder in the execbuffer reservation lists */
>   	if (!list_empty(&vma->exec_list))
>   		return;
>
> -	vm = vma->vm;
> -
> -	if (!i915_is_ggtt(vm))
> -		i915_ppgtt_put(i915_vm_to_ppgtt(vm));
> +	if (!vma->is_ggtt)
> +		i915_ppgtt_put(i915_vm_to_ppgtt(vma->vm));
>
>   	list_del(&vma->obj_link);
>
> @@ -4425,7 +4421,7 @@ u64 i915_gem_obj_offset(struct drm_i915_gem_object *o,
>   	WARN_ON(vm == &dev_priv->mm.aliasing_ppgtt->base);
>
>   	list_for_each_entry(vma, &o->vma_list, obj_link) {
> -		if (i915_is_ggtt(vma->vm) &&
> +		if (vma->is_ggtt &&
>   		    vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
>   			continue;
>   		if (vma->vm == vm)
> @@ -4458,7 +4454,7 @@ bool i915_gem_obj_bound(struct drm_i915_gem_object *o,
>   	struct i915_vma *vma;
>
>   	list_for_each_entry(vma, &o->vma_list, obj_link) {
> -		if (i915_is_ggtt(vma->vm) &&
> +		if (vma->is_ggtt &&
>   		    vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
>   			continue;
>   		if (vma->vm == vm && drm_mm_node_allocated(&vma->node))
> @@ -4505,7 +4501,7 @@ unsigned long i915_gem_obj_size(struct drm_i915_gem_object *o,
>   	BUG_ON(list_empty(&o->vma_list));
>
>   	list_for_each_entry(vma, &o->vma_list, obj_link) {
> -		if (i915_is_ggtt(vma->vm) &&
> +		if (vma->is_ggtt &&
>   		    vma->ggtt_view.type != I915_GGTT_VIEW_NORMAL)
>   			continue;
>   		if (vma->vm == vm)
> diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> index e9741368972e..6788f71ad989 100644
> --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> @@ -658,7 +658,7 @@ need_reloc_mappable(struct i915_vma *vma)
>   	if (entry->relocation_count == 0)
>   		return false;
>
> -	if (!i915_is_ggtt(vma->vm))
> +	if (!vma->is_ggtt)
>   		return false;
>
>   	/* See also use_cpu_reloc() */
> @@ -677,8 +677,7 @@ eb_vma_misplaced(struct i915_vma *vma)
>   	struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
>   	struct drm_i915_gem_object *obj = vma->obj;
>
> -	WARN_ON(entry->flags & __EXEC_OBJECT_NEEDS_MAP &&
> -	       !i915_is_ggtt(vma->vm));
> +	WARN_ON(entry->flags & __EXEC_OBJECT_NEEDS_MAP && !vma->is_ggtt);
>
>   	if (entry->alignment &&
>   	    vma->node.start & (entry->alignment - 1))
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 25bcea3e6ab6..da150c27a76c 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -3134,6 +3134,7 @@ int i915_gem_gtt_init(struct drm_device *dev)
>   	}
>
>   	gtt->base.dev = dev;
> +	gtt->base.is_ggtt = true;
>
>   	ret = gtt->gtt_probe(dev, &gtt->base.total, &gtt->stolen_size,
>   			     &gtt->mappable_base, &gtt->mappable_end);
> @@ -3242,13 +3243,14 @@ __i915_gem_vma_create(struct drm_i915_gem_object *obj,
>   	INIT_LIST_HEAD(&vma->exec_list);
>   	vma->vm = vm;
>   	vma->obj = obj;
> +	vma->is_ggtt = i915_is_ggtt(vm);
>
>   	if (i915_is_ggtt(vm))
>   		vma->ggtt_view = *ggtt_view;
> +	else
> +		i915_ppgtt_get(i915_vm_to_ppgtt(vm));
>
>   	list_add_tail(&vma->obj_link, &obj->vma_list);
> -	if (!i915_is_ggtt(vm))
> -		i915_ppgtt_get(i915_vm_to_ppgtt(vm));
>
>   	return vma;
>   }
> @@ -3520,13 +3522,9 @@ int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level,
>   		return 0;
>
>   	if (vma->bound == 0 && vma->vm->allocate_va_range) {
> -		trace_i915_va_alloc(vma->vm,
> -				    vma->node.start,
> -				    vma->node.size,
> -				    VM_TO_TRACE_NAME(vma->vm));
> -
>   		/* XXX: i915_vma_pin() will fix this +- hack */
>   		vma->pin_count++;
> +		trace_i915_va_alloc(vma);
>   		ret = vma->vm->allocate_va_range(vma->vm,
>   						 vma->node.start,
>   						 vma->node.size);
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
> index 2497671d1e1a..bae005a62cfc 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.h
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
> @@ -184,6 +184,7 @@ struct i915_vma {
>   #define GLOBAL_BIND	(1<<0)
>   #define LOCAL_BIND	(1<<1)
>   	unsigned int bound : 4;
> +	bool is_ggtt : 1;
>
>   	/**
>   	 * Support different GGTT views into the same object.
> @@ -276,6 +277,8 @@ struct i915_address_space {
>   	u64 start;		/* Start offset always 0 for dri2 */
>   	u64 total;		/* size addr space maps (ex. 2GB for ggtt) */
>
> +	bool is_ggtt;
> +
>   	struct i915_page_scratch *scratch_page;
>   	struct i915_page_table *scratch_pt;
>   	struct i915_page_directory *scratch_pd;
> @@ -331,6 +334,8 @@ struct i915_address_space {
>   			u32 flags);
>   };
>
> +#define i915_is_ggtt(V) ((V)->is_ggtt)
> +
>   /* The Graphics Translation Table is the way in which GEN hardware translates a
>    * Graphics Virtual Address into a Physical Address. In addition to the normal
>    * collateral associated with any va->pa translations GEN hardware also has a
> diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h
> index 85469e3c740a..e486dcef508d 100644
> --- a/drivers/gpu/drm/i915/i915_trace.h
> +++ b/drivers/gpu/drm/i915/i915_trace.h
> @@ -175,35 +175,24 @@ TRACE_EVENT(i915_vma_unbind,
>   		      __entry->obj, __entry->offset, __entry->size, __entry->vm)
>   );
>
> -#define VM_TO_TRACE_NAME(vm) \
> -	(i915_is_ggtt(vm) ? "G" : \
> -		      "P")
> -
> -DECLARE_EVENT_CLASS(i915_va,
> -	TP_PROTO(struct i915_address_space *vm, u64 start, u64 length, const char *name),
> -	TP_ARGS(vm, start, length, name),
> +TRACE_EVENT(i915_va_alloc,
> +	TP_PROTO(struct i915_vma *vma),
> +	TP_ARGS(vma),
>
>   	TP_STRUCT__entry(
>   		__field(struct i915_address_space *, vm)
>   		__field(u64, start)
>   		__field(u64, end)
> -		__string(name, name)
>   	),
>
>   	TP_fast_assign(
> -		__entry->vm = vm;
> -		__entry->start = start;
> -		__entry->end = start + length - 1;
> -		__assign_str(name, name);
> +		__entry->vm = vma->vm;
> +		__entry->start = vma->node.start;
> +		__entry->end = vma->node.start + vma->node.size - 1;
>   	),
>
> -	TP_printk("vm=%p (%s), 0x%llx-0x%llx",
> -		  __entry->vm, __get_str(name),  __entry->start, __entry->end)
> -);
> -
> -DEFINE_EVENT(i915_va, i915_va_alloc,
> -	     TP_PROTO(struct i915_address_space *vm, u64 start, u64 length, const char *name),
> -	     TP_ARGS(vm, start, length, name)
> +	TP_printk("vm=%p (%c), 0x%llx-0x%llx",
> +		  __entry->vm, i915_is_ggtt(__entry->vm) ? 'G' : 'P',  __entry->start, __entry->end)
>   );
>
>   DECLARE_EVENT_CLASS(i915_px_entry,
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 03/11] drm/i915: Rename vma->*_list to *_link for consistency
  2015-12-17 11:24     ` Chris Wilson
@ 2015-12-17 11:45       ` Chris Wilson
  0 siblings, 0 replies; 37+ messages in thread
From: Chris Wilson @ 2015-12-17 11:45 UTC (permalink / raw)
  To: Tvrtko Ursulin, intel-gfx

On Thu, Dec 17, 2015 at 11:24:34AM +0000, Chris Wilson wrote:
> On Thu, Dec 17, 2015 at 11:14:54AM +0000, Tvrtko Ursulin wrote:
> > 
> > On 14/12/15 11:36, Chris Wilson wrote:
> > >Elsewhere we have adopted the convention of using '_link' to denote
> > >elements in the list (and '_list' for the actual list_head itself), and
> > >that the name should indicate which list the link belongs to (and
> > >preferrably not just where the link is being stored).
> > >
> > >s/vma_link/obj_link/ (we iterate over obj->vma_list)
> > >s/mm_list/vm_link/ (we iterate over vm->[in]active_list)
> > 
> > A little bit of pain for the established muscle memory but I think
> > good in general. Assuming you compile tested it:
> > 
> > Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> > 
> > Btw perhaps rename the link in  i915_gem_active to request_link so
> > that the good initiative is not questioned. :)
> 
> I think I have:
> 
> 	drm_i915_gem_request.active_list
> 	i915_gem_active.link

Oh you meant the reverse object in the name,
i915_gem_active.request_link.

If we ever have multiple links it would be clearer. At the moment, I'm
erring on the side of laziness.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 06/11] drm/i915: Store owning file on the i915_address_space
  2015-12-14 11:36 ` [PATCH 06/11] drm/i915: Store owning file on the i915_address_space Chris Wilson
@ 2015-12-17 11:52   ` Tvrtko Ursulin
  2015-12-17 13:25     ` Chris Wilson
  0 siblings, 1 reply; 37+ messages in thread
From: Tvrtko Ursulin @ 2015-12-17 11:52 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


Hi,

On 14/12/15 11:36, Chris Wilson wrote:
> For the global GTT (and aliasing GTT), the address space is owned by the
> device (it is a global resource) and so the per-file owner field is
> NULL. For per-process GTT (where we create an address space per
> context), each is owned by the opening file. We can use this ownership
> information to both distinguish GGTT and ppGTT address spaces, as well
> as occasionally inspect the owner.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>   drivers/gpu/drm/i915/i915_debugfs.c     |  2 +-
>   drivers/gpu/drm/i915/i915_drv.h         |  1 -
>   drivers/gpu/drm/i915/i915_gem_context.c |  3 ++-
>   drivers/gpu/drm/i915/i915_gem_gtt.c     | 25 +++++++++++++------------
>   drivers/gpu/drm/i915/i915_gem_gtt.h     | 13 ++++++-------
>   5 files changed, 22 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 9ec133f5af00..179e3c5c5022 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -352,7 +352,7 @@ static int per_file_stats(int id, void *ptr, void *data)
>   				= container_of(vma->vm,
>   					       struct i915_hw_ppgtt,
>   					       base);
> -			if (ppgtt->file_priv != stats->file_priv)
> +			if (ppgtt->base.file != stats->file_priv)
>   				continue;
>   		}
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 6ce163a681f2..b32a00f60e98 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2924,7 +2924,6 @@ i915_vm_to_ppgtt(struct i915_address_space *vm)
>   	return container_of(vm, struct i915_hw_ppgtt, base);
>   }
>
> -
>   static inline bool i915_gem_obj_ggtt_bound(struct drm_i915_gem_object *obj)
>   {
>   	return i915_gem_obj_ggtt_bound_view(obj, &i915_ggtt_view_normal);
> diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
> index 25a8498f0b5a..dcb4603a7f03 100644
> --- a/drivers/gpu/drm/i915/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/i915_gem_context.c
> @@ -296,7 +296,8 @@ i915_gem_create_context(struct drm_device *dev,
>   	}
>
>   	if (USES_FULL_PPGTT(dev)) {
> -		struct i915_hw_ppgtt *ppgtt = i915_ppgtt_create(dev, file_priv);
> +		struct i915_hw_ppgtt *ppgtt =
> +			i915_ppgtt_create(to_i915(dev), file_priv);
>
>   		if (IS_ERR_OR_NULL(ppgtt)) {
>   			DRM_DEBUG_DRIVER("PPGTT setup failed (%ld)\n",
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index da150c27a76c..130ccefb2491 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -2112,11 +2112,12 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
>   	return 0;
>   }
>
> -static int __hw_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt)
> +static int __hw_ppgtt_init(struct i915_hw_ppgtt *ppgtt,
> +			   struct drm_i915_private *dev_priv)
>   {
> -	ppgtt->base.dev = dev;
> +	ppgtt->base.dev = dev_priv->dev;
>
> -	if (INTEL_INFO(dev)->gen < 8)
> +	if (INTEL_INFO(dev_priv)->gen < 8)
>   		return gen6_ppgtt_init(ppgtt);
>   	else
>   		return gen8_ppgtt_init(ppgtt);
> @@ -2132,15 +2133,17 @@ static void i915_address_space_init(struct i915_address_space *vm,
>   	list_add_tail(&vm->global_link, &dev_priv->vm_list);
>   }
>
> -int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt)
> +int i915_ppgtt_init(struct i915_hw_ppgtt *ppgtt,
> +		    struct drm_i915_private *dev_priv,
> +		    struct drm_i915_file_private *file_priv)
>   {
> -	struct drm_i915_private *dev_priv = dev->dev_private;
>   	int ret = 0;

Since you are using the opportunity to tidy whitespace maybe also tidy 
this needless init. ;)

>
> -	ret = __hw_ppgtt_init(dev, ppgtt);
> +	ret = __hw_ppgtt_init(ppgtt, dev_priv);
>   	if (ret == 0) {
>   		kref_init(&ppgtt->ref);
>   		i915_address_space_init(&ppgtt->base, dev_priv);
> +		ppgtt->base.file = file_priv;

I would keep using file_priv since that's what's it's called all over 
the place but whatever.

>   	}
>
>   	return ret;
> @@ -2183,7 +2186,8 @@ int i915_ppgtt_init_ring(struct drm_i915_gem_request *req)
>   }
>
>   struct i915_hw_ppgtt *
> -i915_ppgtt_create(struct drm_device *dev, struct drm_i915_file_private *fpriv)
> +i915_ppgtt_create(struct drm_i915_private *dev_priv,
> +		  struct drm_i915_file_private *fpriv)
>   {
>   	struct i915_hw_ppgtt *ppgtt;
>   	int ret;
> @@ -2192,14 +2196,12 @@ i915_ppgtt_create(struct drm_device *dev, struct drm_i915_file_private *fpriv)
>   	if (!ppgtt)
>   		return ERR_PTR(-ENOMEM);
>
> -	ret = i915_ppgtt_init(dev, ppgtt);
> +	ret = i915_ppgtt_init(ppgtt, dev_priv, fpriv);
>   	if (ret) {
>   		kfree(ppgtt);
>   		return ERR_PTR(ret);
>   	}
>
> -	ppgtt->file_priv = fpriv;
> -
>   	trace_i915_ppgtt_create(&ppgtt->base);
>
>   	return ppgtt;
> @@ -2717,7 +2719,7 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
>   		if (!ppgtt)
>   			return -ENOMEM;
>
> -		ret = __hw_ppgtt_init(dev, ppgtt);
> +		ret = __hw_ppgtt_init(ppgtt, dev_priv);
>   		if (ret) {
>   			ppgtt->base.cleanup(&ppgtt->base);
>   			kfree(ppgtt);
> @@ -3134,7 +3136,6 @@ int i915_gem_gtt_init(struct drm_device *dev)
>   	}
>
>   	gtt->base.dev = dev;
> -	gtt->base.is_ggtt = true;
>
>   	ret = gtt->gtt_probe(dev, &gtt->base.total, &gtt->stolen_size,
>   			     &gtt->mappable_base, &gtt->mappable_end);
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
> index bae005a62cfc..4e9553ace33f 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.h
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
> @@ -273,12 +273,11 @@ struct i915_pml4 {
>   struct i915_address_space {
>   	struct drm_mm mm;
>   	struct drm_device *dev;
> +	struct drm_i915_file_private *file;

Suggest putting a comment documenting when it is NULL and when it is 
valid. Commit says so, but I think comment is also needed.

With that,

Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

Regards,

Tvrtko


>   	struct list_head global_link;
>   	u64 start;		/* Start offset always 0 for dri2 */
>   	u64 total;		/* size addr space maps (ex. 2GB for ggtt) */
>
> -	bool is_ggtt;
> -
>   	struct i915_page_scratch *scratch_page;
>   	struct i915_page_table *scratch_pt;
>   	struct i915_page_directory *scratch_pd;
> @@ -334,7 +333,7 @@ struct i915_address_space {
>   			u32 flags);
>   };
>
> -#define i915_is_ggtt(V) ((V)->is_ggtt)
> +#define i915_is_ggtt(V) ((V)->file == NULL)
>
>   /* The Graphics Translation Table is the way in which GEN hardware translates a
>    * Graphics Virtual Address into a Physical Address. In addition to the normal
> @@ -376,8 +375,6 @@ struct i915_hw_ppgtt {
>   		struct i915_page_directory pd;		/* GEN6-7 */
>   	};
>
> -	struct drm_i915_file_private *file_priv;
> -
>   	gen6_pte_t __iomem *pd_addr;
>
>   	int (*enable)(struct i915_hw_ppgtt *ppgtt);
> @@ -522,11 +519,13 @@ void i915_gem_init_global_gtt(struct drm_device *dev);
>   void i915_global_gtt_cleanup(struct drm_device *dev);
>
>
> -int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt);
> +int i915_ppgtt_init(struct i915_hw_ppgtt *ppgtt,
> +		    struct drm_i915_private *dev_priv,
> +		    struct drm_i915_file_private *file_priv);
>   int i915_ppgtt_init_hw(struct drm_device *dev);
>   int i915_ppgtt_init_ring(struct drm_i915_gem_request *req);
>   void i915_ppgtt_release(struct kref *kref);
> -struct i915_hw_ppgtt *i915_ppgtt_create(struct drm_device *dev,
> +struct i915_hw_ppgtt *i915_ppgtt_create(struct drm_i915_private *dev_priv,
>   					struct drm_i915_file_private *fpriv);
>   static inline void i915_ppgtt_get(struct i915_hw_ppgtt *ppgtt)
>   {
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 07/11] drm/i915: i915_vma_move_to_active prep patch
  2015-12-14 11:36 ` [PATCH 07/11] drm/i915: i915_vma_move_to_active prep patch Chris Wilson
@ 2015-12-17 12:04   ` Tvrtko Ursulin
  0 siblings, 0 replies; 37+ messages in thread
From: Tvrtko Ursulin @ 2015-12-17 12:04 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


On 14/12/15 11:36, Chris Wilson wrote:
> This patch is broken out of the next just to remove the code motion from
> that patch and make it more readable. What we do here is move the
> i915_vma_move_to_active() to i915_gem_execbuffer.c and put the three
> stages (read, write, fenced) together so that future modifications to
> active handling are all located in the same spot. The importance of this
> is so that we can more simply control the order in which the requests
> are place in the retirement list (i.e. control the order at which we
> retire and so control the lifetimes to avoid having to hold onto
> references).
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>   drivers/gpu/drm/i915/i915_drv.h              |  3 +-
>   drivers/gpu/drm/i915/i915_gem.c              | 15 -------
>   drivers/gpu/drm/i915/i915_gem_context.c      |  7 ++--
>   drivers/gpu/drm/i915/i915_gem_execbuffer.c   | 63 ++++++++++++++++++----------
>   drivers/gpu/drm/i915/i915_gem_render_state.c |  2 +-
>   5 files changed, 49 insertions(+), 41 deletions(-)

Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

Regards,

Tvrtko

>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index b32a00f60e98..eb775eb1c693 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2775,7 +2775,8 @@ int __must_check i915_mutex_lock_interruptible(struct drm_device *dev);
>   int i915_gem_object_sync(struct drm_i915_gem_object *obj,
>   			 struct drm_i915_gem_request *to);
>   void i915_vma_move_to_active(struct i915_vma *vma,
> -			     struct drm_i915_gem_request *req);
> +			     struct drm_i915_gem_request *req,
> +			     unsigned flags);
>   int i915_gem_dumb_create(struct drm_file *file_priv,
>   			 struct drm_device *dev,
>   			 struct drm_mode_create_dumb *args);
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 144e92df8137..8a824c5d5348 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -2016,21 +2016,6 @@ void *i915_gem_object_pin_vmap(struct drm_i915_gem_object *obj)
>   	return obj->vmapping;
>   }
>
> -void i915_vma_move_to_active(struct i915_vma *vma,
> -			     struct drm_i915_gem_request *req)
> -{
> -	struct drm_i915_gem_object *obj = vma->obj;
> -	struct intel_engine_cs *engine = req->engine;
> -
> -	/* Add a reference if we're newly entering the active list. */
> -	if (obj->active == 0)
> -		drm_gem_object_reference(&obj->base);
> -	obj->active |= intel_engine_flag(engine);
> -
> -	i915_gem_request_mark_active(req, &obj->last_read[engine->id]);
> -	list_move_tail(&vma->vm_link, &vma->vm->active_list);
> -}
> -
>   static void
>   i915_gem_object_retire__fence(struct drm_i915_gem_request_active *active,
>   			      struct drm_i915_gem_request *req)
> diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
> index dcb4603a7f03..c4a8a64cd1b2 100644
> --- a/drivers/gpu/drm/i915/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/i915_gem_context.c
> @@ -766,8 +766,8 @@ static int do_switch(struct drm_i915_gem_request *req)
>   	 * MI_SET_CONTEXT instead of when the next seqno has completed.
>   	 */
>   	if (from != NULL) {
> -		from->legacy_hw_ctx.rcs_state->base.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
> -		i915_vma_move_to_active(i915_gem_obj_to_ggtt(from->legacy_hw_ctx.rcs_state), req);
> +		struct drm_i915_gem_object *obj = from->legacy_hw_ctx.rcs_state;
> +
>   		/* As long as MI_SET_CONTEXT is serializing, ie. it flushes the
>   		 * whole damn pipeline, we don't need to explicitly mark the
>   		 * object dirty. The only exception is that the context must be
> @@ -775,7 +775,8 @@ static int do_switch(struct drm_i915_gem_request *req)
>   		 * able to defer doing this until we know the object would be
>   		 * swapped, but there is no way to do that yet.
>   		 */
> -		from->legacy_hw_ctx.rcs_state->dirty = 1;
> +		obj->base.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
> +		i915_vma_move_to_active(i915_gem_obj_to_ggtt(obj), req, 0);
>
>   		/* obj is kept alive until the next request by its active ref */
>   		i915_gem_object_ggtt_unpin(from->legacy_hw_ctx.rcs_state);
> diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> index 6788f71ad989..6de8681bb64c 100644
> --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> @@ -1064,6 +1064,44 @@ i915_gem_validate_context(struct drm_device *dev, struct drm_file *file,
>   	return ctx;
>   }
>
> +void i915_vma_move_to_active(struct i915_vma *vma,
> +			     struct drm_i915_gem_request *req,
> +			     unsigned flags)
> +{
> +	struct drm_i915_gem_object *obj = vma->obj;
> +	const unsigned engine = req->engine->id;
> +
> +	RQ_BUG_ON(!drm_mm_node_allocated(&vma->node));
> +
> +	obj->dirty = 1; /* be paranoid  */
> +
> +	/* Add a reference if we're newly entering the active list. */
> +	if (obj->active == 0)
> +		drm_gem_object_reference(&obj->base);
> +	obj->active |= 1 << engine;
> +	i915_gem_request_mark_active(req, &obj->last_read[engine]);
> +
> +	if (flags & EXEC_OBJECT_WRITE) {
> +		i915_gem_request_mark_active(req, &obj->last_write);
> +
> +		intel_fb_obj_invalidate(obj, ORIGIN_CS);
> +
> +		/* update for the implicit flush after a batch */
> +		obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS;
> +	}
> +
> +	if (flags & EXEC_OBJECT_NEEDS_FENCE) {
> +		i915_gem_request_mark_active(req, &obj->last_fence);
> +		if (flags & __EXEC_OBJECT_HAS_FENCE) {
> +			struct drm_i915_private *dev_priv = req->i915;
> +			list_move_tail(&dev_priv->fence_regs[obj->fence_reg].lru_list,
> +				       &dev_priv->mm.fence_list);
> +		}
> +	}
> +
> +	list_move_tail(&vma->vm_link, &vma->vm->active_list);
> +}
> +
>   static void
>   i915_gem_execbuffer_move_to_active(struct list_head *vmas,
>   				   struct drm_i915_gem_request *req)
> @@ -1071,35 +1109,18 @@ i915_gem_execbuffer_move_to_active(struct list_head *vmas,
>   	struct i915_vma *vma;
>
>   	list_for_each_entry(vma, vmas, exec_list) {
> -		struct drm_i915_gem_exec_object2 *entry = vma->exec_entry;
>   		struct drm_i915_gem_object *obj = vma->obj;
>   		u32 old_read = obj->base.read_domains;
>   		u32 old_write = obj->base.write_domain;
>
> -		obj->dirty = 1; /* be paranoid  */
>   		obj->base.write_domain = obj->base.pending_write_domain;
> -		if (obj->base.write_domain == 0)
> +		if (obj->base.write_domain)
> +			vma->exec_entry->flags |= EXEC_OBJECT_WRITE;
> +		else
>   			obj->base.pending_read_domains |= obj->base.read_domains;
>   		obj->base.read_domains = obj->base.pending_read_domains;
>
> -		i915_vma_move_to_active(vma, req);
> -		if (obj->base.write_domain) {
> -			i915_gem_request_mark_active(req, &obj->last_write);
> -
> -			intel_fb_obj_invalidate(obj, ORIGIN_CS);
> -
> -			/* update for the implicit flush after a batch */
> -			obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS;
> -		}
> -		if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) {
> -			i915_gem_request_mark_active(req, &obj->last_fence);
> -			if (entry->flags & __EXEC_OBJECT_HAS_FENCE) {
> -				struct drm_i915_private *dev_priv = req->i915;
> -				list_move_tail(&dev_priv->fence_regs[obj->fence_reg].lru_list,
> -					       &dev_priv->mm.fence_list);
> -			}
> -		}
> -
> +		i915_vma_move_to_active(vma, req, vma->exec_entry->flags);
>   		trace_i915_gem_object_change_domain(obj, old_read, old_write);
>   	}
>   }
> diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c
> index 630e748c991d..d5a87c4ff0f7 100644
> --- a/drivers/gpu/drm/i915/i915_gem_render_state.c
> +++ b/drivers/gpu/drm/i915/i915_gem_render_state.c
> @@ -221,7 +221,7 @@ int i915_gem_render_state_init(struct drm_i915_gem_request *req)
>   			goto out;
>   	}
>
> -	i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), req);
> +	i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), req, 0);
>
>   out:
>   	i915_gem_render_state_fini(&so);
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 08/11] drm/i915: Track active vma requests
  2015-12-14 11:36 ` [PATCH 08/11] drm/i915: Track active vma requests Chris Wilson
@ 2015-12-17 12:26   ` Tvrtko Ursulin
  0 siblings, 0 replies; 37+ messages in thread
From: Tvrtko Ursulin @ 2015-12-17 12:26 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


Hi,

On 14/12/15 11:36, Chris Wilson wrote:
> 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

s/solitary/individual/ ?

> 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.

What list walking are you referring to? Maybe clarify in the commit message.

Anyway, looks surprisingly simple. Almost suspiciously simple, but I 
can't fault it:

Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

Regards,

Tvrtko

>
> 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            | 36 ++++++++++++++++--------------
>   drivers/gpu/drm/i915/i915_gem_execbuffer.c |  2 ++
>   drivers/gpu/drm/i915/i915_gem_gtt.c        | 20 +++++++++++++++++
>   drivers/gpu/drm/i915/i915_gem_gtt.h        |  5 +++++
>   5 files changed, 47 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 179e3c5c5022..4df4ebbd56d6 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -356,7 +356,7 @@ static int per_file_stats(int id, void *ptr, void *data)
>   				continue;
>   		}
>
> -		if (obj->active) /* XXX per-vma statistic */
> +		if (vma->active)
>   			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 8a824c5d5348..1d21c5b79215 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -2040,7 +2040,6 @@ i915_gem_object_retire__read(struct drm_i915_gem_request_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;
>
>   	RQ_BUG_ON((obj->flags & (1 << (ring + I915_BO_ACTIVE_SHIFT))) == 0);
>
> @@ -2052,12 +2051,9 @@ i915_gem_object_retire__read(struct drm_i915_gem_request_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 (!list_empty(&obj->vma_list))
> +		list_move_tail(&obj->global_list,
> +			       &request->i915->mm.bound_list);
>
>   	drm_gem_object_unreference(&obj->base);
>   }
> @@ -2567,7 +2563,19 @@ static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
>   {
>   	struct drm_i915_gem_object *obj = vma->obj;
>   	struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
> -	int ret;
> +	int ret, i;
> +
> +	/* First wait upon any activity as retiring the request may
> +	 * have side-effects such as unpinning or even unbinding this vma.
> +	 */
> +	if (vma->active && wait) {
> +		for (i = 0; i < ARRAY_SIZE(vma->last_read); i++) {
> +			ret = i915_wait_request(vma->last_read[i].request);
> +			if (ret)
> +				return ret;
> +		}
> +		RQ_BUG_ON(vma->active);
> +	}
>
>   	if (list_empty(&vma->obj_link))
>   		return 0;
> @@ -2582,12 +2590,6 @@ static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
>
>   	BUG_ON(obj->pages == NULL);
>
> -	if (wait) {
> -		ret = i915_gem_object_wait_rendering(obj, false);
> -		if (ret)
> -			return ret;
> -	}
> -
>   	if (vma->is_ggtt && vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) {
>   		i915_gem_object_finish_gtt(obj);
>
> @@ -3023,9 +3025,8 @@ 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,
> -			       &to_i915(obj->base.dev)->gtt.base.inactive_list);
> +	if (vma && drm_mm_node_allocated(&vma->node) && !vma->active)
> +		list_move_tail(&vma->vm_link, &vma->vm->inactive_list);
>
>   	return 0;
>   }
> @@ -3874,6 +3875,7 @@ struct i915_vma *i915_gem_obj_to_ggtt_view(struct drm_i915_gem_object *obj,
>   void i915_gem_vma_destroy(struct i915_vma *vma)
>   {
>   	WARN_ON(vma->node.allocated);
> +	RQ_BUG_ON(vma->active);
>
>   	/* Keep the vma as a placeholder in the execbuffer reservation lists */
>   	if (!list_empty(&vma->exec_list))
> diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> index 6de8681bb64c..1d4378a4501e 100644
> --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> @@ -1099,6 +1099,8 @@ void i915_vma_move_to_active(struct i915_vma *vma,
>   		}
>   	}
>
> +	vma->active |= 1 << engine;
> +	i915_gem_request_mark_active(req, &vma->last_read[engine]);
>   	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 130ccefb2491..5505603f52af 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -3225,12 +3225,30 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev)
>   	i915_ggtt_flush(dev_priv);
>   }
>
> +static void
> +i915_vma_retire(struct drm_i915_gem_request_active *active,
> +		struct drm_i915_gem_request *rq)
> +{
> +	const unsigned engine = rq->engine->id;
> +	struct i915_vma *vma =
> +		container_of(active, struct i915_vma, last_read[engine]);
> +
> +	RQ_BUG_ON((vma->obj->active & (1 << engine)) == 0);
> +
> +	vma->active &= ~(1 << engine);
> +	if (vma->active)
> +		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);
> @@ -3242,6 +3260,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 4e9553ace33f..c2f2c62ac88d 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.h
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
> @@ -34,6 +34,8 @@
>   #ifndef __I915_GEM_GTT_H__
>   #define __I915_GEM_GTT_H__
>
> +#include "i915_gem_request.h"
> +
>   struct drm_i915_file_private;
>
>   typedef uint32_t gen6_pte_t;
> @@ -180,10 +182,13 @@ struct i915_vma {
>   	struct drm_i915_gem_object *obj;
>   	struct i915_address_space *vm;
>
> +	struct drm_i915_gem_request_active last_read[I915_NUM_RINGS];
> +
>   	/** 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_RINGS;
>   	bool is_ggtt : 1;
>
>   	/**
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 10/11] drm/i915: Mark the context and address space as closed
  2015-12-14 11:36 ` [PATCH 10/11] drm/i915: Mark the context and address space as closed Chris Wilson
@ 2015-12-17 12:37   ` Tvrtko Ursulin
  2015-12-17 12:39     ` Tvrtko Ursulin
  2015-12-17 12:48     ` Chris Wilson
  2015-12-17 14:15   ` Tvrtko Ursulin
  1 sibling, 2 replies; 37+ messages in thread
From: Tvrtko Ursulin @ 2015-12-17 12:37 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


Hi,

On 14/12/15 11:36, Chris Wilson wrote:
> When the user closes the context mark it and the dependent address space
> as closed. As we use an asynchronous destruct method, this has two purposes.
> First it allows us to flag the closed context and detect internal errors if
> we to create any new objects for it (as it is removed from the user's
> namespace, these should be internal bugs only). And secondly, it allows
> us to immediately reap stale vma.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>   drivers/gpu/drm/i915/i915_drv.h         |  4 ++++
>   drivers/gpu/drm/i915/i915_gem.c         | 15 ++++++++-----
>   drivers/gpu/drm/i915/i915_gem_context.c | 39 +++++++++++++++++++++++++++++----
>   drivers/gpu/drm/i915/i915_gem_gtt.c     | 11 +++++++---
>   drivers/gpu/drm/i915/i915_gem_gtt.h     |  9 ++++++++
>   drivers/gpu/drm/i915/i915_gem_stolen.c  |  2 +-
>   6 files changed, 66 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 696469a06715..66ecd6b3df95 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -892,6 +892,8 @@ struct intel_context {
>   	} engine[I915_NUM_RINGS];
>
>   	struct list_head link;
> +
> +	bool closed:1;
>   };
>
>   enum fb_op_origin {
> @@ -2720,6 +2722,8 @@ int __must_check i915_vma_unbind(struct i915_vma *vma);
>    * _guarantee_ VMA in question is _not in use_ anywhere.
>    */
>   int __must_check __i915_vma_unbind_no_wait(struct i915_vma *vma);
> +void i915_vma_close(struct i915_vma *vma);
> +
>   int i915_gem_object_put_pages(struct drm_i915_gem_object *obj);
>   void i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv);
>   void i915_gem_release_mmap(struct drm_i915_gem_object *obj);
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 7c13c27a6470..08ea0b7eda8b 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -2367,12 +2367,13 @@ i915_gem_object_flush_active(struct drm_i915_gem_object *obj)
>   	return 0;
>   }
>
> -static void i915_vma_close(struct i915_vma *vma)

Can't find this in this series?

> +void i915_vma_close(struct i915_vma *vma)
>   {
>   	RQ_BUG_ON(vma->closed);
>   	vma->closed = true;
>
>   	list_del_init(&vma->obj_link);
> +	list_del_init(&vma->vm_link);
>   	if (!vma->active)
>   		WARN_ON(i915_vma_unbind(vma));
>   }
> @@ -2620,12 +2621,13 @@ static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
>   			return ret;
>   	}
>
> -	trace_i915_vma_unbind(vma);
> -
> -	vma->vm->unbind_vma(vma);
> +	if (likely(!vma->vm->closed)) {
> +		trace_i915_vma_unbind(vma);
> +		vma->vm->unbind_vma(vma);
> +	}
>   	vma->bound = 0;
>
> -	list_del_init(&vma->vm_link);
> +	list_move_tail(&vma->vm_link, &vma->vm->unbound_list);
>   	if (vma->is_ggtt) {
>   		if (vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) {
>   			obj->map_and_fenceable = false;
> @@ -2882,7 +2884,7 @@ search_free:
>   		goto err_remove_node;
>
>   	list_move_tail(&obj->global_list, &dev_priv->mm.bound_list);
> -	list_add_tail(&vma->vm_link, &vm->inactive_list);
> +	list_move_tail(&vma->vm_link, &vm->inactive_list);
>
>   	return vma;
>
> @@ -3890,6 +3892,7 @@ void i915_gem_vma_destroy(struct i915_vma *vma)
>   	if (!list_empty(&vma->exec_list))
>   		return;
>
> +	list_del(&vma->vm_link);
>   	if (!vma->is_ggtt)
>   		i915_ppgtt_put(i915_vm_to_ppgtt(vma->vm));
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
> index c4a8a64cd1b2..9669547c7c2d 100644
> --- a/drivers/gpu/drm/i915/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/i915_gem_context.c
> @@ -153,6 +153,7 @@ void i915_gem_context_free(struct kref *ctx_ref)
>   	struct intel_context *ctx = container_of(ctx_ref, typeof(*ctx), ref);
>
>   	trace_i915_context_free(ctx);
> +	RQ_BUG_ON(!ctx->closed);

Normal BUG_ON I think.

>
>   	if (i915.enable_execlists)
>   		intel_lr_context_free(ctx);
> @@ -209,6 +210,36 @@ i915_gem_alloc_context_obj(struct drm_device *dev, size_t size)
>   	return obj;
>   }
>
> +static void i915_ppgtt_close(struct i915_address_space *vm)
> +{
> +	struct list_head *phases[] = {
> +		&vm->active_list,
> +		&vm->inactive_list,
> +		&vm->unbound_list,
> +		NULL,
> +	}, **phase;
> +
> +	RQ_BUG_ON(vm->is_ggtt);
> +	RQ_BUG_ON(vm->closed);

More, and elsewhere.

> +	vm->closed = true;
> +
> +	for (phase = phases; *phase; phase++) {
> +		struct i915_vma *vma, *vn;
> +
> +		list_for_each_entry_safe(vma, vn, *phase, vm_link)
> +			i915_vma_close(vma);

Can't really carry on since I don't see the implementation of this.

Does it wait for retirement?

> +	}
> +}
> +
> +static void context_close(struct intel_context *ctx)
> +{
> +	RQ_BUG_ON(ctx->closed);
> +	ctx->closed = true;
> +	if (ctx->ppgtt)
> +		i915_ppgtt_close(&ctx->ppgtt->base);
> +	i915_gem_context_unreference(ctx);
> +}
> +
>   static struct intel_context *
>   __create_hw_context(struct drm_device *dev,
>   		    struct drm_i915_file_private *file_priv)
> @@ -256,7 +287,7 @@ __create_hw_context(struct drm_device *dev,
>   	return ctx;
>
>   err_out:
> -	i915_gem_context_unreference(ctx);
> +	context_close(ctx);
>   	return ERR_PTR(ret);
>   }
>
> @@ -318,7 +349,7 @@ err_unpin:
>   		i915_gem_object_ggtt_unpin(ctx->legacy_hw_ctx.rcs_state);
>   err_destroy:
>   	idr_remove(&file_priv->context_idr, ctx->user_handle);
> -	i915_gem_context_unreference(ctx);
> +	context_close(ctx);
>   	return ERR_PTR(ret);
>   }
>
> @@ -470,7 +501,7 @@ static int context_idr_cleanup(int id, void *p, void *data)
>   {
>   	struct intel_context *ctx = p;
>
> -	i915_gem_context_unreference(ctx);
> +	context_close(ctx);
>   	return 0;
>   }
>
> @@ -894,7 +925,7 @@ int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
>   	}
>
>   	idr_remove(&ctx->file_priv->context_idr, ctx->user_handle);
> -	i915_gem_context_unreference(ctx);
> +	context_close(ctx);
>   	mutex_unlock(&dev->struct_mutex);
>
>   	DRM_DEBUG_DRIVER("HW context %d destroyed\n", args->ctx_id);
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 9f594c33bd0a..354236d72432 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -2130,6 +2130,7 @@ static void i915_address_space_init(struct i915_address_space *vm,
>   	vm->dev = dev_priv->dev;
>   	INIT_LIST_HEAD(&vm->active_list);
>   	INIT_LIST_HEAD(&vm->inactive_list);
> +	INIT_LIST_HEAD(&vm->unbound_list);
>   	list_add_tail(&vm->global_link, &dev_priv->vm_list);
>   }
>
> @@ -2214,9 +2215,10 @@ void  i915_ppgtt_release(struct kref *kref)
>
>   	trace_i915_ppgtt_release(&ppgtt->base);
>
> -	/* vmas should already be unbound */
> +	/* vmas should already be unbound and destroyed */
>   	WARN_ON(!list_empty(&ppgtt->base.active_list));
>   	WARN_ON(!list_empty(&ppgtt->base.inactive_list));
> +	WARN_ON(!list_empty(&ppgtt->base.unbound_list));
>
>   	list_del(&ppgtt->base.global_link);
>   	drm_mm_takedown(&ppgtt->base.mm);
> @@ -2698,7 +2700,7 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
>   			return ret;
>   		}
>   		vma->bound |= GLOBAL_BIND;
> -		list_add_tail(&vma->vm_link, &ggtt_vm->inactive_list);
> +		list_move_tail(&vma->vm_link, &ggtt_vm->inactive_list);
>   	}
>
>   	/* Clear any non-preallocated blocks */
> @@ -3252,6 +3254,8 @@ __i915_gem_vma_create(struct drm_i915_gem_object *obj,
>   	struct i915_vma *vma;
>   	int i;
>
> +	RQ_BUG_ON(vm->closed);
> +
>   	if (WARN_ON(i915_is_ggtt(vm) != !!ggtt_view))
>   		return ERR_PTR(-EINVAL);
>
> @@ -3259,11 +3263,11 @@ __i915_gem_vma_create(struct drm_i915_gem_object *obj,
>   	if (vma == NULL)
>   		return ERR_PTR(-ENOMEM);
>
> -	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);
> +	list_add(&vma->vm_link, &vm->unbound_list);
>   	vma->vm = vm;
>   	vma->obj = obj;
>   	vma->is_ggtt = i915_is_ggtt(vm);
> @@ -3310,6 +3314,7 @@ i915_gem_obj_lookup_or_create_ggtt_vma(struct drm_i915_gem_object *obj,
>   	if (!vma)
>   		vma = __i915_gem_vma_create(obj, ggtt, view);
>
> +	RQ_BUG_ON(vma->closed);
>   	return vma;
>
>   }
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
> index be7e8526b219..3bd2a4f4990c 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.h
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
> @@ -284,6 +284,8 @@ struct i915_address_space {
>   	u64 start;		/* Start offset always 0 for dri2 */
>   	u64 total;		/* size addr space maps (ex. 2GB for ggtt) */
>
> +	bool closed;
> +
>   	struct i915_page_scratch *scratch_page;
>   	struct i915_page_table *scratch_pt;
>   	struct i915_page_directory *scratch_pd;
> @@ -312,6 +314,13 @@ struct i915_address_space {
>   	 */
>   	struct list_head inactive_list;
>
> +	/**
> +	 * List of vma that have been unbound.
> +	 *
> +	 * A reference is not held on the buffer while on this list.

s/buffer/object/

> +	 */
> +	struct list_head unbound_list;
> +
>   	/* FIXME: Need a more generic return type */
>   	gen6_pte_t (*pte_encode)(dma_addr_t addr,
>   				 enum i915_cache_level level,
> diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
> index 305d58a5f745..4a803311f5bf 100644
> --- a/drivers/gpu/drm/i915/i915_gem_stolen.c
> +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
> @@ -688,7 +688,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
>   		}
>
>   		vma->bound |= GLOBAL_BIND;
> -		list_add_tail(&vma->vm_link, &ggtt->inactive_list);
> +		list_move_tail(&vma->vm_link, &ggtt->inactive_list);
>   	}
>
>   	list_add_tail(&obj->global_list, &dev_priv->mm.bound_list);
>

Regards,

Tvrtko

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

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

* Re: [PATCH 10/11] drm/i915: Mark the context and address space as closed
  2015-12-17 12:37   ` Tvrtko Ursulin
@ 2015-12-17 12:39     ` Tvrtko Ursulin
  2015-12-17 12:48     ` Chris Wilson
  1 sibling, 0 replies; 37+ messages in thread
From: Tvrtko Ursulin @ 2015-12-17 12:39 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


On 17/12/15 12:37, Tvrtko Ursulin wrote:
>
> Hi,
>
> On 14/12/15 11:36, Chris Wilson wrote:
>> When the user closes the context mark it and the dependent address space
>> as closed. As we use an asynchronous destruct method, this has two
>> purposes.
>> First it allows us to flag the closed context and detect internal
>> errors if
>> we to create any new objects for it (as it is removed from the user's
>> namespace, these should be internal bugs only). And secondly, it allows
>> us to immediately reap stale vma.
>>
>> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
>> ---
>>   drivers/gpu/drm/i915/i915_drv.h         |  4 ++++
>>   drivers/gpu/drm/i915/i915_gem.c         | 15 ++++++++-----
>>   drivers/gpu/drm/i915/i915_gem_context.c | 39
>> +++++++++++++++++++++++++++++----
>>   drivers/gpu/drm/i915/i915_gem_gtt.c     | 11 +++++++---
>>   drivers/gpu/drm/i915/i915_gem_gtt.h     |  9 ++++++++
>>   drivers/gpu/drm/i915/i915_gem_stolen.c  |  2 +-
>>   6 files changed, 66 insertions(+), 14 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h
>> b/drivers/gpu/drm/i915/i915_drv.h
>> index 696469a06715..66ecd6b3df95 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -892,6 +892,8 @@ struct intel_context {
>>       } engine[I915_NUM_RINGS];
>>
>>       struct list_head link;
>> +
>> +    bool closed:1;
>>   };
>>
>>   enum fb_op_origin {
>> @@ -2720,6 +2722,8 @@ int __must_check i915_vma_unbind(struct i915_vma
>> *vma);
>>    * _guarantee_ VMA in question is _not in use_ anywhere.
>>    */
>>   int __must_check __i915_vma_unbind_no_wait(struct i915_vma *vma);
>> +void i915_vma_close(struct i915_vma *vma);
>> +
>>   int i915_gem_object_put_pages(struct drm_i915_gem_object *obj);
>>   void i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv);
>>   void i915_gem_release_mmap(struct drm_i915_gem_object *obj);
>> diff --git a/drivers/gpu/drm/i915/i915_gem.c
>> b/drivers/gpu/drm/i915/i915_gem.c
>> index 7c13c27a6470..08ea0b7eda8b 100644
>> --- a/drivers/gpu/drm/i915/i915_gem.c
>> +++ b/drivers/gpu/drm/i915/i915_gem.c
>> @@ -2367,12 +2367,13 @@ i915_gem_object_flush_active(struct
>> drm_i915_gem_object *obj)
>>       return 0;
>>   }
>>
>> -static void i915_vma_close(struct i915_vma *vma)
>
> Can't find this in this series?

Ooops it is in a different mail folder, I did not sport the break in 
patch numbers...

Regards,

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

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

* Re: [PATCH 10/11] drm/i915: Mark the context and address space as closed
  2015-12-17 12:37   ` Tvrtko Ursulin
  2015-12-17 12:39     ` Tvrtko Ursulin
@ 2015-12-17 12:48     ` Chris Wilson
  2015-12-17 13:26       ` Tvrtko Ursulin
  1 sibling, 1 reply; 37+ messages in thread
From: Chris Wilson @ 2015-12-17 12:48 UTC (permalink / raw)
  To: Tvrtko Ursulin; +Cc: intel-gfx

On Thu, Dec 17, 2015 at 12:37:13PM +0000, Tvrtko Ursulin wrote:
> >-static void i915_vma_close(struct i915_vma *vma)
> 
> Can't find this in this series?

Should be the previous patch (9/11: Release vma when the handle is
closed) that hooks in gem_object_close to mark each vma as closed if it
is owned by the file.

http://patchwork.freedesktop.org/patch/68086/

> >diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
> >index c4a8a64cd1b2..9669547c7c2d 100644
> >--- a/drivers/gpu/drm/i915/i915_gem_context.c
> >+++ b/drivers/gpu/drm/i915/i915_gem_context.c
> >@@ -153,6 +153,7 @@ void i915_gem_context_free(struct kref *ctx_ref)
> >  	struct intel_context *ctx = container_of(ctx_ref, typeof(*ctx), ref);
> >
> >  	trace_i915_context_free(ctx);
> >+	RQ_BUG_ON(!ctx->closed);
> 
> Normal BUG_ON I think.

You want a BUG_ON! :-p Just enable them.

> >+	for (phase = phases; *phase; phase++) {
> >+		struct i915_vma *vma, *vn;
> >+
> >+		list_for_each_entry_safe(vma, vn, *phase, vm_link)
> >+			i915_vma_close(vma);
> 
> Can't really carry on since I don't see the implementation of this.
> 
> Does it wait for retirement?

No. i915_vma_close() uses vma tracking to defer the unbind until idle.

> >+	/**
> >+	 * List of vma that have been unbound.
> >+	 *
> >+	 * A reference is not held on the buffer while on this list.
> 
> s/buffer/object/

They are buffer objects! The comment was cut'n'paste. I don't think it
is entirely apt to be talking about the object level active reference
here anyway. But I didn't feel inclined to write something that was even
more confusing.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 06/11] drm/i915: Store owning file on the i915_address_space
  2015-12-17 11:52   ` Tvrtko Ursulin
@ 2015-12-17 13:25     ` Chris Wilson
  0 siblings, 0 replies; 37+ messages in thread
From: Chris Wilson @ 2015-12-17 13:25 UTC (permalink / raw)
  To: Tvrtko Ursulin; +Cc: intel-gfx

On Thu, Dec 17, 2015 at 11:52:06AM +0000, Tvrtko Ursulin wrote:
> >-	ret = __hw_ppgtt_init(dev, ppgtt);
> >+	ret = __hw_ppgtt_init(ppgtt, dev_priv);
> >  	if (ret == 0) {
> >  		kref_init(&ppgtt->ref);
> >  		i915_address_space_init(&ppgtt->base, dev_priv);
> >+		ppgtt->base.file = file_priv;
> 
> I would keep using file_priv since that's what's it's called all
> over the place but whatever.

Personally I have been working towards dropping the _priv from our
nomenclature inside our driver (only on the boundaries from drm do we
care about translating from drm objects to ours) - in a parallel fashion
to using crtc and crtc->base instead of intel_crtc / crtc.

> >diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
> >index bae005a62cfc..4e9553ace33f 100644
> >--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
> >+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
> >@@ -273,12 +273,11 @@ struct i915_pml4 {
> >  struct i915_address_space {
> >  	struct drm_mm mm;
> >  	struct drm_device *dev;
> >+	struct drm_i915_file_private *file;
> 
> Suggest putting a comment documenting when it is NULL and when it is
> valid. Commit says so, but I think comment is also needed.

+       /* Every address space belongs to a struct file - except for the global
+        * GTT that is owned by the driver (and so @file is set to NULL). In
+        * principle, no information should leak from one context to another
+        * (or between files/processes etc) unless explicitly shared by the
+        * owner. Tracking the owner is important in order to free up per-file
+        * objects along with the file, to aide resource tracking, and to
+        * assign blame.
+        */
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 10/11] drm/i915: Mark the context and address space as closed
  2015-12-17 12:48     ` Chris Wilson
@ 2015-12-17 13:26       ` Tvrtko Ursulin
  0 siblings, 0 replies; 37+ messages in thread
From: Tvrtko Ursulin @ 2015-12-17 13:26 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


On 17/12/15 12:48, Chris Wilson wrote:
> On Thu, Dec 17, 2015 at 12:37:13PM +0000, Tvrtko Ursulin wrote:
>>> -static void i915_vma_close(struct i915_vma *vma)
>>
>> Can't find this in this series?
>
> Should be the previous patch (9/11: Release vma when the handle is
> closed) that hooks in gem_object_close to mark each vma as closed if it
> is owned by the file.
>
> http://patchwork.freedesktop.org/patch/68086/

Yeah found it later, mail filtering split the thread to different folders.

>>> diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
>>> index c4a8a64cd1b2..9669547c7c2d 100644
>>> --- a/drivers/gpu/drm/i915/i915_gem_context.c
>>> +++ b/drivers/gpu/drm/i915/i915_gem_context.c
>>> @@ -153,6 +153,7 @@ void i915_gem_context_free(struct kref *ctx_ref)
>>>   	struct intel_context *ctx = container_of(ctx_ref, typeof(*ctx), ref);
>>>
>>>   	trace_i915_context_free(ctx);
>>> +	RQ_BUG_ON(!ctx->closed);
>>
>> Normal BUG_ON I think.
>
> You want a BUG_ON! :-p Just enable them.

No I just gave up on you seeing the light! :>

Point is RQ_BUG_ON is behind CONFIG_DRM_I915_DEBUG_REQUESTS so it is 
wrong to use it for other things.

>>> +	for (phase = phases; *phase; phase++) {
>>> +		struct i915_vma *vma, *vn;
>>> +
>>> +		list_for_each_entry_safe(vma, vn, *phase, vm_link)
>>> +			i915_vma_close(vma);
>>
>> Can't really carry on since I don't see the implementation of this.
>>
>> Does it wait for retirement?
>
> No. i915_vma_close() uses vma tracking to defer the unbind until idle.
>
>>> +	/**
>>> +	 * List of vma that have been unbound.
>>> +	 *
>>> +	 * A reference is not held on the buffer while on this list.
>>
>> s/buffer/object/
>
> They are buffer objects! The comment was cut'n'paste. I don't think it
> is entirely apt to be talking about the object level active reference
> here anyway. But I didn't feel inclined to write something that was even
> more confusing.

# grep buffer i915_gem.c | grep -v ring | grep -v front | grep -v batch 
| grep -v execbuffer | grep -v scanout | wc -l
8

Ok, there is some precedence for the term.

Tvrtko

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

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

* Re: [PATCH 09/11] drm/i915: Release vma when the handle is closed
  2015-12-14 11:36 ` [PATCH 09/11] drm/i915: Release vma when the handle is closed Chris Wilson
@ 2015-12-17 13:46   ` Tvrtko Ursulin
  2015-12-17 14:11     ` Chris Wilson
  2015-12-17 14:21     ` Chris Wilson
  0 siblings, 2 replies; 37+ messages in thread
From: Tvrtko Ursulin @ 2015-12-17 13:46 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


Hi,

On 14/12/15 11:36, Chris Wilson wrote:
> In order to prevent a leak of the vma on shared objects, we need to
> hook into the object_close callback to destroy the vma on the object for
> this file. However, if we destroyed that vma immediately we may cause
> unexpected application stalls as we try to unbind a busy vma - hence we
> defer the unbind to when we retire the vma.
>
> Testcase: igt/gem_ppggtt/flink-and-close-vma-leak
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
> Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com
> ---
>   drivers/gpu/drm/i915/i915_drv.c     |  1 +
>   drivers/gpu/drm/i915/i915_drv.h     |  1 +
>   drivers/gpu/drm/i915/i915_gem.c     | 41 ++++++++++++++++++++++---------------
>   drivers/gpu/drm/i915/i915_gem_gtt.c |  2 ++
>   drivers/gpu/drm/i915/i915_gem_gtt.h |  1 +
>   5 files changed, 30 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index e7eef5fd6918..70979339d58a 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -1656,6 +1656,7 @@ static struct drm_driver driver = {
>   	.debugfs_init = i915_debugfs_init,
>   	.debugfs_cleanup = i915_debugfs_cleanup,
>   #endif
> +	.gem_close_object = i915_gem_close_object,
>   	.gem_free_object = i915_gem_free_object,
>   	.gem_vm_ops = &i915_gem_vm_ops,
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index eb775eb1c693..696469a06715 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2686,6 +2686,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
>   						  size_t size);
>   struct drm_i915_gem_object *i915_gem_object_create_from_data(
>   		struct drm_device *dev, const void *data, size_t size);
> +void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file);
>   void i915_gem_free_object(struct drm_gem_object *obj);
>   void i915_gem_vma_destroy(struct i915_vma *vma);
>
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 1d21c5b79215..7c13c27a6470 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -2367,6 +2367,30 @@ i915_gem_object_flush_active(struct drm_i915_gem_object *obj)
>   	return 0;
>   }
>
> +static void i915_vma_close(struct i915_vma *vma)
> +{
> +	RQ_BUG_ON(vma->closed);

Same complaint as in the previous patch, cannot use RQ_BUG_ON. Maybe 
need GEM_BUG_ON then, don't know.

> +	vma->closed = true;

Hmmm, vma->detached? Because VMA is not really closed. And 
i915_vma_detach - it would symbolise then that VMA has been detached 
from the object and is lingering only on the VM lists.

> +
> +	list_del_init(&vma->obj_link);
> +	if (!vma->active)
> +		WARN_ON(i915_vma_unbind(vma));
> +}
> +
> +void i915_gem_close_object(struct drm_gem_object *gem,
> +			   struct drm_file *file)
> +{
> +	struct drm_i915_gem_object *obj = to_intel_bo(gem);
> +	struct drm_i915_file_private *fpriv = file->driver_priv;
> +	struct i915_vma *vma, *vn;
> +
> +	mutex_lock(&obj->base.dev->struct_mutex);
> +	list_for_each_entry_safe(vma, vn, &obj->vma_list, obj_link)
> +		if (vma->vm->file == fpriv)
> +			i915_vma_close(vma);
> +	mutex_unlock(&obj->base.dev->struct_mutex);
> +}
> +
>   /**
>    * i915_gem_wait_ioctl - implements DRM_IOCTL_I915_GEM_WAIT
>    * @DRM_IOCTL_ARGS: standard ioctl arguments
> @@ -2577,9 +2601,6 @@ static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
>   		RQ_BUG_ON(vma->active);
>   	}
>
> -	if (list_empty(&vma->obj_link))
> -		return 0;
> -
>   	if (!drm_mm_node_allocated(&vma->node)) {
>   		i915_gem_vma_destroy(vma);
>   		return 0;
> @@ -3792,20 +3813,8 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
>   	trace_i915_gem_object_destroy(obj);
>
>   	list_for_each_entry_safe(vma, next, &obj->vma_list, obj_link) {
> -		int ret;
> -
>   		vma->pin_count = 0;
> -		ret = i915_vma_unbind(vma);
> -		if (WARN_ON(ret == -ERESTARTSYS)) {
> -			bool was_interruptible;
> -
> -			was_interruptible = dev_priv->mm.interruptible;
> -			dev_priv->mm.interruptible = false;
> -
> -			WARN_ON(i915_vma_unbind(vma));
> -
> -			dev_priv->mm.interruptible = was_interruptible;
> -		}
> +		i915_vma_close(vma);

In what circumstances can there be any VMAs still left unclosed at this 
point? I thought i915_gem_close_object would had closed them all.

>   	}
>
>   	/* Stolen objects don't hold a ref, but do hold pin count. Fix that up
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 5505603f52af..9f594c33bd0a 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -3240,6 +3240,8 @@ i915_vma_retire(struct drm_i915_gem_request_active *active,
>   		return;
>
>   	list_move_tail(&vma->vm_link, &vma->vm->inactive_list);
> +	if (unlikely(vma->closed))
> +		WARN_ON(i915_vma_unbind(vma));
>   }
>
>   static struct i915_vma *
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
> index c2f2c62ac88d..be7e8526b219 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.h
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
> @@ -190,6 +190,7 @@ struct i915_vma {
>   	unsigned int bound : 4;
>   	unsigned int active : I915_NUM_RINGS;
>   	bool is_ggtt : 1;
> +	bool closed : 1;
>
>   	/**
>   	 * Support different GGTT views into the same object.
>

Regards,

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

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

* Re: [PATCH 09/11] drm/i915: Release vma when the handle is closed
  2015-12-17 13:46   ` Tvrtko Ursulin
@ 2015-12-17 14:11     ` Chris Wilson
  2015-12-17 14:21     ` Chris Wilson
  1 sibling, 0 replies; 37+ messages in thread
From: Chris Wilson @ 2015-12-17 14:11 UTC (permalink / raw)
  To: Tvrtko Ursulin; +Cc: intel-gfx

On Thu, Dec 17, 2015 at 01:46:58PM +0000, Tvrtko Ursulin wrote:
> 
> Hi,
> 
> On 14/12/15 11:36, Chris Wilson wrote:
> >In order to prevent a leak of the vma on shared objects, we need to
> >hook into the object_close callback to destroy the vma on the object for
> >this file. However, if we destroyed that vma immediately we may cause
> >unexpected application stalls as we try to unbind a busy vma - hence we
> >defer the unbind to when we retire the vma.
> >
> >Testcase: igt/gem_ppggtt/flink-and-close-vma-leak
> >Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> >Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
> >Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com
> >---
> >  drivers/gpu/drm/i915/i915_drv.c     |  1 +
> >  drivers/gpu/drm/i915/i915_drv.h     |  1 +
> >  drivers/gpu/drm/i915/i915_gem.c     | 41 ++++++++++++++++++++++---------------
> >  drivers/gpu/drm/i915/i915_gem_gtt.c |  2 ++
> >  drivers/gpu/drm/i915/i915_gem_gtt.h |  1 +
> >  5 files changed, 30 insertions(+), 16 deletions(-)
> >
> >diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> >index e7eef5fd6918..70979339d58a 100644
> >--- a/drivers/gpu/drm/i915/i915_drv.c
> >+++ b/drivers/gpu/drm/i915/i915_drv.c
> >@@ -1656,6 +1656,7 @@ static struct drm_driver driver = {
> >  	.debugfs_init = i915_debugfs_init,
> >  	.debugfs_cleanup = i915_debugfs_cleanup,
> >  #endif
> >+	.gem_close_object = i915_gem_close_object,
> >  	.gem_free_object = i915_gem_free_object,
> >  	.gem_vm_ops = &i915_gem_vm_ops,
> >
> >diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> >index eb775eb1c693..696469a06715 100644
> >--- a/drivers/gpu/drm/i915/i915_drv.h
> >+++ b/drivers/gpu/drm/i915/i915_drv.h
> >@@ -2686,6 +2686,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
> >  						  size_t size);
> >  struct drm_i915_gem_object *i915_gem_object_create_from_data(
> >  		struct drm_device *dev, const void *data, size_t size);
> >+void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file);
> >  void i915_gem_free_object(struct drm_gem_object *obj);
> >  void i915_gem_vma_destroy(struct i915_vma *vma);
> >
> >diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> >index 1d21c5b79215..7c13c27a6470 100644
> >--- a/drivers/gpu/drm/i915/i915_gem.c
> >+++ b/drivers/gpu/drm/i915/i915_gem.c
> >@@ -2367,6 +2367,30 @@ i915_gem_object_flush_active(struct drm_i915_gem_object *obj)
> >  	return 0;
> >  }
> >
> >+static void i915_vma_close(struct i915_vma *vma)
> >+{
> >+	RQ_BUG_ON(vma->closed);
> 
> Same complaint as in the previous patch, cannot use RQ_BUG_ON. Maybe
> need GEM_BUG_ON then, don't know.

Hopefully Joonas will jump in to the rescue. GEM_BUG_ON() works for me.
 
> >+	vma->closed = true;
> 
> Hmmm, vma->detached? Because VMA is not really closed. And
> i915_vma_detach - it would symbolise then that VMA has been detached
> from the object and is lingering only on the VM lists.

Perhaps. I chose _close() simply because that it the user action that
initiated all the actitive (either GEM_CLOSE or GEM_CONTEXT_CLOSE, or
the implicit close from close(fd)/task_exit).

detach feels a little too undefined, close at least implies termination
to me.

Of course on the vfs side, close() is handled by fput/delayed_fput!

Maybe:

gem_object_close -> i915_vma_release
context_close -> i915_ppgtt_release -> i915_vma_release

though release is already used by kref tracking (i915_ppgtt_release).

I'm not keen on using i915_vma_get/i915_vma_put, precisely because we
have managed to avoid using kref vma so far (and so we are not doing
typical reference tracking).

gem_object_close -> i915_vma_detach
context_close -> i915_ppgtt_detach -> i915_vma_detach

Still liking the consistency of close.

gem_object_close -> i915_vma_close
context_close -> i915_ppgtt_close -> i915_vma_close

Could be worse, but also there may easily be a better naming pattern.

> >@@ -3792,20 +3813,8 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
> >  	trace_i915_gem_object_destroy(obj);
> >
> >  	list_for_each_entry_safe(vma, next, &obj->vma_list, obj_link) {
> >-		int ret;
> >-
> >  		vma->pin_count = 0;
> >-		ret = i915_vma_unbind(vma);
> >-		if (WARN_ON(ret == -ERESTARTSYS)) {
> >-			bool was_interruptible;
> >-
> >-			was_interruptible = dev_priv->mm.interruptible;
> >-			dev_priv->mm.interruptible = false;
> >-
> >-			WARN_ON(i915_vma_unbind(vma));
> >-
> >-			dev_priv->mm.interruptible = was_interruptible;
> >-		}
> >+		i915_vma_close(vma);
> 
> In what circumstances can there be any VMAs still left unclosed at
> this point? I thought i915_gem_close_object would had closed them
> all.

vma belonging to GGTT are not owned by any one file but shared, so we
still expect them here as well.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 10/11] drm/i915: Mark the context and address space as closed
  2015-12-14 11:36 ` [PATCH 10/11] drm/i915: Mark the context and address space as closed Chris Wilson
  2015-12-17 12:37   ` Tvrtko Ursulin
@ 2015-12-17 14:15   ` Tvrtko Ursulin
  2015-12-17 14:26     ` Chris Wilson
  1 sibling, 1 reply; 37+ messages in thread
From: Tvrtko Ursulin @ 2015-12-17 14:15 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx



On 14/12/15 11:36, Chris Wilson wrote:
> When the user closes the context mark it and the dependent address space
> as closed. As we use an asynchronous destruct method, this has two purposes.
> First it allows us to flag the closed context and detect internal errors if
> we to create any new objects for it (as it is removed from the user's
> namespace, these should be internal bugs only). And secondly, it allows
> us to immediately reap stale vma.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>   drivers/gpu/drm/i915/i915_drv.h         |  4 ++++
>   drivers/gpu/drm/i915/i915_gem.c         | 15 ++++++++-----
>   drivers/gpu/drm/i915/i915_gem_context.c | 39 +++++++++++++++++++++++++++++----
>   drivers/gpu/drm/i915/i915_gem_gtt.c     | 11 +++++++---
>   drivers/gpu/drm/i915/i915_gem_gtt.h     |  9 ++++++++
>   drivers/gpu/drm/i915/i915_gem_stolen.c  |  2 +-
>   6 files changed, 66 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 696469a06715..66ecd6b3df95 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -892,6 +892,8 @@ struct intel_context {
>   	} engine[I915_NUM_RINGS];
>
>   	struct list_head link;
> +
> +	bool closed:1;
>   };
>
>   enum fb_op_origin {
> @@ -2720,6 +2722,8 @@ int __must_check i915_vma_unbind(struct i915_vma *vma);
>    * _guarantee_ VMA in question is _not in use_ anywhere.
>    */
>   int __must_check __i915_vma_unbind_no_wait(struct i915_vma *vma);
> +void i915_vma_close(struct i915_vma *vma);
> +
>   int i915_gem_object_put_pages(struct drm_i915_gem_object *obj);
>   void i915_gem_release_all_mmaps(struct drm_i915_private *dev_priv);
>   void i915_gem_release_mmap(struct drm_i915_gem_object *obj);
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 7c13c27a6470..08ea0b7eda8b 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -2367,12 +2367,13 @@ i915_gem_object_flush_active(struct drm_i915_gem_object *obj)
>   	return 0;
>   }
>
> -static void i915_vma_close(struct i915_vma *vma)
> +void i915_vma_close(struct i915_vma *vma)
>   {
>   	RQ_BUG_ON(vma->closed);
>   	vma->closed = true;
>
>   	list_del_init(&vma->obj_link);
> +	list_del_init(&vma->vm_link);
>   	if (!vma->active)
>   		WARN_ON(i915_vma_unbind(vma));
>   }
> @@ -2620,12 +2621,13 @@ static int __i915_vma_unbind(struct i915_vma *vma, bool wait)
>   			return ret;
>   	}
>
> -	trace_i915_vma_unbind(vma);
> -
> -	vma->vm->unbind_vma(vma);
> +	if (likely(!vma->vm->closed)) {
> +		trace_i915_vma_unbind(vma);
> +		vma->vm->unbind_vma(vma);
> +	}
>   	vma->bound = 0;
>
> -	list_del_init(&vma->vm_link);
> +	list_move_tail(&vma->vm_link, &vma->vm->unbound_list);
>   	if (vma->is_ggtt) {
>   		if (vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL) {
>   			obj->map_and_fenceable = false;
> @@ -2882,7 +2884,7 @@ search_free:
>   		goto err_remove_node;
>
>   	list_move_tail(&obj->global_list, &dev_priv->mm.bound_list);
> -	list_add_tail(&vma->vm_link, &vm->inactive_list);
> +	list_move_tail(&vma->vm_link, &vm->inactive_list);
>
>   	return vma;
>
> @@ -3890,6 +3892,7 @@ void i915_gem_vma_destroy(struct i915_vma *vma)
>   	if (!list_empty(&vma->exec_list))
>   		return;
>
> +	list_del(&vma->vm_link);
>   	if (!vma->is_ggtt)
>   		i915_ppgtt_put(i915_vm_to_ppgtt(vma->vm));
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
> index c4a8a64cd1b2..9669547c7c2d 100644
> --- a/drivers/gpu/drm/i915/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/i915_gem_context.c
> @@ -153,6 +153,7 @@ void i915_gem_context_free(struct kref *ctx_ref)
>   	struct intel_context *ctx = container_of(ctx_ref, typeof(*ctx), ref);
>
>   	trace_i915_context_free(ctx);
> +	RQ_BUG_ON(!ctx->closed);
>
>   	if (i915.enable_execlists)
>   		intel_lr_context_free(ctx);
> @@ -209,6 +210,36 @@ i915_gem_alloc_context_obj(struct drm_device *dev, size_t size)
>   	return obj;
>   }
>
> +static void i915_ppgtt_close(struct i915_address_space *vm)
> +{
> +	struct list_head *phases[] = {
> +		&vm->active_list,
> +		&vm->inactive_list,
> +		&vm->unbound_list,
> +		NULL,
> +	}, **phase;
> +
> +	RQ_BUG_ON(vm->is_ggtt);
> +	RQ_BUG_ON(vm->closed);
> +	vm->closed = true;
> +
> +	for (phase = phases; *phase; phase++) {
> +		struct i915_vma *vma, *vn;
> +
> +		list_for_each_entry_safe(vma, vn, *phase, vm_link)
> +			i915_vma_close(vma);
> +	}
> +}

Hm so VMAs get unlinked from everywhere, but then on retire goes back to 
inactive. Is it not a bit weird?

Why it is needed to unlink VMAs from everywhere when marking them as closed?

And actually on retire objects are ahead of VMAs in the req->active_list 
so the last object unreference happens before the last vma is retired, 
which is even weirder.

Am I missing something?

Regards,

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

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

* Re: [PATCH 09/11] drm/i915: Release vma when the handle is closed
  2015-12-17 13:46   ` Tvrtko Ursulin
  2015-12-17 14:11     ` Chris Wilson
@ 2015-12-17 14:21     ` Chris Wilson
  2015-12-17 14:32       ` Tvrtko Ursulin
  1 sibling, 1 reply; 37+ messages in thread
From: Chris Wilson @ 2015-12-17 14:21 UTC (permalink / raw)
  To: Tvrtko Ursulin; +Cc: intel-gfx

On Thu, Dec 17, 2015 at 01:46:58PM +0000, Tvrtko Ursulin wrote:
> >  	list_for_each_entry_safe(vma, next, &obj->vma_list, obj_link) {
> >-		int ret;
> >-
> >  		vma->pin_count = 0;
> >-		ret = i915_vma_unbind(vma);
> >-		if (WARN_ON(ret == -ERESTARTSYS)) {
> >-			bool was_interruptible;
> >-
> >-			was_interruptible = dev_priv->mm.interruptible;
> >-			dev_priv->mm.interruptible = false;
> >-
> >-			WARN_ON(i915_vma_unbind(vma));
> >-
> >-			dev_priv->mm.interruptible = was_interruptible;
> >-		}
> >+		i915_vma_close(vma);
> 
> In what circumstances can there be any VMAs still left unclosed at
> this point? I thought i915_gem_close_object would had closed them
> all.


diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 688162703070..edfa5ebc4e77 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3857,7 +3857,14 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
 
        trace_i915_gem_object_destroy(obj);
 
+       /* All file-owned VMA should have been released by this point (through
+        * i915_gem_close_object). However, the object may also be bound into
+        * the global GTT (e.g. older GPUs without per-process support, or
+        * for direct access through the GTT either for the user or for
+        * scanout). Those VMA still need to unbound now.
+        */
        list_for_each_entry_safe(vma, next, &obj->vma_list, obj_link) {
+               RQ_BUG_ON(!i915_is_ggtt(vma->vm));
                RQ_BUG_ON(vma->active);
                vma->pin_count = 0;
                i915_vma_close(vma);

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 10/11] drm/i915: Mark the context and address space as closed
  2015-12-17 14:15   ` Tvrtko Ursulin
@ 2015-12-17 14:26     ` Chris Wilson
  2015-12-17 14:35       ` Tvrtko Ursulin
  0 siblings, 1 reply; 37+ messages in thread
From: Chris Wilson @ 2015-12-17 14:26 UTC (permalink / raw)
  To: Tvrtko Ursulin; +Cc: intel-gfx

On Thu, Dec 17, 2015 at 02:15:52PM +0000, Tvrtko Ursulin wrote:
> >+static void i915_ppgtt_close(struct i915_address_space *vm)
> >+{
> >+	struct list_head *phases[] = {
> >+		&vm->active_list,
> >+		&vm->inactive_list,
> >+		&vm->unbound_list,
> >+		NULL,
> >+	}, **phase;
> >+
> >+	RQ_BUG_ON(vm->is_ggtt);
> >+	RQ_BUG_ON(vm->closed);
> >+	vm->closed = true;
> >+
> >+	for (phase = phases; *phase; phase++) {
> >+		struct i915_vma *vma, *vn;
> >+
> >+		list_for_each_entry_safe(vma, vn, *phase, vm_link)
> >+			i915_vma_close(vma);
> >+	}
> >+}
> 
> Hm so VMAs get unlinked from everywhere, but then on retire goes
> back to inactive. Is it not a bit weird?

Very weird. In the end, I have to stop unlinking in i915_vma_close()
from the vm lists.
 
> Why it is needed to unlink VMAs from everywhere when marking them as closed?

Indeed, it was just to try and keep this walk short. But I realised that
this would actually also foul up the evict/shrinker (by hiding objects
from them that should be thrown away).
 
> And actually on retire objects are ahead of VMAs in the
> req->active_list so the last object unreference happens before the
> last vma is retired, which is even weirder.
> 
> Am I missing something?

That shouldn't happen. The i915_gem_object_retire_read is run after the
i915_vma_retire.

I had added some commentary to i915_vma_move_to_active() that hopefully
explains the interdependences between retire callbacks (mostly to try
and prevent breakage later).

@@ -1075,7 +1075,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*.
+        */
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 09/11] drm/i915: Release vma when the handle is closed
  2015-12-17 14:21     ` Chris Wilson
@ 2015-12-17 14:32       ` Tvrtko Ursulin
  0 siblings, 0 replies; 37+ messages in thread
From: Tvrtko Ursulin @ 2015-12-17 14:32 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx, Daniele Ceraolo Spurio


On 17/12/15 14:21, Chris Wilson wrote:
> On Thu, Dec 17, 2015 at 01:46:58PM +0000, Tvrtko Ursulin wrote:
>>>   	list_for_each_entry_safe(vma, next, &obj->vma_list, obj_link) {
>>> -		int ret;
>>> -
>>>   		vma->pin_count = 0;
>>> -		ret = i915_vma_unbind(vma);
>>> -		if (WARN_ON(ret == -ERESTARTSYS)) {
>>> -			bool was_interruptible;
>>> -
>>> -			was_interruptible = dev_priv->mm.interruptible;
>>> -			dev_priv->mm.interruptible = false;
>>> -
>>> -			WARN_ON(i915_vma_unbind(vma));
>>> -
>>> -			dev_priv->mm.interruptible = was_interruptible;
>>> -		}
>>> +		i915_vma_close(vma);
>>
>> In what circumstances can there be any VMAs still left unclosed at
>> this point? I thought i915_gem_close_object would had closed them
>> all.
>
>
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 688162703070..edfa5ebc4e77 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -3857,7 +3857,14 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
>
>          trace_i915_gem_object_destroy(obj);
>
> +       /* All file-owned VMA should have been released by this point (through
> +        * i915_gem_close_object). However, the object may also be bound into
> +        * the global GTT (e.g. older GPUs without per-process support, or
> +        * for direct access through the GTT either for the user or for
> +        * scanout). Those VMA still need to unbound now.
> +        */
>          list_for_each_entry_safe(vma, next, &obj->vma_list, obj_link) {
> +               RQ_BUG_ON(!i915_is_ggtt(vma->vm));
>                  RQ_BUG_ON(vma->active);
>                  vma->pin_count = 0;
>                  i915_vma_close(vma);
>

Ah yes, I've missed that detail. Very good to have it in a comment (and 
assert).

Regards,

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

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

* Re: [PATCH 10/11] drm/i915: Mark the context and address space as closed
  2015-12-17 14:26     ` Chris Wilson
@ 2015-12-17 14:35       ` Tvrtko Ursulin
  0 siblings, 0 replies; 37+ messages in thread
From: Tvrtko Ursulin @ 2015-12-17 14:35 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


On 17/12/15 14:26, Chris Wilson wrote:
> On Thu, Dec 17, 2015 at 02:15:52PM +0000, Tvrtko Ursulin wrote:
>>> +static void i915_ppgtt_close(struct i915_address_space *vm)
>>> +{
>>> +	struct list_head *phases[] = {
>>> +		&vm->active_list,
>>> +		&vm->inactive_list,
>>> +		&vm->unbound_list,
>>> +		NULL,
>>> +	}, **phase;
>>> +
>>> +	RQ_BUG_ON(vm->is_ggtt);
>>> +	RQ_BUG_ON(vm->closed);
>>> +	vm->closed = true;
>>> +
>>> +	for (phase = phases; *phase; phase++) {
>>> +		struct i915_vma *vma, *vn;
>>> +
>>> +		list_for_each_entry_safe(vma, vn, *phase, vm_link)
>>> +			i915_vma_close(vma);
>>> +	}
>>> +}
>>
>> Hm so VMAs get unlinked from everywhere, but then on retire goes
>> back to inactive. Is it not a bit weird?
>
> Very weird. In the end, I have to stop unlinking in i915_vma_close()
> from the vm lists.
>
>> Why it is needed to unlink VMAs from everywhere when marking them as closed?
>
> Indeed, it was just to try and keep this walk short. But I realised that
> this would actually also foul up the evict/shrinker (by hiding objects
> from them that should be thrown away).
>
>> And actually on retire objects are ahead of VMAs in the
>> req->active_list so the last object unreference happens before the
>> last vma is retired, which is even weirder.
>>
>> Am I missing something?
>
> That shouldn't happen. The i915_gem_object_retire_read is run after the
> i915_vma_retire.
>
> I had added some commentary to i915_vma_move_to_active() that hopefully
> explains the interdependences between retire callbacks (mostly to try
> and prevent breakage later).
>
> @@ -1075,7 +1075,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*.
> +        */

I don't know how I concluded active VMA is after the active object, and 
I specifically saw the order and list_move.

Again, very good to document that, so something good at least came out 
of it. :)


Regards,

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

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

* ✗ failure: UK.CI.checkpatch.pl
  2015-12-14 11:36 [PATCH 01/11] drm/i915: Introduce drm_i915_gem_request_node for request tracking Chris Wilson
                   ` (11 preceding siblings ...)
  2015-12-15 10:51 ` [PATCH v2] drm/i915: Introduce drm_i915_gem_request_active " Chris Wilson
@ 2015-12-17 14:48 ` Patchwork
  12 siblings, 0 replies; 37+ messages in thread
From: Patchwork @ 2015-12-17 14:48 UTC (permalink / raw)
  To: Chris Wilson, damien.lespiau; +Cc: intel-gfx

== Summary ==

  • Testing [v2] drm/i915: Introduce drm_i915_gem_request_active for request tracking
  • Testing [02/11] drm/i915: Refactor activity tracking for requests

WARNING: Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()
#680: FILE: drivers/gpu/drm/i915/i915_gem_request.h:123:
+#define RQ_BUG_ON(expr) BUG_ON(expr)

WARNING: storage class should be at the beginning of the declaration
#701: FILE: drivers/gpu/drm/i915/i915_gem_request.h:218:
+inline static void init_request_active(struct drm_i915_gem_request_active *active,

ERROR: inline keyword should sit between storage class and type
#701: FILE: drivers/gpu/drm/i915/i915_gem_request.h:218:
+inline static void init_request_active(struct drm_i915_gem_request_active *active,


Your patch has style problems, please review.

NOTE: Ignored message types: BLOCK_COMMENT_STYLE COMMIT_LOG_LONG_LINE COMPLEX_MACRO FILE_PATH_CHANGES GIT_COMMIT_ID SPLIT_STRING

NOTE: If any of the errors are false positives, please report
      them to the maintainer, see CHECKPATCH in MAINTAINERS.

  • Testing [03/11] drm/i915: Rename vma->*_list to *_link for consistency
  • Testing [04/11] drm/i915: Amalgamate GGTT/ppGTT vma debug list walkers
  • Testing [05/11] drm/i915: Reduce the pointer dance of i915_is_ggtt()
  • Testing [06/11] drm/i915: Store owning file on the i915_address_space
  • Testing [07/11] drm/i915: i915_vma_move_to_active prep patch

WARNING: Missing a blank line after declarations
#134: FILE: drivers/gpu/drm/i915/i915_gem_execbuffer.c:1097:
+			struct drm_i915_private *dev_priv = req->i915;
+			list_move_tail(&dev_priv->fence_regs[obj->fence_reg].lru_list,


Your patch has style problems, please review.

NOTE: Ignored message types: BLOCK_COMMENT_STYLE COMMIT_LOG_LONG_LINE COMPLEX_MACRO FILE_PATH_CHANGES GIT_COMMIT_ID SPLIT_STRING

NOTE: If any of the errors are false positives, please report
      them to the maintainer, see CHECKPATCH in MAINTAINERS.

  • Testing [08/11] drm/i915: Track active vma requests
  • Testing [10/11] drm/i915: Mark the context and address space as closed
  • Testing [11/11] Revert "drm/i915: Clean up associated VMAs on context destruction"

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

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

end of thread, other threads:[~2015-12-17 14:48 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-14 11:36 [PATCH 01/11] drm/i915: Introduce drm_i915_gem_request_node for request tracking Chris Wilson
2015-12-14 11:36 ` [PATCH 02/11] drm/i915: Refactor activity tracking for requests Chris Wilson
2015-12-16 17:16   ` Tvrtko Ursulin
2015-12-16 17:31     ` Chris Wilson
2015-12-14 11:36 ` [PATCH 03/11] drm/i915: Rename vma->*_list to *_link for consistency Chris Wilson
2015-12-17 11:14   ` Tvrtko Ursulin
2015-12-17 11:24     ` Chris Wilson
2015-12-17 11:45       ` Chris Wilson
2015-12-14 11:36 ` [PATCH 04/11] drm/i915: Amalgamate GGTT/ppGTT vma debug list walkers Chris Wilson
2015-12-17 11:21   ` Tvrtko Ursulin
2015-12-14 11:36 ` [PATCH 05/11] drm/i915: Reduce the pointer dance of i915_is_ggtt() Chris Wilson
2015-12-17 11:31   ` Tvrtko Ursulin
2015-12-14 11:36 ` [PATCH 06/11] drm/i915: Store owning file on the i915_address_space Chris Wilson
2015-12-17 11:52   ` Tvrtko Ursulin
2015-12-17 13:25     ` Chris Wilson
2015-12-14 11:36 ` [PATCH 07/11] drm/i915: i915_vma_move_to_active prep patch Chris Wilson
2015-12-17 12:04   ` Tvrtko Ursulin
2015-12-14 11:36 ` [PATCH 08/11] drm/i915: Track active vma requests Chris Wilson
2015-12-17 12:26   ` Tvrtko Ursulin
2015-12-14 11:36 ` [PATCH 09/11] drm/i915: Release vma when the handle is closed Chris Wilson
2015-12-17 13:46   ` Tvrtko Ursulin
2015-12-17 14:11     ` Chris Wilson
2015-12-17 14:21     ` Chris Wilson
2015-12-17 14:32       ` Tvrtko Ursulin
2015-12-14 11:36 ` [PATCH 10/11] drm/i915: Mark the context and address space as closed Chris Wilson
2015-12-17 12:37   ` Tvrtko Ursulin
2015-12-17 12:39     ` Tvrtko Ursulin
2015-12-17 12:48     ` Chris Wilson
2015-12-17 13:26       ` Tvrtko Ursulin
2015-12-17 14:15   ` Tvrtko Ursulin
2015-12-17 14:26     ` Chris Wilson
2015-12-17 14:35       ` Tvrtko Ursulin
2015-12-14 11:36 ` [PATCH 11/11] Revert "drm/i915: Clean up associated VMAs on context destruction" Chris Wilson
2015-12-14 15:58 ` [PATCH 01/11] drm/i915: Introduce drm_i915_gem_request_node for request tracking Tvrtko Ursulin
2015-12-14 16:11   ` Chris Wilson
2015-12-15 10:51 ` [PATCH v2] drm/i915: Introduce drm_i915_gem_request_active " Chris Wilson
2015-12-17 14:48 ` ✗ failure: UK.CI.checkpatch.pl Patchwork

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.