All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/28] Replace seqno values with request structures
@ 2014-11-24 18:49 John.C.Harrison
  2014-11-24 18:49 ` [PATCH v3 01/28] drm/i915: Ensure OLS & PLR are always in sync John.C.Harrison
                   ` (29 more replies)
  0 siblings, 30 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

There is a general feeling that it is better to move away from using a simple
integer 'seqno' value to track batch buffer completion. Instead, the request
structure should be used. That provides for much more flexibility going
forwards. Especially which things like a GPU scheduler (which can re-order batch
buffers and hence seqnos after submission to the hardware), Android sync points
and other such features which potentially make seqno usage more and more
complex.

This patch set does the work of converting most of the driver to use request
structures in preference to seqno values. The only place left that still uses
seqnos is the semaphore code. It was decided to leave that alone for the time
being as the semaphores are hardware based and the hardware only understands
seqno values.

v2: Rebased to newer nightly tree which significantly changed some of the
display MMIO flip code (including making __wait_request public and renaming
it).

v3: Rebased to yet another nightly tree which included execlist pin/unpin
patches. NB: this is based on a tree including a pending update for an unpin
bug. Also includes a fix for a clash with the shrinker.

[Patches against drm-intel-nightly tree fetched 24/11/2014]

John Harrison (28):
  drm/i915: Ensure OLS & PLR are always in sync
  drm/i915: Add reference count to request structure
  drm/i915: Add helper functions to aid seqno -> request transition
  drm/i915: Replace last_[rwf]_seqno with last_[rwf]_req
  drm/i915: Convert i915_gem_ring_throttle to use requests
  drm/i915: Ensure requests stick around during waits
  drm/i915: Remove 'outstanding_lazy_seqno'
  drm/i915: Make 'i915_gem_check_olr' actually check by request not seqno
  drm/i915: Convert 'last_flip_req' to be a request not a seqno
  drm/i915: Convert i915_wait_seqno to i915_wait_request
  drm/i915: Add IRQ friendly request deference facility
  drm/i915: Convert mmio_flip::seqno to struct request
  drm/i915: Convert __wait_seqno() to __wait_request()
  drm/i915: Remove obsolete seqno parameter from 'i915_add_request'
  drm/i915: Convert 'flip_queued_seqno' into 'flip_queued_request'
  drm/i915: Convert trace functions from seqno to request
  drm/i915: Convert 'trace_irq' to use requests rather than seqnos
  drm/i915: Convert 'ring_idle()' to use requests not seqnos
  drm/i915: Connect requests to rings at creation not submission
  drm/i915: Convert 'i915_seqno_passed' calls into 'i915_gem_request_completed'
  drm/i915: Remove the now redundant 'obj->ring'
  drm/i915: Cache request completion status
  drm/i915: Zero fill the request structure
  drm/i915: Spinlock protection for request list
  drm/i915: Interrupt driven request completion
  drm/i915: Remove obsolete parameter to i915_gem_request_completed()
  drm/i915: Add unique id to the request structure for debugging
  drm/i915: Additional request structure tracing

 drivers/gpu/drm/i915/i915_debugfs.c          |   20 +-
 drivers/gpu/drm/i915/i915_drv.h              |   97 ++++++--
 drivers/gpu/drm/i915/i915_gem.c              |  323 ++++++++++++++++----------
 drivers/gpu/drm/i915/i915_gem_context.c      |    3 +-
 drivers/gpu/drm/i915/i915_gem_execbuffer.c   |   10 +-
 drivers/gpu/drm/i915/i915_gem_gtt.h          |    4 +-
 drivers/gpu/drm/i915/i915_gem_render_state.c |    2 +-
 drivers/gpu/drm/i915/i915_gem_tiling.c       |    2 +-
 drivers/gpu/drm/i915/i915_gpu_error.c        |    7 +-
 drivers/gpu/drm/i915/i915_irq.c              |   16 +-
 drivers/gpu/drm/i915/i915_trace.h            |   69 +++---
 drivers/gpu/drm/i915/intel_display.c         |   47 ++--
 drivers/gpu/drm/i915/intel_drv.h             |    5 +-
 drivers/gpu/drm/i915/intel_lrc.c             |   72 +++---
 drivers/gpu/drm/i915/intel_overlay.c         |   26 ++-
 drivers/gpu/drm/i915/intel_ringbuffer.c      |   81 ++++---
 drivers/gpu/drm/i915/intel_ringbuffer.h      |   25 +-
 17 files changed, 510 insertions(+), 299 deletions(-)

-- 
1.7.9.5

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

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

* [PATCH v3 01/28] drm/i915: Ensure OLS & PLR are always in sync
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-24 18:49 ` [PATCH v3 02/28] drm/i915: Add reference count to request structure John.C.Harrison
                   ` (28 subsequent siblings)
  29 siblings, 0 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The aim is to replace seqno values with request structures. A step along the way
is to switch to using the PLR in preference to the OLS. That requires the PLR to
only be valid when and only when the OLS is also valid. I.e., the two must be
kept in lock step. Then, code which was using the OLS can be safely switched
over to using the PLR instead.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/intel_lrc.c        |   55 ++++++++++++++++++-------------
 drivers/gpu/drm/i915/intel_ringbuffer.c |   29 +++++++++++-----
 2 files changed, 54 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index e588376..98a4b119 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -879,37 +879,48 @@ void intel_lr_context_unpin(struct intel_engine_cs *ring,
 static int logical_ring_alloc_seqno(struct intel_engine_cs *ring,
 				    struct intel_context *ctx)
 {
+	struct drm_i915_gem_request *request;
 	int ret;
 
-	if (ring->outstanding_lazy_seqno)
-		return 0;
+	/* XXX: The aim is to replace seqno values with request structures.
+	 * A step along the way is to switch to using the PLR in preference
+	 * to the OLS. That requires the PLR to only be valid when the OLS is
+	 * also valid. I.e., the two must be kept in step. */
 
-	if (ring->preallocated_lazy_request == NULL) {
-		struct drm_i915_gem_request *request;
+	if (ring->outstanding_lazy_seqno) {
+		WARN_ON(ring->preallocated_lazy_request == NULL);
+		return 0;
+	}
+	WARN_ON(ring->preallocated_lazy_request != NULL);
 
-		request = kmalloc(sizeof(*request), GFP_KERNEL);
-		if (request == NULL)
-			return -ENOMEM;
+	request = kmalloc(sizeof(*request), GFP_KERNEL);
+	if (request == NULL)
+		return -ENOMEM;
 
-		if (ctx != ring->default_context) {
-			ret = intel_lr_context_pin(ring, ctx);
-			if (ret) {
-				kfree(request);
-				return ret;
-			}
+	if (ctx != ring->default_context) {
+		ret = intel_lr_context_pin(ring, ctx);
+		if (ret) {
+			kfree(request);
+			return ret;
 		}
+	}
 
-		/* Hold a reference to the context this request belongs to
-		 * (we will need it when the time comes to emit/retire the
-		 * request).
-		 */
-		request->ctx = ctx;
-		i915_gem_context_reference(request->ctx);
-
-		ring->preallocated_lazy_request = request;
+	ret = i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_seqno);
+	if (ret) {
+		intel_lr_context_unpin(ring, ctx);
+		kfree(request);
+		return ret;
 	}
 
-	return i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_seqno);
+	/* Hold a reference to the context this request belongs to
+	 * (we will need it when the time comes to emit/retire the
+	 * request).
+	 */
+	request->ctx = ctx;
+	i915_gem_context_reference(request->ctx);
+
+	ring->preallocated_lazy_request = request;
+	return 0;
 }
 
 static int logical_ring_wait_request(struct intel_ringbuffer *ringbuf,
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 1d01b51..9fe1307 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -2024,20 +2024,33 @@ int intel_ring_idle(struct intel_engine_cs *ring)
 static int
 intel_ring_alloc_seqno(struct intel_engine_cs *ring)
 {
-	if (ring->outstanding_lazy_seqno)
+	int ret;
+	struct drm_i915_gem_request *request;
+
+	/* XXX: The aim is to replace seqno values with request structures.
+	 * A step along the way is to switch to using the PLR in preference
+	 * to the OLS. That requires the PLR to only be valid when the OLS
+	 * is also valid. I.e., the two must be kept in step. */
+
+	if (ring->outstanding_lazy_seqno) {
+		WARN_ON(ring->preallocated_lazy_request == NULL);
 		return 0;
+	}
 
-	if (ring->preallocated_lazy_request == NULL) {
-		struct drm_i915_gem_request *request;
+	WARN_ON(ring->preallocated_lazy_request != NULL);
 
-		request = kmalloc(sizeof(*request), GFP_KERNEL);
-		if (request == NULL)
-			return -ENOMEM;
+	request = kmalloc(sizeof(*request), GFP_KERNEL);
+	if (request == NULL)
+		return -ENOMEM;
 
-		ring->preallocated_lazy_request = request;
+	ret = i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_seqno);
+	if (ret) {
+		kfree(request);
+		return ret;
 	}
 
-	return i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_seqno);
+	ring->preallocated_lazy_request = request;
+	return 0;
 }
 
 static int __intel_ring_prepare(struct intel_engine_cs *ring,
-- 
1.7.9.5

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

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

* [PATCH v3 02/28] drm/i915: Add reference count to request structure
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
  2014-11-24 18:49 ` [PATCH v3 01/28] drm/i915: Ensure OLS & PLR are always in sync John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-24 18:49 ` [PATCH v3 03/28] drm/i915: Add helper functions to aid seqno -> request transition John.C.Harrison
                   ` (27 subsequent siblings)
  29 siblings, 0 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The plan is to use request structures everywhere that seqno values were
previously used. This means saving pointers to structures in places that used to
be simple integers. In turn, that means that the target structure now needs much
more stringent lifetime tracking. That is, it must not be freed while some other
random object still holds a pointer to it.

To achieve this tracking, a reference count needs to be added. Whenever a
pointer to the structure is saved away, the count must be incremented and the
free must only occur when all references have been released.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h         |   28 ++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_gem.c         |   20 ++++++++++++++------
 drivers/gpu/drm/i915/intel_lrc.c        |    4 +++-
 drivers/gpu/drm/i915/intel_ringbuffer.c |    4 +++-
 4 files changed, 48 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f6f92f1..a317adf 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1995,6 +1995,8 @@ void i915_gem_track_fb(struct drm_i915_gem_object *old,
  * an emission time with seqnos for tracking how far ahead of the GPU we are.
  */
 struct drm_i915_gem_request {
+	struct kref ref;
+
 	/** On Which ring this request was generated */
 	struct intel_engine_cs *ring;
 
@@ -2024,6 +2026,32 @@ struct drm_i915_gem_request {
 	struct list_head client_list;
 };
 
+void i915_gem_request_free(struct kref *req_ref);
+
+static inline void
+i915_gem_request_reference(struct drm_i915_gem_request *req)
+{
+	kref_get(&req->ref);
+}
+
+static inline void
+i915_gem_request_unreference(struct drm_i915_gem_request *req)
+{
+	kref_put(&req->ref, i915_gem_request_free);
+}
+
+static inline void i915_gem_request_assign(struct drm_i915_gem_request **pdst,
+					   struct drm_i915_gem_request *src)
+{
+	if (src)
+		i915_gem_request_reference(src);
+
+	if (*pdst)
+		i915_gem_request_unreference(*pdst);
+
+	*pdst = src;
+}
+
 struct drm_i915_file_private {
 	struct drm_i915_private *dev_priv;
 	struct drm_file *file;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 3765027..569c2da 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2569,21 +2569,30 @@ static void i915_set_reset_status(struct drm_i915_private *dev_priv,
 
 static void i915_gem_free_request(struct drm_i915_gem_request *request)
 {
-	struct intel_context *ctx = request->ctx;
-
 	list_del(&request->list);
 	i915_gem_request_remove_from_client(request);
 
+	i915_gem_request_unreference(request);
+}
+
+void i915_gem_request_free(struct kref *req_ref)
+{
+	struct drm_i915_gem_request *req = container_of(req_ref,
+						 typeof(*req), ref);
+	struct intel_context *ctx = req->ctx;
+
 	if (ctx) {
 		if (i915.enable_execlists) {
-			struct intel_engine_cs *ring = request->ring;
+			struct intel_engine_cs *ring = req->ring;
 
 			if (ctx != ring->default_context)
 				intel_lr_context_unpin(ring, ctx);
 		}
+
 		i915_gem_context_unreference(ctx);
 	}
-	kfree(request);
+
+	kfree(req);
 }
 
 struct drm_i915_gem_request *
@@ -2671,8 +2680,7 @@ static void i915_gem_reset_ring_cleanup(struct drm_i915_private *dev_priv,
 	}
 
 	/* These may not have been flush before the reset, do so now */
-	kfree(ring->preallocated_lazy_request);
-	ring->preallocated_lazy_request = NULL;
+	i915_gem_request_assign(&ring->preallocated_lazy_request, NULL);
 	ring->outstanding_lazy_seqno = 0;
 }
 
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 98a4b119..fe66482 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -905,6 +905,8 @@ static int logical_ring_alloc_seqno(struct intel_engine_cs *ring,
 		}
 	}
 
+	kref_init(&request->ref);
+
 	ret = i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_seqno);
 	if (ret) {
 		intel_lr_context_unpin(ring, ctx);
@@ -1365,7 +1367,7 @@ void intel_logical_ring_cleanup(struct intel_engine_cs *ring)
 
 	intel_logical_ring_stop(ring);
 	WARN_ON((I915_READ_MODE(ring) & MODE_IDLE) == 0);
-	ring->preallocated_lazy_request = NULL;
+	i915_gem_request_assign(&ring->preallocated_lazy_request, NULL);
 	ring->outstanding_lazy_seqno = 0;
 
 	if (ring->cleanup)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 9fe1307..fbeaa3a 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1870,7 +1870,7 @@ void intel_cleanup_ring_buffer(struct intel_engine_cs *ring)
 
 	intel_unpin_ringbuffer_obj(ringbuf);
 	intel_destroy_ringbuffer_obj(ringbuf);
-	ring->preallocated_lazy_request = NULL;
+	i915_gem_request_assign(&ring->preallocated_lazy_request, NULL);
 	ring->outstanding_lazy_seqno = 0;
 
 	if (ring->cleanup)
@@ -2043,6 +2043,8 @@ intel_ring_alloc_seqno(struct intel_engine_cs *ring)
 	if (request == NULL)
 		return -ENOMEM;
 
+	kref_init(&request->ref);
+
 	ret = i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_seqno);
 	if (ret) {
 		kfree(request);
-- 
1.7.9.5

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

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

* [PATCH v3 03/28] drm/i915: Add helper functions to aid seqno -> request transition
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
  2014-11-24 18:49 ` [PATCH v3 01/28] drm/i915: Ensure OLS & PLR are always in sync John.C.Harrison
  2014-11-24 18:49 ` [PATCH v3 02/28] drm/i915: Add reference count to request structure John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-24 18:49 ` [PATCH v3 04/28] drm/i915: Replace last_[rwf]_seqno with last_[rwf]_req John.C.Harrison
                   ` (26 subsequent siblings)
  29 siblings, 0 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Added helper functions for retrieving the ring and seqno entries from a request
structure. This allows the internal workings of the request structure to be
hidden from code that is using these. It also allows for useful
workarounds/debug code to be added as or when necessary.

Note that it is intended that the majority (if not all) uses of the seqno
accessor will disappear eventually as code is updated to use the request
structure itself rather than working with seqno values.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h         |   12 ++++++++++++
 drivers/gpu/drm/i915/intel_ringbuffer.h |    7 +++++++
 2 files changed, 19 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a317adf..bce0346 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2028,6 +2028,18 @@ struct drm_i915_gem_request {
 
 void i915_gem_request_free(struct kref *req_ref);
 
+static inline uint32_t
+i915_gem_request_get_seqno(struct drm_i915_gem_request *req)
+{
+	return req ? req->seqno : 0;
+}
+
+static inline struct intel_engine_cs *
+i915_gem_request_get_ring(struct drm_i915_gem_request *req)
+{
+	return req ? req->ring : NULL;
+}
+
 static inline void
 i915_gem_request_reference(struct drm_i915_gem_request *req)
 {
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index fe426cf..20636e0 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -442,6 +442,13 @@ static inline u32 intel_ring_get_seqno(struct intel_engine_cs *ring)
 	return ring->outstanding_lazy_seqno;
 }
 
+static inline struct drm_i915_gem_request *
+intel_ring_get_request(struct intel_engine_cs *ring)
+{
+	BUG_ON(ring->preallocated_lazy_request == NULL);
+	return ring->preallocated_lazy_request;
+}
+
 static inline void i915_trace_irq_get(struct intel_engine_cs *ring, u32 seqno)
 {
 	if (ring->trace_irq_seqno == 0 && ring->irq_get(ring))
-- 
1.7.9.5

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

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

* [PATCH v3 04/28] drm/i915: Replace last_[rwf]_seqno with last_[rwf]_req
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (2 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 03/28] drm/i915: Add helper functions to aid seqno -> request transition John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-24 18:49 ` [PATCH v3 05/28] drm/i915: Convert i915_gem_ring_throttle to use requests John.C.Harrison
                   ` (25 subsequent siblings)
  29 siblings, 0 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The object structure contains the last read, write and fenced seqno values for
use in syncrhonisation operations. These have now been replaced with their
request structure counterparts.

Note that to ensure that objects do not end up with dangling pointers, the
assignments of last_*_req include reference count updates. Thus a request cannot
be freed if an object is still hanging on to it for any reason.

v2: Corrected 'last_rendering_' to 'last_read_' in a number of comments that did
not get updated when 'last_rendering_seqno' became 'last_read|write_seqno'
several millenia ago.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c        |    6 +--
 drivers/gpu/drm/i915/i915_drv.h            |   13 ++---
 drivers/gpu/drm/i915/i915_gem.c            |   71 ++++++++++++++++------------
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |    6 +--
 drivers/gpu/drm/i915/i915_gem_gtt.h        |    4 +-
 drivers/gpu/drm/i915/i915_gem_tiling.c     |    2 +-
 drivers/gpu/drm/i915/i915_gpu_error.c      |    4 +-
 drivers/gpu/drm/i915/intel_display.c       |    6 ++-
 drivers/gpu/drm/i915/intel_ringbuffer.h    |    2 +-
 9 files changed, 64 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index b4f23a8..2720eb5 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -133,9 +133,9 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
 		   obj->base.size / 1024,
 		   obj->base.read_domains,
 		   obj->base.write_domain,
-		   obj->last_read_seqno,
-		   obj->last_write_seqno,
-		   obj->last_fenced_seqno,
+		   i915_gem_request_get_seqno(obj->last_read_req),
+		   i915_gem_request_get_seqno(obj->last_write_req),
+		   i915_gem_request_get_seqno(obj->last_fenced_req),
 		   i915_cache_level_str(to_i915(obj->base.dev), obj->cache_level),
 		   obj->dirty ? " dirty" : "",
 		   obj->madv == I915_MADV_DONTNEED ? " purgeable" : "");
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index bce0346..5c00cf3 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1944,10 +1944,10 @@ struct drm_i915_gem_object {
 	struct intel_engine_cs *ring;
 
 	/** Breadcrumb of last rendering to the buffer. */
-	uint32_t last_read_seqno;
-	uint32_t last_write_seqno;
+	struct drm_i915_gem_request *last_read_req;
+	struct drm_i915_gem_request *last_write_req;
 	/** Breadcrumb of last fenced GPU access to the buffer. */
-	uint32_t last_fenced_seqno;
+	struct drm_i915_gem_request *last_fenced_req;
 
 	/** Current tiling stride for the object, if it's tiled. */
 	uint32_t stride;
@@ -1990,9 +1990,10 @@ void i915_gem_track_fb(struct drm_i915_gem_object *old,
  * The request queue allows us to note sequence numbers that have been emitted
  * and may be associated with active buffers to be retired.
  *
- * By keeping this list, we can avoid having to do questionable
- * sequence-number comparisons on buffer last_rendering_seqnos, and associate
- * an emission time with seqnos for tracking how far ahead of the GPU we are.
+ * By keeping this list, we can avoid having to do questionable sequence
+ * number comparisons on buffer last_read|write_seqno. It also allows an
+ * emission time to be associated with the request for tracking how far ahead
+ * of the GPU the submission is.
  */
 struct drm_i915_gem_request {
 	struct kref ref;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 569c2da..eba112d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1346,11 +1346,11 @@ i915_gem_object_wait_rendering__tail(struct drm_i915_gem_object *obj)
 	/* Manually manage the write flush as we may have not yet
 	 * retired the buffer.
 	 *
-	 * Note that the last_write_seqno is always the earlier of
-	 * the two (read/write) seqno, so if we haved successfully waited,
+	 * Note that the last_write_req is always the earlier of
+	 * the two (read/write) requests, so if we haved successfully waited,
 	 * we know we have passed the last write.
 	 */
-	obj->last_write_seqno = 0;
+	i915_gem_request_assign(&obj->last_write_req, NULL);
 
 	return 0;
 }
@@ -1363,14 +1363,18 @@ static __must_check int
 i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
 			       bool readonly)
 {
+	struct drm_i915_gem_request *req;
 	struct intel_engine_cs *ring = obj->ring;
 	u32 seqno;
 	int ret;
 
-	seqno = readonly ? obj->last_write_seqno : obj->last_read_seqno;
-	if (seqno == 0)
+	req = readonly ? obj->last_write_req : obj->last_read_req;
+	if (!req)
 		return 0;
 
+	seqno = i915_gem_request_get_seqno(req);
+	WARN_ON(seqno == 0);
+
 	ret = i915_wait_seqno(ring, seqno);
 	if (ret)
 		return ret;
@@ -1386,6 +1390,7 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj,
 					    struct drm_i915_file_private *file_priv,
 					    bool readonly)
 {
+	struct drm_i915_gem_request *req;
 	struct drm_device *dev = obj->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_engine_cs *ring = obj->ring;
@@ -1396,10 +1401,13 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj,
 	BUG_ON(!mutex_is_locked(&dev->struct_mutex));
 	BUG_ON(!dev_priv->mm.interruptible);
 
-	seqno = readonly ? obj->last_write_seqno : obj->last_read_seqno;
-	if (seqno == 0)
+	req = readonly ? obj->last_write_req : obj->last_read_req;
+	if (!req)
 		return 0;
 
+	seqno = i915_gem_request_get_seqno(req);
+	WARN_ON(seqno == 0);
+
 	ret = i915_gem_check_wedge(&dev_priv->gpu_error, true);
 	if (ret)
 		return ret;
@@ -2257,12 +2265,12 @@ static void
 i915_gem_object_move_to_active(struct drm_i915_gem_object *obj,
 			       struct intel_engine_cs *ring)
 {
-	u32 seqno = intel_ring_get_seqno(ring);
+	struct drm_i915_gem_request *req = intel_ring_get_request(ring);
 
 	BUG_ON(ring == NULL);
-	if (obj->ring != ring && obj->last_write_seqno) {
-		/* Keep the seqno relative to the current ring */
-		obj->last_write_seqno = seqno;
+	if (obj->ring != ring && obj->last_write_req) {
+		/* Keep the request relative to the current ring */
+		i915_gem_request_assign(&obj->last_write_req, req);
 	}
 	obj->ring = ring;
 
@@ -2274,7 +2282,7 @@ i915_gem_object_move_to_active(struct drm_i915_gem_object *obj,
 
 	list_move_tail(&obj->ring_list, &ring->active_list);
 
-	obj->last_read_seqno = seqno;
+	i915_gem_request_assign(&obj->last_read_req, req);
 }
 
 void i915_vma_move_to_active(struct i915_vma *vma,
@@ -2305,11 +2313,11 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj)
 	list_del_init(&obj->ring_list);
 	obj->ring = NULL;
 
-	obj->last_read_seqno = 0;
-	obj->last_write_seqno = 0;
+	i915_gem_request_assign(&obj->last_read_req, NULL);
+	i915_gem_request_assign(&obj->last_write_req, NULL);
 	obj->base.write_domain = 0;
 
-	obj->last_fenced_seqno = 0;
+	i915_gem_request_assign(&obj->last_fenced_req, NULL);
 
 	obj->active = 0;
 	drm_gem_object_unreference(&obj->base);
@@ -2326,7 +2334,7 @@ i915_gem_object_retire(struct drm_i915_gem_object *obj)
 		return;
 
 	if (i915_seqno_passed(ring->get_seqno(ring, true),
-			      obj->last_read_seqno))
+			      i915_gem_request_get_seqno(obj->last_read_req)))
 		i915_gem_object_move_to_inactive(obj);
 }
 
@@ -2753,7 +2761,8 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
 				      struct drm_i915_gem_object,
 				      ring_list);
 
-		if (!i915_seqno_passed(seqno, obj->last_read_seqno))
+		if (!i915_seqno_passed(seqno,
+			     i915_gem_request_get_seqno(obj->last_read_req)))
 			break;
 
 		i915_gem_object_move_to_inactive(obj);
@@ -2872,7 +2881,8 @@ i915_gem_object_flush_active(struct drm_i915_gem_object *obj)
 	int ret;
 
 	if (obj->active) {
-		ret = i915_gem_check_olr(obj->ring, obj->last_read_seqno);
+		ret = i915_gem_check_olr(obj->ring,
+			     i915_gem_request_get_seqno(obj->last_read_req));
 		if (ret)
 			return ret;
 
@@ -2933,13 +2943,12 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
 	if (ret)
 		goto out;
 
-	if (obj->active) {
-		seqno = obj->last_read_seqno;
-		ring = obj->ring;
-	}
+	if (!obj->active || !obj->last_read_req)
+		goto out;
 
-	if (seqno == 0)
-		 goto out;
+	seqno = i915_gem_request_get_seqno(obj->last_read_req);
+	WARN_ON(seqno == 0);
+	ring = obj->ring;
 
 	/* Do this after OLR check to make sure we make forward progress polling
 	 * on this IOCTL with a timeout <=0 (like busy ioctl)
@@ -2990,7 +2999,7 @@ i915_gem_object_sync(struct drm_i915_gem_object *obj,
 
 	idx = intel_ring_sync_index(from, to);
 
-	seqno = obj->last_read_seqno;
+	seqno = i915_gem_request_get_seqno(obj->last_read_req);
 	/* Optimization: Avoid semaphore sync when we are sure we already
 	 * waited for an object with higher seqno */
 	if (seqno <= from->semaphore.sync_seqno[idx])
@@ -3003,11 +3012,12 @@ i915_gem_object_sync(struct drm_i915_gem_object *obj,
 	trace_i915_gem_ring_sync_to(from, to, seqno);
 	ret = to->semaphore.sync_to(to, from, seqno);
 	if (!ret)
-		/* We use last_read_seqno because sync_to()
+		/* We use last_read_req because sync_to()
 		 * might have just caused seqno wrap under
 		 * the radar.
 		 */
-		from->semaphore.sync_seqno[idx] = obj->last_read_seqno;
+		from->semaphore.sync_seqno[idx] =
+				i915_gem_request_get_seqno(obj->last_read_req);
 
 	return ret;
 }
@@ -3321,12 +3331,13 @@ static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj,
 static int
 i915_gem_object_wait_fence(struct drm_i915_gem_object *obj)
 {
-	if (obj->last_fenced_seqno) {
-		int ret = i915_wait_seqno(obj->ring, obj->last_fenced_seqno);
+	if (obj->last_fenced_req) {
+		int ret = i915_wait_seqno(obj->ring,
+			   i915_gem_request_get_seqno(obj->last_fenced_req));
 		if (ret)
 			return ret;
 
-		obj->last_fenced_seqno = 0;
+		i915_gem_request_assign(&obj->last_fenced_req, NULL);
 	}
 
 	return 0;
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index f06027b..4d9baef 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -946,7 +946,7 @@ void
 i915_gem_execbuffer_move_to_active(struct list_head *vmas,
 				   struct intel_engine_cs *ring)
 {
-	u32 seqno = intel_ring_get_seqno(ring);
+	struct drm_i915_gem_request *req = intel_ring_get_request(ring);
 	struct i915_vma *vma;
 
 	list_for_each_entry(vma, vmas, exec_list) {
@@ -963,7 +963,7 @@ i915_gem_execbuffer_move_to_active(struct list_head *vmas,
 		i915_vma_move_to_active(vma, ring);
 		if (obj->base.write_domain) {
 			obj->dirty = 1;
-			obj->last_write_seqno = seqno;
+			i915_gem_request_assign(&obj->last_write_req, req);
 
 			intel_fb_obj_invalidate(obj, ring);
 
@@ -971,7 +971,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) {
-			obj->last_fenced_seqno = seqno;
+			i915_gem_request_assign(&obj->last_fenced_req, req);
 			if (entry->flags & __EXEC_OBJECT_HAS_FENCE) {
 				struct drm_i915_private *dev_priv = to_i915(ring->dev);
 				list_move_tail(&dev_priv->fence_regs[obj->fence_reg].lru_list,
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index beaf4bc..f524017 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -182,7 +182,7 @@ struct i915_address_space {
 	 * List of objects currently involved in rendering.
 	 *
 	 * Includes buffers having the contents of their GPU caches
-	 * flushed, not necessarily primitives.  last_rendering_seqno
+	 * 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.
@@ -193,7 +193,7 @@ struct i915_address_space {
 	 * LRU list of objects which are not in the ringbuffer and
 	 * are ready to unbind, but are still in the GTT.
 	 *
-	 * last_rendering_seqno is 0 while an object is in this list.
+	 * last_read_req is NULL while an object is in this list.
 	 *
 	 * A reference is not held on the buffer while on this list,
 	 * as merely being GTT-bound shouldn't prevent its being
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index 4727a4e..7a24bd1 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -399,7 +399,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
 			}
 
 			obj->fence_dirty =
-				obj->last_fenced_seqno ||
+				obj->last_fenced_req ||
 				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 cdaee6c..998bd8a 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -670,8 +670,8 @@ static void capture_bo(struct drm_i915_error_buffer *err,
 
 	err->size = obj->base.size;
 	err->name = obj->base.name;
-	err->rseqno = obj->last_read_seqno;
-	err->wseqno = obj->last_write_seqno;
+	err->rseqno = i915_gem_request_get_seqno(obj->last_read_req);
+	err->wseqno = i915_gem_request_get_seqno(obj->last_write_req);
 	err->gtt_offset = vma->node.start;
 	err->read_domains = obj->base.read_domains;
 	err->write_domain = obj->base.write_domain;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3307e9c..faf7e03 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9573,7 +9573,8 @@ static int intel_queue_mmio_flip(struct drm_device *dev,
 {
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
-	intel_crtc->mmio_flip.seqno = obj->last_write_seqno;
+	intel_crtc->mmio_flip.seqno =
+			     i915_gem_request_get_seqno(obj->last_write_req);
 	intel_crtc->mmio_flip.ring = obj->ring;
 
 	schedule_work(&intel_crtc->mmio_flip.work);
@@ -9836,7 +9837,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 		if (ret)
 			goto cleanup_unpin;
 
-		work->flip_queued_seqno = obj->last_write_seqno;
+		work->flip_queued_seqno =
+			     i915_gem_request_get_seqno(obj->last_write_req);
 		work->flip_queued_ring = obj->ring;
 	} else {
 		ret = dev_priv->display.queue_flip(dev, crtc, fb, obj, ring,
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 20636e0..dbac132 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -251,7 +251,7 @@ struct  intel_engine_cs {
 	 * ringbuffer.
 	 *
 	 * Includes buffers having the contents of their GPU caches
-	 * flushed, not necessarily primitives.  last_rendering_seqno
+	 * 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.
-- 
1.7.9.5

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

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

* [PATCH v3 05/28] drm/i915: Convert i915_gem_ring_throttle to use requests
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (3 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 04/28] drm/i915: Replace last_[rwf]_seqno with last_[rwf]_req John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-24 18:49 ` [PATCH v3 06/28] drm/i915: Ensure requests stick around during waits John.C.Harrison
                   ` (24 subsequent siblings)
  29 siblings, 0 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Convert the throttle code to use the request structure rather than extracting a 
ring/seqno pair from it and using those. This is in preparation for
__wait_seqno() becoming __wait_request().

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c |   13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index eba112d..9ac9157 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4102,10 +4102,8 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_i915_file_private *file_priv = file->driver_priv;
 	unsigned long recent_enough = jiffies - msecs_to_jiffies(20);
-	struct drm_i915_gem_request *request;
-	struct intel_engine_cs *ring = NULL;
+	struct drm_i915_gem_request *request, *target = NULL;
 	unsigned reset_counter;
-	u32 seqno = 0;
 	int ret;
 
 	ret = i915_gem_wait_for_error(&dev_priv->gpu_error);
@@ -4121,16 +4119,17 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file)
 		if (time_after_eq(request->emitted_jiffies, recent_enough))
 			break;
 
-		ring = request->ring;
-		seqno = request->seqno;
+		target = request;
 	}
 	reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
 	spin_unlock(&file_priv->mm.lock);
 
-	if (seqno == 0)
+	if (target == NULL)
 		return 0;
 
-	ret = __i915_wait_seqno(ring, seqno, reset_counter, true, NULL, NULL);
+	ret = __i915_wait_seqno(i915_gem_request_get_ring(target),
+				i915_gem_request_get_seqno(target),
+				reset_counter, true, NULL, NULL);
 	if (ret == 0)
 		queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0);
 
-- 
1.7.9.5

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

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

* [PATCH v3 06/28] drm/i915: Ensure requests stick around during waits
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (4 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 05/28] drm/i915: Convert i915_gem_ring_throttle to use requests John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-26 12:27   ` John Harrison
  2014-11-24 18:49 ` [PATCH v3 07/28] drm/i915: Remove 'outstanding_lazy_seqno' John.C.Harrison
                   ` (23 subsequent siblings)
  29 siblings, 1 reply; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Added reference counting of the request structure around __wait_seqno() calls.
This is a precursor to updating the wait code itself to take the request rather
than a seqno. At that point, it would be a Bad Idea for a request object to be
retired and freed while the wait code is still using it.

v3:

Note that even though the mutex lock is held during a call to i915_wait_seqno(),
it is still necessary to explicitly bump the reference count. It appears that
the shrinker can asynchronously retire items even though the mutex is locked.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c |   28 +++++++++++++++++++++++-----
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 9ac9157..71303a1 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1333,8 +1333,11 @@ i915_wait_seqno(struct intel_engine_cs *ring, uint32_t seqno)
 		return ret;
 
 	reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
-	return __i915_wait_seqno(ring, seqno, reset_counter, interruptible,
-				 NULL, NULL);
+	i915_gem_request_reference(req);
+	ret = __i915_wait_seqno(ring, seqno, reset_counter, interruptible,
+				NULL, NULL);
+	i915_gem_request_unreference(req);
+	return ret;
 }
 
 static int
@@ -1417,10 +1420,12 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj,
 		return ret;
 
 	reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
+	i915_gem_request_reference(req);
 	mutex_unlock(&dev->struct_mutex);
 	ret = __i915_wait_seqno(ring, seqno, reset_counter, true, NULL,
 				file_priv);
 	mutex_lock(&dev->struct_mutex);
+	i915_gem_request_unreference(req);
 	if (ret)
 		return ret;
 
@@ -2920,6 +2925,7 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_i915_gem_wait *args = data;
 	struct drm_i915_gem_object *obj;
+	struct drm_i915_gem_request *req;
 	struct intel_engine_cs *ring = NULL;
 	unsigned reset_counter;
 	u32 seqno = 0;
@@ -2946,7 +2952,8 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
 	if (!obj->active || !obj->last_read_req)
 		goto out;
 
-	seqno = i915_gem_request_get_seqno(obj->last_read_req);
+	req = obj->last_read_req;
+	seqno = i915_gem_request_get_seqno(req);
 	WARN_ON(seqno == 0);
 	ring = obj->ring;
 
@@ -2960,10 +2967,15 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
 
 	drm_gem_object_unreference(&obj->base);
 	reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
+	i915_gem_request_reference(req);
 	mutex_unlock(&dev->struct_mutex);
 
-	return __i915_wait_seqno(ring, seqno, reset_counter, true,
-				 &args->timeout_ns, file->driver_priv);
+	ret = __i915_wait_seqno(ring, seqno, reset_counter, true, &args->timeout_ns,
+			   file->driver_priv);
+	mutex_lock(&dev->struct_mutex);
+	i915_gem_request_unreference(req);
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
 
 out:
 	drm_gem_object_unreference(&obj->base);
@@ -4122,6 +4134,8 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file)
 		target = request;
 	}
 	reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
+	if (target)
+		i915_gem_request_reference(target);
 	spin_unlock(&file_priv->mm.lock);
 
 	if (target == NULL)
@@ -4133,6 +4147,10 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file)
 	if (ret == 0)
 		queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0);
 
+	mutex_lock(&dev->struct_mutex);
+	i915_gem_request_unreference(target);
+	mutex_unlock(&dev->struct_mutex);
+
 	return ret;
 }
 
-- 
1.7.9.5

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

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

* [PATCH v3 07/28] drm/i915: Remove 'outstanding_lazy_seqno'
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (5 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 06/28] drm/i915: Ensure requests stick around during waits John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-24 18:49 ` [PATCH v3 08/28] drm/i915: Make 'i915_gem_check_olr' actually check by request not seqno John.C.Harrison
                   ` (22 subsequent siblings)
  29 siblings, 0 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The OLS value is now obsolete. Exactly the same value is guarateed to be always
available as PLR->seqno. Thus it is safe to remove the OLS completely. And also
to rename the PLR to OLR to keep the 'outstanding lazy ...' naming convention
valid.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c            |   13 +++----
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |    4 ++-
 drivers/gpu/drm/i915/intel_display.c       |    3 +-
 drivers/gpu/drm/i915/intel_lrc.c           |   26 +++++---------
 drivers/gpu/drm/i915/intel_ringbuffer.c    |   52 +++++++++++++++-------------
 drivers/gpu/drm/i915/intel_ringbuffer.h    |   13 ++-----
 6 files changed, 49 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 71303a1..9b3e03b 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1164,7 +1164,7 @@ i915_gem_check_olr(struct intel_engine_cs *ring, u32 seqno)
 	BUG_ON(!mutex_is_locked(&ring->dev->struct_mutex));
 
 	ret = 0;
-	if (seqno == ring->outstanding_lazy_seqno)
+	if (seqno == i915_gem_request_get_seqno(ring->outstanding_lazy_request))
 		ret = i915_add_request(ring, NULL);
 
 	return ret;
@@ -2424,7 +2424,7 @@ int __i915_add_request(struct intel_engine_cs *ring,
 	u32 request_ring_position, request_start;
 	int ret;
 
-	request = ring->preallocated_lazy_request;
+	request = ring->outstanding_lazy_request;
 	if (WARN_ON(request == NULL))
 		return -ENOMEM;
 
@@ -2469,7 +2469,6 @@ int __i915_add_request(struct intel_engine_cs *ring,
 			return ret;
 	}
 
-	request->seqno = intel_ring_get_seqno(ring);
 	request->ring = ring;
 	request->head = request_start;
 	request->tail = request_ring_position;
@@ -2506,8 +2505,7 @@ int __i915_add_request(struct intel_engine_cs *ring,
 	}
 
 	trace_i915_gem_request_add(ring, request->seqno);
-	ring->outstanding_lazy_seqno = 0;
-	ring->preallocated_lazy_request = NULL;
+	ring->outstanding_lazy_request = NULL;
 
 	i915_queue_hangcheck(ring->dev);
 
@@ -2692,9 +2690,8 @@ static void i915_gem_reset_ring_cleanup(struct drm_i915_private *dev_priv,
 		i915_gem_free_request(request);
 	}
 
-	/* These may not have been flush before the reset, do so now */
-	i915_gem_request_assign(&ring->preallocated_lazy_request, NULL);
-	ring->outstanding_lazy_seqno = 0;
+	/* This may not have been flushed before the reset, so clean it now */
+	i915_gem_request_assign(&ring->outstanding_lazy_request, NULL);
 }
 
 void i915_gem_restore_fences(struct drm_device *dev)
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 4d9baef..7ecfa91 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1211,7 +1211,9 @@ i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file,
 			return ret;
 	}
 
-	trace_i915_gem_ring_dispatch(ring, intel_ring_get_seqno(ring), flags);
+	trace_i915_gem_ring_dispatch(ring,
+		    i915_gem_request_get_seqno(intel_ring_get_request(ring)),
+		    flags);
 
 	i915_gem_execbuffer_move_to_active(vmas, ring);
 	i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index faf7e03..097e8a1 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9846,7 +9846,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 		if (ret)
 			goto cleanup_unpin;
 
-		work->flip_queued_seqno = intel_ring_get_seqno(ring);
+		work->flip_queued_seqno =
+		    i915_gem_request_get_seqno(intel_ring_get_request(ring));
 		work->flip_queued_ring = ring;
 	}
 
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index fe66482..9aed83c 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -876,22 +876,14 @@ void intel_lr_context_unpin(struct intel_engine_cs *ring,
 	}
 }
 
-static int logical_ring_alloc_seqno(struct intel_engine_cs *ring,
-				    struct intel_context *ctx)
+static int logical_ring_alloc_request(struct intel_engine_cs *ring,
+				      struct intel_context *ctx)
 {
 	struct drm_i915_gem_request *request;
 	int ret;
 
-	/* XXX: The aim is to replace seqno values with request structures.
-	 * A step along the way is to switch to using the PLR in preference
-	 * to the OLS. That requires the PLR to only be valid when the OLS is
-	 * also valid. I.e., the two must be kept in step. */
-
-	if (ring->outstanding_lazy_seqno) {
-		WARN_ON(ring->preallocated_lazy_request == NULL);
+	if (ring->outstanding_lazy_request)
 		return 0;
-	}
-	WARN_ON(ring->preallocated_lazy_request != NULL);
 
 	request = kmalloc(sizeof(*request), GFP_KERNEL);
 	if (request == NULL)
@@ -907,7 +899,7 @@ static int logical_ring_alloc_seqno(struct intel_engine_cs *ring,
 
 	kref_init(&request->ref);
 
-	ret = i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_seqno);
+	ret = i915_gem_get_seqno(ring->dev, &request->seqno);
 	if (ret) {
 		intel_lr_context_unpin(ring, ctx);
 		kfree(request);
@@ -921,7 +913,7 @@ static int logical_ring_alloc_seqno(struct intel_engine_cs *ring,
 	request->ctx = ctx;
 	i915_gem_context_reference(request->ctx);
 
-	ring->preallocated_lazy_request = request;
+	ring->outstanding_lazy_request = request;
 	return 0;
 }
 
@@ -1089,7 +1081,7 @@ int intel_logical_ring_begin(struct intel_ringbuffer *ringbuf, int num_dwords)
 		return ret;
 
 	/* Preallocate the olr before touching the ring */
-	ret = logical_ring_alloc_seqno(ring, ringbuf->FIXME_lrc_ctx);
+	ret = logical_ring_alloc_request(ring, ringbuf->FIXME_lrc_ctx);
 	if (ret)
 		return ret;
 
@@ -1342,7 +1334,8 @@ static int gen8_emit_request(struct intel_ringbuffer *ringbuf)
 				(ring->status_page.gfx_addr +
 				(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT)));
 	intel_logical_ring_emit(ringbuf, 0);
-	intel_logical_ring_emit(ringbuf, ring->outstanding_lazy_seqno);
+	intel_logical_ring_emit(ringbuf,
+		i915_gem_request_get_seqno(ring->outstanding_lazy_request));
 	intel_logical_ring_emit(ringbuf, MI_USER_INTERRUPT);
 	intel_logical_ring_emit(ringbuf, MI_NOOP);
 	intel_logical_ring_advance_and_submit(ringbuf);
@@ -1367,8 +1360,7 @@ void intel_logical_ring_cleanup(struct intel_engine_cs *ring)
 
 	intel_logical_ring_stop(ring);
 	WARN_ON((I915_READ_MODE(ring) & MODE_IDLE) == 0);
-	i915_gem_request_assign(&ring->preallocated_lazy_request, NULL);
-	ring->outstanding_lazy_seqno = 0;
+	i915_gem_request_assign(&ring->outstanding_lazy_request, NULL);
 
 	if (ring->cleanup)
 		ring->cleanup(ring);
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index fbeaa3a..accfc89 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -911,17 +911,20 @@ static int gen8_rcs_signal(struct intel_engine_cs *signaller,
 		return ret;
 
 	for_each_ring(waiter, dev_priv, i) {
+		u32 seqno;
 		u64 gtt_offset = signaller->semaphore.signal_ggtt[i];
 		if (gtt_offset == MI_SEMAPHORE_SYNC_INVALID)
 			continue;
 
+		seqno = i915_gem_request_get_seqno(
+					   signaller->outstanding_lazy_request);
 		intel_ring_emit(signaller, GFX_OP_PIPE_CONTROL(6));
 		intel_ring_emit(signaller, PIPE_CONTROL_GLOBAL_GTT_IVB |
 					   PIPE_CONTROL_QW_WRITE |
 					   PIPE_CONTROL_FLUSH_ENABLE);
 		intel_ring_emit(signaller, lower_32_bits(gtt_offset));
 		intel_ring_emit(signaller, upper_32_bits(gtt_offset));
-		intel_ring_emit(signaller, signaller->outstanding_lazy_seqno);
+		intel_ring_emit(signaller, seqno);
 		intel_ring_emit(signaller, 0);
 		intel_ring_emit(signaller, MI_SEMAPHORE_SIGNAL |
 					   MI_SEMAPHORE_TARGET(waiter->id));
@@ -949,16 +952,19 @@ static int gen8_xcs_signal(struct intel_engine_cs *signaller,
 		return ret;
 
 	for_each_ring(waiter, dev_priv, i) {
+		u32 seqno;
 		u64 gtt_offset = signaller->semaphore.signal_ggtt[i];
 		if (gtt_offset == MI_SEMAPHORE_SYNC_INVALID)
 			continue;
 
+		seqno = i915_gem_request_get_seqno(
+					   signaller->outstanding_lazy_request);
 		intel_ring_emit(signaller, (MI_FLUSH_DW + 1) |
 					   MI_FLUSH_DW_OP_STOREDW);
 		intel_ring_emit(signaller, lower_32_bits(gtt_offset) |
 					   MI_FLUSH_DW_USE_GTT);
 		intel_ring_emit(signaller, upper_32_bits(gtt_offset));
-		intel_ring_emit(signaller, signaller->outstanding_lazy_seqno);
+		intel_ring_emit(signaller, seqno);
 		intel_ring_emit(signaller, MI_SEMAPHORE_SIGNAL |
 					   MI_SEMAPHORE_TARGET(waiter->id));
 		intel_ring_emit(signaller, 0);
@@ -987,9 +993,11 @@ static int gen6_signal(struct intel_engine_cs *signaller,
 	for_each_ring(useless, dev_priv, i) {
 		u32 mbox_reg = signaller->semaphore.mbox.signal[i];
 		if (mbox_reg != GEN6_NOSYNC) {
+			u32 seqno = i915_gem_request_get_seqno(
+					   signaller->outstanding_lazy_request);
 			intel_ring_emit(signaller, MI_LOAD_REGISTER_IMM(1));
 			intel_ring_emit(signaller, mbox_reg);
-			intel_ring_emit(signaller, signaller->outstanding_lazy_seqno);
+			intel_ring_emit(signaller, seqno);
 		}
 	}
 
@@ -1024,7 +1032,8 @@ gen6_add_request(struct intel_engine_cs *ring)
 
 	intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
 	intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
-	intel_ring_emit(ring, ring->outstanding_lazy_seqno);
+	intel_ring_emit(ring,
+		    i915_gem_request_get_seqno(ring->outstanding_lazy_request));
 	intel_ring_emit(ring, MI_USER_INTERRUPT);
 	__intel_ring_advance(ring);
 
@@ -1142,7 +1151,8 @@ pc_render_add_request(struct intel_engine_cs *ring)
 			PIPE_CONTROL_WRITE_FLUSH |
 			PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE);
 	intel_ring_emit(ring, ring->scratch.gtt_offset | PIPE_CONTROL_GLOBAL_GTT);
-	intel_ring_emit(ring, ring->outstanding_lazy_seqno);
+	intel_ring_emit(ring,
+		    i915_gem_request_get_seqno(ring->outstanding_lazy_request));
 	intel_ring_emit(ring, 0);
 	PIPE_CONTROL_FLUSH(ring, scratch_addr);
 	scratch_addr += 2 * CACHELINE_BYTES; /* write to separate cachelines */
@@ -1161,7 +1171,8 @@ pc_render_add_request(struct intel_engine_cs *ring)
 			PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE |
 			PIPE_CONTROL_NOTIFY);
 	intel_ring_emit(ring, ring->scratch.gtt_offset | PIPE_CONTROL_GLOBAL_GTT);
-	intel_ring_emit(ring, ring->outstanding_lazy_seqno);
+	intel_ring_emit(ring,
+		    i915_gem_request_get_seqno(ring->outstanding_lazy_request));
 	intel_ring_emit(ring, 0);
 	__intel_ring_advance(ring);
 
@@ -1401,7 +1412,8 @@ i9xx_add_request(struct intel_engine_cs *ring)
 
 	intel_ring_emit(ring, MI_STORE_DWORD_INDEX);
 	intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
-	intel_ring_emit(ring, ring->outstanding_lazy_seqno);
+	intel_ring_emit(ring,
+		    i915_gem_request_get_seqno(ring->outstanding_lazy_request));
 	intel_ring_emit(ring, MI_USER_INTERRUPT);
 	__intel_ring_advance(ring);
 
@@ -1870,8 +1882,7 @@ void intel_cleanup_ring_buffer(struct intel_engine_cs *ring)
 
 	intel_unpin_ringbuffer_obj(ringbuf);
 	intel_destroy_ringbuffer_obj(ringbuf);
-	i915_gem_request_assign(&ring->preallocated_lazy_request, NULL);
-	ring->outstanding_lazy_seqno = 0;
+	i915_gem_request_assign(&ring->outstanding_lazy_request, NULL);
 
 	if (ring->cleanup)
 		ring->cleanup(ring);
@@ -2004,7 +2015,7 @@ int intel_ring_idle(struct intel_engine_cs *ring)
 	int ret;
 
 	/* We need to add any requests required to flush the objects and ring */
-	if (ring->outstanding_lazy_seqno) {
+	if (ring->outstanding_lazy_request) {
 		ret = i915_add_request(ring, NULL);
 		if (ret)
 			return ret;
@@ -2022,22 +2033,13 @@ int intel_ring_idle(struct intel_engine_cs *ring)
 }
 
 static int
-intel_ring_alloc_seqno(struct intel_engine_cs *ring)
+intel_ring_alloc_request(struct intel_engine_cs *ring)
 {
 	int ret;
 	struct drm_i915_gem_request *request;
 
-	/* XXX: The aim is to replace seqno values with request structures.
-	 * A step along the way is to switch to using the PLR in preference
-	 * to the OLS. That requires the PLR to only be valid when the OLS
-	 * is also valid. I.e., the two must be kept in step. */
-
-	if (ring->outstanding_lazy_seqno) {
-		WARN_ON(ring->preallocated_lazy_request == NULL);
+	if (ring->outstanding_lazy_request)
 		return 0;
-	}
-
-	WARN_ON(ring->preallocated_lazy_request != NULL);
 
 	request = kmalloc(sizeof(*request), GFP_KERNEL);
 	if (request == NULL)
@@ -2045,13 +2047,13 @@ intel_ring_alloc_seqno(struct intel_engine_cs *ring)
 
 	kref_init(&request->ref);
 
-	ret = i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_seqno);
+	ret = i915_gem_get_seqno(ring->dev, &request->seqno);
 	if (ret) {
 		kfree(request);
 		return ret;
 	}
 
-	ring->preallocated_lazy_request = request;
+	ring->outstanding_lazy_request = request;
 	return 0;
 }
 
@@ -2092,7 +2094,7 @@ int intel_ring_begin(struct intel_engine_cs *ring,
 		return ret;
 
 	/* Preallocate the olr before touching the ring */
-	ret = intel_ring_alloc_seqno(ring);
+	ret = intel_ring_alloc_request(ring);
 	if (ret)
 		return ret;
 
@@ -2127,7 +2129,7 @@ void intel_ring_init_seqno(struct intel_engine_cs *ring, u32 seqno)
 	struct drm_device *dev = ring->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
-	BUG_ON(ring->outstanding_lazy_seqno);
+	BUG_ON(ring->outstanding_lazy_request);
 
 	if (INTEL_INFO(dev)->gen == 6 || INTEL_INFO(dev)->gen == 7) {
 		I915_WRITE(RING_SYNC_0(ring->mmio_base), 0);
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index dbac132..2a84bd9 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -267,8 +267,7 @@ struct  intel_engine_cs {
 	/**
 	 * Do we have some not yet emitted requests outstanding?
 	 */
-	struct drm_i915_gem_request *preallocated_lazy_request;
-	u32 outstanding_lazy_seqno;
+	struct drm_i915_gem_request *outstanding_lazy_request;
 	bool gpu_caches_dirty;
 	bool fbc_dirty;
 
@@ -436,17 +435,11 @@ static inline u32 intel_ring_get_tail(struct intel_ringbuffer *ringbuf)
 	return ringbuf->tail;
 }
 
-static inline u32 intel_ring_get_seqno(struct intel_engine_cs *ring)
-{
-	BUG_ON(ring->outstanding_lazy_seqno == 0);
-	return ring->outstanding_lazy_seqno;
-}
-
 static inline struct drm_i915_gem_request *
 intel_ring_get_request(struct intel_engine_cs *ring)
 {
-	BUG_ON(ring->preallocated_lazy_request == NULL);
-	return ring->preallocated_lazy_request;
+	BUG_ON(ring->outstanding_lazy_request == NULL);
+	return ring->outstanding_lazy_request;
 }
 
 static inline void i915_trace_irq_get(struct intel_engine_cs *ring, u32 seqno)
-- 
1.7.9.5

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

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

* [PATCH v3 08/28] drm/i915: Make 'i915_gem_check_olr' actually check by request not seqno
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (6 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 07/28] drm/i915: Remove 'outstanding_lazy_seqno' John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-24 18:49 ` [PATCH v3 09/28] drm/i915: Convert 'last_flip_req' to be a request not a seqno John.C.Harrison
                   ` (21 subsequent siblings)
  29 siblings, 0 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Updated the _check_olr() function to actually take a request object and compare
it to the OLR rather than extracting seqnos and comparing those.

Note that there is one use case where the request object being processed is no
longer available at that point in the call stack. Hence a temporary copy of the
original function is still present (but called _check_ols() instead). This will
be removed in a subsequent patch.

Also, downgraded a BUG_ON to a WARN_ON as apparently the former is frowned upon
for shipping code.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h |   18 +++++++++++++++++-
 drivers/gpu/drm/i915/i915_gem.c |   28 +++++++++++-----------------
 2 files changed, 28 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 5c00cf3..62ffdb5 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2585,7 +2585,7 @@ bool i915_gem_retire_requests(struct drm_device *dev);
 void i915_gem_retire_requests_ring(struct intel_engine_cs *ring);
 int __must_check i915_gem_check_wedge(struct i915_gpu_error *error,
 				      bool interruptible);
-int __must_check i915_gem_check_olr(struct intel_engine_cs *ring, u32 seqno);
+int __must_check i915_gem_check_olr(struct drm_i915_gem_request *req);
 
 static inline bool i915_reset_in_progress(struct i915_gpu_error *error)
 {
@@ -3125,4 +3125,20 @@ wait_remaining_ms_from_jiffies(unsigned long timestamp_jiffies, int to_wait_ms)
 	}
 }
 
+/* XXX: Temporary solution to be removed later in patch series. */
+static inline int __must_check i915_gem_check_ols(
+				     struct intel_engine_cs *ring, u32 seqno)
+{
+	int ret;
+
+	WARN_ON(!mutex_is_locked(&ring->dev->struct_mutex));
+
+	ret = 0;
+	if (seqno == i915_gem_request_get_seqno(ring->outstanding_lazy_request))
+		ret = i915_add_request(ring, NULL);
+
+	return ret;
+}
+/* XXX: Temporary solution to be removed later in patch series. */
+
 #endif
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 9b3e03b..b07de69 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1153,19 +1153,18 @@ i915_gem_check_wedge(struct i915_gpu_error *error,
 }
 
 /*
- * Compare seqno against outstanding lazy request. Emit a request if they are
- * equal.
+ * Compare arbitrary request against outstanding lazy request. Emit on match.
  */
 int
-i915_gem_check_olr(struct intel_engine_cs *ring, u32 seqno)
+i915_gem_check_olr(struct drm_i915_gem_request *req)
 {
 	int ret;
 
-	BUG_ON(!mutex_is_locked(&ring->dev->struct_mutex));
+	WARN_ON(!mutex_is_locked(&req->ring->dev->struct_mutex));
 
 	ret = 0;
-	if (seqno == i915_gem_request_get_seqno(ring->outstanding_lazy_request))
-		ret = i915_add_request(ring, NULL);
+	if (req == req->ring->outstanding_lazy_request)
+		ret = i915_add_request(req->ring, NULL);
 
 	return ret;
 }
@@ -1328,7 +1327,7 @@ i915_wait_seqno(struct intel_engine_cs *ring, uint32_t seqno)
 	if (ret)
 		return ret;
 
-	ret = i915_gem_check_olr(ring, seqno);
+	ret = i915_gem_check_ols(ring, seqno);
 	if (ret)
 		return ret;
 
@@ -1398,7 +1397,6 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj,
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_engine_cs *ring = obj->ring;
 	unsigned reset_counter;
-	u32 seqno;
 	int ret;
 
 	BUG_ON(!mutex_is_locked(&dev->struct_mutex));
@@ -1408,22 +1406,19 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj,
 	if (!req)
 		return 0;
 
-	seqno = i915_gem_request_get_seqno(req);
-	WARN_ON(seqno == 0);
-
 	ret = i915_gem_check_wedge(&dev_priv->gpu_error, true);
 	if (ret)
 		return ret;
 
-	ret = i915_gem_check_olr(ring, seqno);
+	ret = i915_gem_check_olr(req);
 	if (ret)
 		return ret;
 
 	reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
 	i915_gem_request_reference(req);
 	mutex_unlock(&dev->struct_mutex);
-	ret = __i915_wait_seqno(ring, seqno, reset_counter, true, NULL,
-				file_priv);
+	ret = __i915_wait_seqno(ring, i915_gem_request_get_seqno(req),
+				reset_counter, true, NULL, file_priv);
 	mutex_lock(&dev->struct_mutex);
 	i915_gem_request_unreference(req);
 	if (ret)
@@ -2883,8 +2878,7 @@ i915_gem_object_flush_active(struct drm_i915_gem_object *obj)
 	int ret;
 
 	if (obj->active) {
-		ret = i915_gem_check_olr(obj->ring,
-			     i915_gem_request_get_seqno(obj->last_read_req));
+		ret = i915_gem_check_olr(obj->last_read_req);
 		if (ret)
 			return ret;
 
@@ -3014,7 +3008,7 @@ i915_gem_object_sync(struct drm_i915_gem_object *obj,
 	if (seqno <= from->semaphore.sync_seqno[idx])
 		return 0;
 
-	ret = i915_gem_check_olr(obj->ring, seqno);
+	ret = i915_gem_check_olr(obj->last_read_req);
 	if (ret)
 		return ret;
 
-- 
1.7.9.5

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

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

* [PATCH v3 09/28] drm/i915: Convert 'last_flip_req' to be a request not a seqno
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (7 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 08/28] drm/i915: Make 'i915_gem_check_olr' actually check by request not seqno John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-24 18:49 ` [PATCH v3 10/28] drm/i915: Convert i915_wait_seqno to i915_wait_request John.C.Harrison
                   ` (20 subsequent siblings)
  29 siblings, 0 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Converted 'last_flip_req' to be an actual request rather than a seqno value as
part of the on going seqno to request changes. This includes reference counting
the request being saved away to ensure it can not be retired and freed while the
overlay code is still waiting on it.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/intel_overlay.c |   23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index dc2f4f2..5defc37 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -182,7 +182,7 @@ struct intel_overlay {
 	u32 flip_addr;
 	struct drm_i915_gem_object *reg_bo;
 	/* flip handling */
-	uint32_t last_flip_req;
+	struct drm_i915_gem_request *last_flip_req;
 	void (*flip_tail)(struct intel_overlay *);
 };
 
@@ -217,17 +217,20 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
 	int ret;
 
 	BUG_ON(overlay->last_flip_req);
-	ret = i915_add_request(ring, &overlay->last_flip_req);
+	i915_gem_request_assign(&overlay->last_flip_req,
+					     ring->outstanding_lazy_request);
+	ret = i915_add_request(ring, NULL);
 	if (ret)
 		return ret;
 
 	overlay->flip_tail = tail;
-	ret = i915_wait_seqno(ring, overlay->last_flip_req);
+	ret = i915_wait_seqno(ring,
+			 i915_gem_request_get_seqno(overlay->last_flip_req));
 	if (ret)
 		return ret;
 	i915_gem_retire_requests(dev);
 
-	overlay->last_flip_req = 0;
+	i915_gem_request_assign(&overlay->last_flip_req, NULL);
 	return 0;
 }
 
@@ -286,7 +289,10 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
 	intel_ring_emit(ring, flip_addr);
 	intel_ring_advance(ring);
 
-	return i915_add_request(ring, &overlay->last_flip_req);
+	WARN_ON(overlay->last_flip_req);
+	i915_gem_request_assign(&overlay->last_flip_req,
+					     ring->outstanding_lazy_request);
+	return i915_add_request(ring, NULL);
 }
 
 static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
@@ -366,10 +372,11 @@ static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
 	struct intel_engine_cs *ring = &dev_priv->ring[RCS];
 	int ret;
 
-	if (overlay->last_flip_req == 0)
+	if (overlay->last_flip_req == NULL)
 		return 0;
 
-	ret = i915_wait_seqno(ring, overlay->last_flip_req);
+	ret = i915_wait_seqno(ring,
+			 i915_gem_request_get_seqno(overlay->last_flip_req));
 	if (ret)
 		return ret;
 	i915_gem_retire_requests(dev);
@@ -377,7 +384,7 @@ static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
 	if (overlay->flip_tail)
 		overlay->flip_tail(overlay);
 
-	overlay->last_flip_req = 0;
+	i915_gem_request_assign(&overlay->last_flip_req, NULL);
 	return 0;
 }
 
-- 
1.7.9.5

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

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

* [PATCH v3 10/28] drm/i915: Convert i915_wait_seqno to i915_wait_request
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (8 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 09/28] drm/i915: Convert 'last_flip_req' to be a request not a seqno John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-24 18:49 ` [PATCH v3 11/28] drm/i915: Add IRQ friendly request deference facility John.C.Harrison
                   ` (19 subsequent siblings)
  29 siblings, 0 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Updated i915_wait_seqno() to take a request structure instead of a seqno value
and renamed it accordingly. Internally, it just pulls the seqno out of the
request and calls on to __wait_seqno() as before. However, all the code further
up the stack is now simplified as it can just pass the request object straight
through without having to peek inside.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h         |   19 +-----------------
 drivers/gpu/drm/i915/i915_gem.c         |   33 +++++++++++++++----------------
 drivers/gpu/drm/i915/intel_lrc.c        |    6 ++----
 drivers/gpu/drm/i915/intel_overlay.c    |   11 +++--------
 drivers/gpu/drm/i915/intel_ringbuffer.c |   14 ++++++-------
 5 files changed, 28 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 62ffdb5..149532e6 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2637,8 +2637,7 @@ int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno,
 			bool interruptible,
 			s64 *timeout,
 			struct drm_i915_file_private *file_priv);
-int __must_check i915_wait_seqno(struct intel_engine_cs *ring,
-				 uint32_t seqno);
+int __must_check i915_wait_request(struct drm_i915_gem_request *req);
 int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
 int __must_check
 i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj,
@@ -3125,20 +3124,4 @@ wait_remaining_ms_from_jiffies(unsigned long timestamp_jiffies, int to_wait_ms)
 	}
 }
 
-/* XXX: Temporary solution to be removed later in patch series. */
-static inline int __must_check i915_gem_check_ols(
-				     struct intel_engine_cs *ring, u32 seqno)
-{
-	int ret;
-
-	WARN_ON(!mutex_is_locked(&ring->dev->struct_mutex));
-
-	ret = 0;
-	if (seqno == i915_gem_request_get_seqno(ring->outstanding_lazy_request))
-		ret = i915_add_request(ring, NULL);
-
-	return ret;
-}
-/* XXX: Temporary solution to be removed later in patch series. */
-
 #endif
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index b07de69..8e2c530 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1308,33 +1308,38 @@ int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno,
 }
 
 /**
- * Waits for a sequence number to be signaled, and cleans up the
+ * Waits for a request to be signaled, and cleans up the
  * request and object lists appropriately for that event.
  */
 int
-i915_wait_seqno(struct intel_engine_cs *ring, uint32_t seqno)
+i915_wait_request(struct drm_i915_gem_request *req)
 {
-	struct drm_device *dev = ring->dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	bool interruptible = dev_priv->mm.interruptible;
+	struct drm_device *dev;
+	struct drm_i915_private *dev_priv;
+	bool interruptible;
 	unsigned reset_counter;
 	int ret;
 
+	BUG_ON(req == NULL);
+
+	dev = req->ring->dev;
+	dev_priv = dev->dev_private;
+	interruptible = dev_priv->mm.interruptible;
+
 	BUG_ON(!mutex_is_locked(&dev->struct_mutex));
-	BUG_ON(seqno == 0);
 
 	ret = i915_gem_check_wedge(&dev_priv->gpu_error, interruptible);
 	if (ret)
 		return ret;
 
-	ret = i915_gem_check_ols(ring, seqno);
+	ret = i915_gem_check_olr(req);
 	if (ret)
 		return ret;
 
 	reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
 	i915_gem_request_reference(req);
-	ret = __i915_wait_seqno(ring, seqno, reset_counter, interruptible,
-				NULL, NULL);
+	ret = __i915_wait_seqno(req->ring, i915_gem_request_get_seqno(req),
+				reset_counter, interruptible, NULL, NULL);
 	i915_gem_request_unreference(req);
 	return ret;
 }
@@ -1366,18 +1371,13 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
 			       bool readonly)
 {
 	struct drm_i915_gem_request *req;
-	struct intel_engine_cs *ring = obj->ring;
-	u32 seqno;
 	int ret;
 
 	req = readonly ? obj->last_write_req : obj->last_read_req;
 	if (!req)
 		return 0;
 
-	seqno = i915_gem_request_get_seqno(req);
-	WARN_ON(seqno == 0);
-
-	ret = i915_wait_seqno(ring, seqno);
+	ret = i915_wait_request(req);
 	if (ret)
 		return ret;
 
@@ -3335,8 +3335,7 @@ static int
 i915_gem_object_wait_fence(struct drm_i915_gem_object *obj)
 {
 	if (obj->last_fenced_req) {
-		int ret = i915_wait_seqno(obj->ring,
-			   i915_gem_request_get_seqno(obj->last_fenced_req));
+		int ret = i915_wait_request(obj->last_fenced_req);
 		if (ret)
 			return ret;
 
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 9aed83c..6177179 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -922,7 +922,6 @@ static int logical_ring_wait_request(struct intel_ringbuffer *ringbuf,
 {
 	struct intel_engine_cs *ring = ringbuf->ring;
 	struct drm_i915_gem_request *request;
-	u32 seqno = 0;
 	int ret;
 
 	if (ringbuf->last_retired_head != -1) {
@@ -937,15 +936,14 @@ static int logical_ring_wait_request(struct intel_ringbuffer *ringbuf,
 	list_for_each_entry(request, &ring->request_list, list) {
 		if (__intel_ring_space(request->tail, ringbuf->tail,
 				       ringbuf->size) >= bytes) {
-			seqno = request->seqno;
 			break;
 		}
 	}
 
-	if (seqno == 0)
+	if (&request->list == &ring->request_list)
 		return -ENOSPC;
 
-	ret = i915_wait_seqno(ring, seqno);
+	ret = i915_wait_request(request);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index 5defc37..6c530e2 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -224,8 +224,7 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
 		return ret;
 
 	overlay->flip_tail = tail;
-	ret = i915_wait_seqno(ring,
-			 i915_gem_request_get_seqno(overlay->last_flip_req));
+	ret = i915_wait_request(overlay->last_flip_req);
 	if (ret)
 		return ret;
 	i915_gem_retire_requests(dev);
@@ -367,19 +366,15 @@ static int intel_overlay_off(struct intel_overlay *overlay)
  * We have to be careful not to repeat work forever an make forward progess. */
 static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
 {
-	struct drm_device *dev = overlay->dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_engine_cs *ring = &dev_priv->ring[RCS];
 	int ret;
 
 	if (overlay->last_flip_req == NULL)
 		return 0;
 
-	ret = i915_wait_seqno(ring,
-			 i915_gem_request_get_seqno(overlay->last_flip_req));
+	ret = i915_wait_request(overlay->last_flip_req);
 	if (ret)
 		return ret;
-	i915_gem_retire_requests(dev);
+	i915_gem_retire_requests(overlay->dev);
 
 	if (overlay->flip_tail)
 		overlay->flip_tail(overlay);
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index accfc89..b9d0d29 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1899,7 +1899,6 @@ static int intel_ring_wait_request(struct intel_engine_cs *ring, int n)
 {
 	struct intel_ringbuffer *ringbuf = ring->buffer;
 	struct drm_i915_gem_request *request;
-	u32 seqno = 0;
 	int ret;
 
 	if (ringbuf->last_retired_head != -1) {
@@ -1914,15 +1913,14 @@ static int intel_ring_wait_request(struct intel_engine_cs *ring, int n)
 	list_for_each_entry(request, &ring->request_list, list) {
 		if (__intel_ring_space(request->tail, ringbuf->tail,
 				       ringbuf->size) >= n) {
-			seqno = request->seqno;
 			break;
 		}
 	}
 
-	if (seqno == 0)
+	if (&request->list == &ring->request_list)
 		return -ENOSPC;
 
-	ret = i915_wait_seqno(ring, seqno);
+	ret = i915_wait_request(request);
 	if (ret)
 		return ret;
 
@@ -2011,7 +2009,7 @@ static int intel_wrap_ring_buffer(struct intel_engine_cs *ring)
 
 int intel_ring_idle(struct intel_engine_cs *ring)
 {
-	u32 seqno;
+	struct drm_i915_gem_request *req;
 	int ret;
 
 	/* We need to add any requests required to flush the objects and ring */
@@ -2025,11 +2023,11 @@ int intel_ring_idle(struct intel_engine_cs *ring)
 	if (list_empty(&ring->request_list))
 		return 0;
 
-	seqno = list_entry(ring->request_list.prev,
+	req = list_entry(ring->request_list.prev,
 			   struct drm_i915_gem_request,
-			   list)->seqno;
+			   list);
 
-	return i915_wait_seqno(ring, seqno);
+	return i915_wait_request(req);
 }
 
 static int
-- 
1.7.9.5

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

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

* [PATCH v3 11/28] drm/i915: Add IRQ friendly request deference facility
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (9 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 10/28] drm/i915: Convert i915_wait_seqno to i915_wait_request John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-26  9:19   ` Daniel Vetter
  2014-11-24 18:49 ` [PATCH v3 12/28] drm/i915: Convert mmio_flip::seqno to struct request John.C.Harrison
                   ` (18 subsequent siblings)
  29 siblings, 1 reply; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The next patches in the series convert some display related seqno usage to
request structure usage. However, the request dereference introduced must be
done from interrupt context. As the dereference potentially involves freeing the
request structure and thus calling lots of non-interrupt friendly code, this
poses a problem.

The solution is to add an IRQ friendly version of the dereference function. All
this does is to add the request structure to a 'delayed free' list and return.
The retire code, which is run periodically, then processes this list and does
the actual dereferencing of the request structures.

v2: Added a count to allow for multiple IRQ dereferences of the same request at
a time.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h         |    7 +++++++
 drivers/gpu/drm/i915/i915_gem.c         |   33 +++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_lrc.c        |    2 ++
 drivers/gpu/drm/i915/intel_ringbuffer.c |    2 ++
 drivers/gpu/drm/i915/intel_ringbuffer.h |    2 ++
 5 files changed, 46 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 149532e6..e9b01e1 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2025,6 +2025,10 @@ struct drm_i915_gem_request {
 	struct drm_i915_file_private *file_priv;
 	/** file_priv list entry for this request */
 	struct list_head client_list;
+
+	/** deferred free list for dereferencing from IRQ context */
+	struct list_head delay_free_list;
+	uint32_t delay_free_count;
 };
 
 void i915_gem_request_free(struct kref *req_ref);
@@ -2050,9 +2054,12 @@ i915_gem_request_reference(struct drm_i915_gem_request *req)
 static inline void
 i915_gem_request_unreference(struct drm_i915_gem_request *req)
 {
+	WARN_ON(!mutex_is_locked(&req->ring->dev->struct_mutex));
 	kref_put(&req->ref, i915_gem_request_free);
 }
 
+void i915_gem_request_unreference_irq(struct drm_i915_gem_request *req);
+
 static inline void i915_gem_request_assign(struct drm_i915_gem_request **pdst,
 					   struct drm_i915_gem_request *src)
 {
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 8e2c530..b62b9d9 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2732,6 +2732,19 @@ void i915_gem_reset(struct drm_device *dev)
 	i915_gem_restore_fences(dev);
 }
 
+void i915_gem_request_unreference_irq(struct drm_i915_gem_request *req)
+{
+	struct intel_engine_cs *ring = req->ring;
+	unsigned long flags;
+
+	/* Need to add the req to a deferred dereference list to be processed
+	 * outside of interrupt time */
+	spin_lock_irqsave(&ring->reqlist_lock, flags);
+	if (req->delay_free_count++ == 0)
+		list_add_tail(&req->delay_free_list, &ring->delayed_free_list);
+	spin_unlock_irqrestore(&ring->reqlist_lock, flags);
+}
+
 /**
  * This function clears the request list as sequence numbers are passed.
  */
@@ -2806,6 +2819,25 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
 		ring->trace_irq_seqno = 0;
 	}
 
+	while (!list_empty(&ring->delayed_free_list)) {
+		struct drm_i915_gem_request *request;
+		unsigned long flags;
+		uint32_t count;
+
+		request = list_first_entry(&ring->delayed_free_list,
+					   struct drm_i915_gem_request,
+					   delay_free_list);
+
+		spin_lock_irqsave(&request->ring->reqlist_lock, flags);
+		list_del(&request->delay_free_list);
+		count = request->delay_free_count;
+		request->delay_free_count = 0;
+		spin_unlock_irqrestore(&request->ring->reqlist_lock, flags);
+
+		while (count-- > 0)
+			i915_gem_request_unreference(request);
+	}
+
 	WARN_ON(i915_verify_lists(ring->dev));
 }
 
@@ -5007,6 +5039,7 @@ init_ring_lists(struct intel_engine_cs *ring)
 {
 	INIT_LIST_HEAD(&ring->active_list);
 	INIT_LIST_HEAD(&ring->request_list);
+	INIT_LIST_HEAD(&ring->delayed_free_list);
 }
 
 void i915_init_vm(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 6177179..09f4588 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -1381,7 +1381,9 @@ static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *rin
 	ring->dev = dev;
 	INIT_LIST_HEAD(&ring->active_list);
 	INIT_LIST_HEAD(&ring->request_list);
+	spin_lock_init(&ring->reqlist_lock);
 	init_waitqueue_head(&ring->irq_queue);
+	INIT_LIST_HEAD(&ring->delayed_free_list);
 
 	INIT_LIST_HEAD(&ring->execlist_queue);
 	INIT_LIST_HEAD(&ring->execlist_retired_req_list);
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index b9d0d29..e3082af 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1807,6 +1807,8 @@ static int intel_init_ring_buffer(struct drm_device *dev,
 	ring->dev = dev;
 	INIT_LIST_HEAD(&ring->active_list);
 	INIT_LIST_HEAD(&ring->request_list);
+	spin_lock_init(&ring->reqlist_lock);
+	INIT_LIST_HEAD(&ring->delayed_free_list);
 	INIT_LIST_HEAD(&ring->execlist_queue);
 	ringbuf->size = 32 * PAGE_SIZE;
 	ringbuf->ring = ring;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 2a84bd9..cd1a9f9 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -263,6 +263,8 @@ struct  intel_engine_cs {
 	 * outstanding.
 	 */
 	struct list_head request_list;
+	spinlock_t reqlist_lock;
+	struct list_head delayed_free_list;
 
 	/**
 	 * Do we have some not yet emitted requests outstanding?
-- 
1.7.9.5

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

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

* [PATCH v3 12/28] drm/i915: Convert mmio_flip::seqno to struct request
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (10 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 11/28] drm/i915: Add IRQ friendly request deference facility John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-26  9:23   ` Daniel Vetter
  2014-11-24 18:49 ` [PATCH v3 13/28] drm/i915: Convert __wait_seqno() to __wait_request() John.C.Harrison
                   ` (17 subsequent siblings)
  29 siblings, 1 reply; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Converted the mmio_flip 'seqno' value to be a request structure as part of the
on going seqno to request changes. This includes reference counting the request
being saved away to ensure it can not be retired and freed while the flip code
is still waiting on it.

v2: Used the IRQ friendly request dereference call in the notify handler as that
code is called asynchronously without holding any useful mutex locks.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |   20 ++++++++++----------
 drivers/gpu/drm/i915/intel_drv.h     |    3 +--
 2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 097e8a1..cbf3cb7 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9550,18 +9550,19 @@ static void intel_mmio_flip_work_func(struct work_struct *work)
 {
 	struct intel_crtc *intel_crtc =
 		container_of(work, struct intel_crtc, mmio_flip.work);
-	struct intel_engine_cs *ring;
-	uint32_t seqno;
-
-	seqno = intel_crtc->mmio_flip.seqno;
-	ring = intel_crtc->mmio_flip.ring;
+	struct intel_mmio_flip *mmio_flip;
 
-	if (seqno)
-		WARN_ON(__i915_wait_seqno(ring, seqno,
+	mmio_flip = &intel_crtc->mmio_flip;
+	if (mmio_flip->req)
+		WARN_ON(__i915_wait_seqno(i915_gem_request_get_ring(mmio_flip->req),
+					  i915_gem_request_get_seqno(mmio_flip->req),
 					  intel_crtc->reset_counter,
 					  false, NULL, NULL) != 0);
 
 	intel_do_mmio_flip(intel_crtc);
+	if (mmio_flip->req)
+		i915_gem_request_unreference_irq(mmio_flip->req);
+	mmio_flip->req = NULL;
 }
 
 static int intel_queue_mmio_flip(struct drm_device *dev,
@@ -9573,9 +9574,8 @@ static int intel_queue_mmio_flip(struct drm_device *dev,
 {
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
-	intel_crtc->mmio_flip.seqno =
-			     i915_gem_request_get_seqno(obj->last_write_req);
-	intel_crtc->mmio_flip.ring = obj->ring;
+	i915_gem_request_assign(&intel_crtc->mmio_flip.req,
+				obj->last_write_req);
 
 	schedule_work(&intel_crtc->mmio_flip.work);
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 44b153c5..2755532 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -406,8 +406,7 @@ struct intel_pipe_wm {
 };
 
 struct intel_mmio_flip {
-	u32 seqno;
-	struct intel_engine_cs *ring;
+	struct drm_i915_gem_request *req;
 	struct work_struct work;
 };
 
-- 
1.7.9.5

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

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

* [PATCH v3 13/28] drm/i915: Convert __wait_seqno() to __wait_request()
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (11 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 12/28] drm/i915: Convert mmio_flip::seqno to struct request John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-24 18:49 ` [PATCH v3 14/28] drm/i915: Remove obsolete seqno parameter from 'i915_add_request' John.C.Harrison
                   ` (16 subsequent siblings)
  29 siblings, 0 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Now that all code above is using request structures instead of seqno values, it
is possible to convert  __wait_seqno() itself. Internally, it is still calling
i915_seqno_passed(), this will be updated later in the series. This step is just
changing the parameter list and function name.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |    2 +-
 drivers/gpu/drm/i915/i915_gem.c      |   45 +++++++++++++++-------------------
 drivers/gpu/drm/i915/intel_display.c |    7 +++---
 3 files changed, 24 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e9b01e1..12b3f9b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2639,7 +2639,7 @@ int __i915_add_request(struct intel_engine_cs *ring,
 		       u32 *seqno);
 #define i915_add_request(ring, seqno) \
 	__i915_add_request(ring, NULL, NULL, seqno)
-int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno,
+int __i915_wait_request(struct drm_i915_gem_request *req,
 			unsigned reset_counter,
 			bool interruptible,
 			s64 *timeout,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index b62b9d9..18698ab 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1189,10 +1189,9 @@ static bool can_wait_boost(struct drm_i915_file_private *file_priv)
 }
 
 /**
- * __i915_wait_seqno - wait until execution of seqno has finished
- * @ring: the ring expected to report seqno
- * @seqno: duh!
- * @reset_counter: reset sequence associated with the given seqno
+ * __i915_wait_request - wait until execution of request has finished
+ * @req: duh!
+ * @reset_counter: reset sequence associated with the given request
  * @interruptible: do an interruptible wait (normally yes)
  * @timeout: in - how long to wait (NULL forever); out - how much time remaining
  *
@@ -1203,15 +1202,16 @@ static bool can_wait_boost(struct drm_i915_file_private *file_priv)
  * reset_counter _must_ be read before, and an appropriate smp_rmb must be
  * inserted.
  *
- * Returns 0 if the seqno was found within the alloted time. Else returns the
+ * Returns 0 if the request was found within the alloted time. Else returns the
  * errno with remaining time filled in timeout argument.
  */
-int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno,
+int __i915_wait_request(struct drm_i915_gem_request *req,
 			unsigned reset_counter,
 			bool interruptible,
 			s64 *timeout,
 			struct drm_i915_file_private *file_priv)
 {
+	struct intel_engine_cs *ring = i915_gem_request_get_ring(req);
 	struct drm_device *dev = ring->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	const bool irq_test_in_progress =
@@ -1223,7 +1223,8 @@ int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno,
 
 	WARN(!intel_irqs_enabled(dev_priv), "IRQs disabled");
 
-	if (i915_seqno_passed(ring->get_seqno(ring, true), seqno))
+	if (i915_seqno_passed(ring->get_seqno(ring, true),
+			      i915_gem_request_get_seqno(req)))
 		return 0;
 
 	timeout_expire = timeout ? jiffies + nsecs_to_jiffies((u64)*timeout) : 0;
@@ -1240,7 +1241,8 @@ int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno,
 		return -ENODEV;
 
 	/* Record current time in case interrupted by signal, or wedged */
-	trace_i915_gem_request_wait_begin(ring, seqno);
+	trace_i915_gem_request_wait_begin(i915_gem_request_get_ring(req),
+					  i915_gem_request_get_seqno(req));
 	before = ktime_get_raw_ns();
 	for (;;) {
 		struct timer_list timer;
@@ -1259,7 +1261,8 @@ int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno,
 			break;
 		}
 
-		if (i915_seqno_passed(ring->get_seqno(ring, false), seqno)) {
+		if (i915_seqno_passed(ring->get_seqno(ring, false),
+				      i915_gem_request_get_seqno(req))) {
 			ret = 0;
 			break;
 		}
@@ -1291,7 +1294,8 @@ int __i915_wait_seqno(struct intel_engine_cs *ring, u32 seqno,
 		}
 	}
 	now = ktime_get_raw_ns();
-	trace_i915_gem_request_wait_end(ring, seqno);
+	trace_i915_gem_request_wait_end(i915_gem_request_get_ring(req),
+					i915_gem_request_get_seqno(req));
 
 	if (!irq_test_in_progress)
 		ring->irq_put(ring);
@@ -1338,8 +1342,8 @@ i915_wait_request(struct drm_i915_gem_request *req)
 
 	reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
 	i915_gem_request_reference(req);
-	ret = __i915_wait_seqno(req->ring, i915_gem_request_get_seqno(req),
-				reset_counter, interruptible, NULL, NULL);
+	ret = __i915_wait_request(req, reset_counter,
+				  interruptible, NULL, NULL);
 	i915_gem_request_unreference(req);
 	return ret;
 }
@@ -1395,7 +1399,6 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj,
 	struct drm_i915_gem_request *req;
 	struct drm_device *dev = obj->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_engine_cs *ring = obj->ring;
 	unsigned reset_counter;
 	int ret;
 
@@ -1417,8 +1420,7 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj,
 	reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
 	i915_gem_request_reference(req);
 	mutex_unlock(&dev->struct_mutex);
-	ret = __i915_wait_seqno(ring, i915_gem_request_get_seqno(req),
-				reset_counter, true, NULL, file_priv);
+	ret = __i915_wait_request(req, reset_counter, true, NULL, file_priv);
 	mutex_lock(&dev->struct_mutex);
 	i915_gem_request_unreference(req);
 	if (ret)
@@ -2949,9 +2951,7 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
 	struct drm_i915_gem_wait *args = data;
 	struct drm_i915_gem_object *obj;
 	struct drm_i915_gem_request *req;
-	struct intel_engine_cs *ring = NULL;
 	unsigned reset_counter;
-	u32 seqno = 0;
 	int ret = 0;
 
 	if (args->flags != 0)
@@ -2976,9 +2976,6 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
 		goto out;
 
 	req = obj->last_read_req;
-	seqno = i915_gem_request_get_seqno(req);
-	WARN_ON(seqno == 0);
-	ring = obj->ring;
 
 	/* Do this after OLR check to make sure we make forward progress polling
 	 * on this IOCTL with a timeout <=0 (like busy ioctl)
@@ -2993,8 +2990,8 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
 	i915_gem_request_reference(req);
 	mutex_unlock(&dev->struct_mutex);
 
-	ret = __i915_wait_seqno(ring, seqno, reset_counter, true, &args->timeout_ns,
-			   file->driver_priv);
+	ret = __i915_wait_request(req, reset_counter, true, &args->timeout_ns,
+				  file->driver_priv);
 	mutex_lock(&dev->struct_mutex);
 	i915_gem_request_unreference(req);
 	mutex_unlock(&dev->struct_mutex);
@@ -4163,9 +4160,7 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file)
 	if (target == NULL)
 		return 0;
 
-	ret = __i915_wait_seqno(i915_gem_request_get_ring(target),
-				i915_gem_request_get_seqno(target),
-				reset_counter, true, NULL, NULL);
+	ret = __i915_wait_request(target, reset_counter, true, NULL, NULL);
 	if (ret == 0)
 		queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0);
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index cbf3cb7..98a5ed0 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9554,10 +9554,9 @@ static void intel_mmio_flip_work_func(struct work_struct *work)
 
 	mmio_flip = &intel_crtc->mmio_flip;
 	if (mmio_flip->req)
-		WARN_ON(__i915_wait_seqno(i915_gem_request_get_ring(mmio_flip->req),
-					  i915_gem_request_get_seqno(mmio_flip->req),
-					  intel_crtc->reset_counter,
-					  false, NULL, NULL) != 0);
+		WARN_ON(__i915_wait_request(mmio_flip->req,
+					    intel_crtc->reset_counter,
+					    false, NULL, NULL) != 0);
 
 	intel_do_mmio_flip(intel_crtc);
 	if (mmio_flip->req)
-- 
1.7.9.5

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

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

* [PATCH v3 14/28] drm/i915: Remove obsolete seqno parameter from 'i915_add_request'
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (12 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 13/28] drm/i915: Convert __wait_seqno() to __wait_request() John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-24 18:49 ` [PATCH v3 15/28] drm/i915: Convert 'flip_queued_seqno' into 'flip_queued_request' John.C.Harrison
                   ` (15 subsequent siblings)
  29 siblings, 0 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

There is no longer any need to retrieve a seqno value from an i915_add_request()
call. The calling code already knows which request structure is being processed
(it can only be ring->OLR). And as the request itself is now used in preference
to the basic seqno value, the latter is now redundant in this situation.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h              |    7 +++----
 drivers/gpu/drm/i915/i915_gem.c              |    7 ++-----
 drivers/gpu/drm/i915/i915_gem_execbuffer.c   |    2 +-
 drivers/gpu/drm/i915/i915_gem_render_state.c |    2 +-
 drivers/gpu/drm/i915/intel_lrc.c             |    2 +-
 drivers/gpu/drm/i915/intel_overlay.c         |    4 ++--
 drivers/gpu/drm/i915/intel_ringbuffer.c      |    2 +-
 7 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 12b3f9b..8bfdac6 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2635,10 +2635,9 @@ int __must_check i915_gpu_idle(struct drm_device *dev);
 int __must_check i915_gem_suspend(struct drm_device *dev);
 int __i915_add_request(struct intel_engine_cs *ring,
 		       struct drm_file *file,
-		       struct drm_i915_gem_object *batch_obj,
-		       u32 *seqno);
-#define i915_add_request(ring, seqno) \
-	__i915_add_request(ring, NULL, NULL, seqno)
+		       struct drm_i915_gem_object *batch_obj);
+#define i915_add_request(ring) \
+	__i915_add_request(ring, NULL, NULL)
 int __i915_wait_request(struct drm_i915_gem_request *req,
 			unsigned reset_counter,
 			bool interruptible,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 18698ab..a45335e 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1164,7 +1164,7 @@ i915_gem_check_olr(struct drm_i915_gem_request *req)
 
 	ret = 0;
 	if (req == req->ring->outstanding_lazy_request)
-		ret = i915_add_request(req->ring, NULL);
+		ret = i915_add_request(req->ring);
 
 	return ret;
 }
@@ -2412,8 +2412,7 @@ i915_gem_get_seqno(struct drm_device *dev, u32 *seqno)
 
 int __i915_add_request(struct intel_engine_cs *ring,
 		       struct drm_file *file,
-		       struct drm_i915_gem_object *obj,
-		       u32 *out_seqno)
+		       struct drm_i915_gem_object *obj)
 {
 	struct drm_i915_private *dev_priv = ring->dev->dev_private;
 	struct drm_i915_gem_request *request;
@@ -2512,8 +2511,6 @@ int __i915_add_request(struct intel_engine_cs *ring,
 			   round_jiffies_up_relative(HZ));
 	intel_mark_busy(dev_priv->dev);
 
-	if (out_seqno)
-		*out_seqno = request->seqno;
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 7ecfa91..faada75 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -993,7 +993,7 @@ i915_gem_execbuffer_retire_commands(struct drm_device *dev,
 	ring->gpu_caches_dirty = true;
 
 	/* Add a breadcrumb for the completion of the batch buffer */
-	(void)__i915_add_request(ring, file, obj, NULL);
+	(void)__i915_add_request(ring, file, obj);
 }
 
 static int
diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c
index 98dcd94..521548a 100644
--- a/drivers/gpu/drm/i915/i915_gem_render_state.c
+++ b/drivers/gpu/drm/i915/i915_gem_render_state.c
@@ -173,7 +173,7 @@ int i915_gem_render_state_init(struct intel_engine_cs *ring)
 
 	i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), ring);
 
-	ret = __i915_add_request(ring, NULL, so.obj, NULL);
+	ret = __i915_add_request(ring, NULL, so.obj);
 	/* __i915_add_request moves object to inactive if it fails */
 out:
 	i915_gem_render_state_fini(&so);
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 09f4588..4cd02e8 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -1621,7 +1621,7 @@ int intel_lr_context_render_state_init(struct intel_engine_cs *ring,
 
 	i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), ring);
 
-	ret = __i915_add_request(ring, file, so.obj, NULL);
+	ret = __i915_add_request(ring, file, so.obj);
 	/* intel_logical_ring_add_request moves object to inactive if it
 	 * fails */
 out:
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index 6c530e2..c1abf49 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -219,7 +219,7 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
 	BUG_ON(overlay->last_flip_req);
 	i915_gem_request_assign(&overlay->last_flip_req,
 					     ring->outstanding_lazy_request);
-	ret = i915_add_request(ring, NULL);
+	ret = i915_add_request(ring);
 	if (ret)
 		return ret;
 
@@ -291,7 +291,7 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
 	WARN_ON(overlay->last_flip_req);
 	i915_gem_request_assign(&overlay->last_flip_req,
 					     ring->outstanding_lazy_request);
-	return i915_add_request(ring, NULL);
+	return i915_add_request(ring);
 }
 
 static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index e3082af..04b6d94 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -2016,7 +2016,7 @@ int intel_ring_idle(struct intel_engine_cs *ring)
 
 	/* We need to add any requests required to flush the objects and ring */
 	if (ring->outstanding_lazy_request) {
-		ret = i915_add_request(ring, NULL);
+		ret = i915_add_request(ring);
 		if (ret)
 			return ret;
 	}
-- 
1.7.9.5

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

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

* [PATCH v3 15/28] drm/i915: Convert 'flip_queued_seqno' into 'flip_queued_request'
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (13 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 14/28] drm/i915: Remove obsolete seqno parameter from 'i915_add_request' John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-26 13:07   ` Daniel Vetter
  2014-11-24 18:49 ` [PATCH v3 16/28] drm/i915: Convert trace functions from seqno to request John.C.Harrison
                   ` (14 subsequent siblings)
  29 siblings, 1 reply; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Converted the flip_queued_seqno value to be a request structure as part of the
on going seqno to request changes. This includes reference counting the request
being saved away to ensure it can not be retired and freed while the flip code
is still waiting on it.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c  |    4 ++--
 drivers/gpu/drm/i915/intel_display.c |   24 ++++++++++++++++--------
 drivers/gpu/drm/i915/intel_drv.h     |    2 +-
 3 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 2720eb5..bc9b1c8 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -546,11 +546,11 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data)
 			if (work->flip_queued_ring) {
 				seq_printf(m, "Flip queued on %s at seqno %u, next seqno %u [current breadcrumb %u], completed? %d\n",
 					   work->flip_queued_ring->name,
-					   work->flip_queued_seqno,
+					   i915_gem_request_get_seqno(work->flip_queued_req),
 					   dev_priv->next_seqno,
 					   work->flip_queued_ring->get_seqno(work->flip_queued_ring, true),
 					   i915_seqno_passed(work->flip_queued_ring->get_seqno(work->flip_queued_ring, true),
-							     work->flip_queued_seqno));
+							     i915_gem_request_get_seqno(work->flip_queued_req)));
 			} else
 				seq_printf(m, "Flip not associated with any ring\n");
 			seq_printf(m, "Flip queued on frame %d, (was ready on frame %d), now %d\n",
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 98a5ed0..4a801e4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9669,10 +9669,18 @@ static bool __intel_pageflip_stall_check(struct drm_device *dev,
 		return false;
 
 	if (work->flip_ready_vblank == 0) {
-		if (work->flip_queued_ring &&
-		    !i915_seqno_passed(work->flip_queued_ring->get_seqno(work->flip_queued_ring, true),
-				       work->flip_queued_seqno))
-			return false;
+		if (work->flip_queued_ring) {
+			uint32_t s1 = work->flip_queued_ring->get_seqno(
+					       work->flip_queued_ring, true);
+			uint32_t s2 = i915_gem_request_get_seqno(
+						      work->flip_queued_req);
+			if (!i915_seqno_passed(s1, s2))
+				return false;
+
+			i915_gem_request_unreference_irq(work->flip_queued_req);
+			work->flip_queued_req  = NULL;
+			work->flip_queued_ring = NULL;
+		}
 
 		work->flip_ready_vblank = drm_vblank_count(dev, intel_crtc->pipe);
 	}
@@ -9836,8 +9844,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 		if (ret)
 			goto cleanup_unpin;
 
-		work->flip_queued_seqno =
-			     i915_gem_request_get_seqno(obj->last_write_req);
+		i915_gem_request_assign(&work->flip_queued_req,
+					obj->last_write_req);
 		work->flip_queued_ring = obj->ring;
 	} else {
 		ret = dev_priv->display.queue_flip(dev, crtc, fb, obj, ring,
@@ -9845,8 +9853,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 		if (ret)
 			goto cleanup_unpin;
 
-		work->flip_queued_seqno =
-		    i915_gem_request_get_seqno(intel_ring_get_request(ring));
+		i915_gem_request_assign(&work->flip_queued_req,
+					intel_ring_get_request(ring));
 		work->flip_queued_ring = ring;
 	}
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 2755532..c4a86bb 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -708,7 +708,7 @@ struct intel_unpin_work {
 	u32 flip_count;
 	u32 gtt_offset;
 	struct intel_engine_cs *flip_queued_ring;
-	u32 flip_queued_seqno;
+	struct drm_i915_gem_request *flip_queued_req;
 	int flip_queued_vblank;
 	int flip_ready_vblank;
 	bool enable_stall_check;
-- 
1.7.9.5

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

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

* [PATCH v3 16/28] drm/i915: Convert trace functions from seqno to request
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (14 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 15/28] drm/i915: Convert 'flip_queued_seqno' into 'flip_queued_request' John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-24 18:49 ` [PATCH v3 17/28] drm/i915: Convert 'trace_irq' to use requests rather than seqnos John.C.Harrison
                   ` (13 subsequent siblings)
  29 siblings, 0 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

All the code above is now using requests not seqnos so it is possible to convert
the trace functions across. Note that rather than get into problematic reference
counting issues, the trace code only saves the seqno and ring values from the
request structure not the structure pointer itself.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c            |   12 +++----
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |    4 +--
 drivers/gpu/drm/i915/i915_trace.h          |   47 ++++++++++++++++------------
 3 files changed, 33 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index a45335e..69c3e50 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1241,8 +1241,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
 		return -ENODEV;
 
 	/* Record current time in case interrupted by signal, or wedged */
-	trace_i915_gem_request_wait_begin(i915_gem_request_get_ring(req),
-					  i915_gem_request_get_seqno(req));
+	trace_i915_gem_request_wait_begin(req);
 	before = ktime_get_raw_ns();
 	for (;;) {
 		struct timer_list timer;
@@ -1294,8 +1293,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
 		}
 	}
 	now = ktime_get_raw_ns();
-	trace_i915_gem_request_wait_end(i915_gem_request_get_ring(req),
-					i915_gem_request_get_seqno(req));
+	trace_i915_gem_request_wait_end(req);
 
 	if (!irq_test_in_progress)
 		ring->irq_put(ring);
@@ -2500,7 +2498,7 @@ int __i915_add_request(struct intel_engine_cs *ring,
 		spin_unlock(&file_priv->mm.lock);
 	}
 
-	trace_i915_gem_request_add(ring, request->seqno);
+	trace_i915_gem_request_add(request);
 	ring->outstanding_lazy_request = NULL;
 
 	i915_queue_hangcheck(ring->dev);
@@ -2789,7 +2787,7 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
 		if (!i915_seqno_passed(seqno, request->seqno))
 			break;
 
-		trace_i915_gem_request_retire(ring, request->seqno);
+		trace_i915_gem_request_retire(request);
 
 		/* This is one of the few common intersection points
 		 * between legacy ringbuffer submission and execlists:
@@ -3038,7 +3036,7 @@ i915_gem_object_sync(struct drm_i915_gem_object *obj,
 	if (ret)
 		return ret;
 
-	trace_i915_gem_ring_sync_to(from, to, seqno);
+	trace_i915_gem_ring_sync_to(from, to, obj->last_read_req);
 	ret = to->semaphore.sync_to(to, from, seqno);
 	if (!ret)
 		/* We use last_read_req because sync_to()
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index faada75..0c25f62 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1211,9 +1211,7 @@ i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file,
 			return ret;
 	}
 
-	trace_i915_gem_ring_dispatch(ring,
-		    i915_gem_request_get_seqno(intel_ring_get_request(ring)),
-		    flags);
+	trace_i915_gem_ring_dispatch(intel_ring_get_request(ring), flags);
 
 	i915_gem_execbuffer_move_to_active(vmas, ring);
 	i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj);
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h
index 751d4ad..2c0327b 100644
--- a/drivers/gpu/drm/i915/i915_trace.h
+++ b/drivers/gpu/drm/i915/i915_trace.h
@@ -328,8 +328,8 @@ TRACE_EVENT(i915_gem_evict_vm,
 TRACE_EVENT(i915_gem_ring_sync_to,
 	    TP_PROTO(struct intel_engine_cs *from,
 		     struct intel_engine_cs *to,
-		     u32 seqno),
-	    TP_ARGS(from, to, seqno),
+		     struct drm_i915_gem_request *req),
+	    TP_ARGS(from, to, req),
 
 	    TP_STRUCT__entry(
 			     __field(u32, dev)
@@ -342,7 +342,7 @@ TRACE_EVENT(i915_gem_ring_sync_to,
 			   __entry->dev = from->dev->primary->index;
 			   __entry->sync_from = from->id;
 			   __entry->sync_to = to->id;
-			   __entry->seqno = seqno;
+			   __entry->seqno = i915_gem_request_get_seqno(req);
 			   ),
 
 	    TP_printk("dev=%u, sync-from=%u, sync-to=%u, seqno=%u",
@@ -352,8 +352,8 @@ TRACE_EVENT(i915_gem_ring_sync_to,
 );
 
 TRACE_EVENT(i915_gem_ring_dispatch,
-	    TP_PROTO(struct intel_engine_cs *ring, u32 seqno, u32 flags),
-	    TP_ARGS(ring, seqno, flags),
+	    TP_PROTO(struct drm_i915_gem_request *req, u32 flags),
+	    TP_ARGS(req, flags),
 
 	    TP_STRUCT__entry(
 			     __field(u32, dev)
@@ -363,11 +363,13 @@ TRACE_EVENT(i915_gem_ring_dispatch,
 			     ),
 
 	    TP_fast_assign(
+			   struct intel_engine_cs *ring =
+						i915_gem_request_get_ring(req);
 			   __entry->dev = ring->dev->primary->index;
 			   __entry->ring = ring->id;
-			   __entry->seqno = seqno;
+			   __entry->seqno = i915_gem_request_get_seqno(req);
 			   __entry->flags = flags;
-			   i915_trace_irq_get(ring, seqno);
+			   i915_trace_irq_get(ring, __entry->seqno);
 			   ),
 
 	    TP_printk("dev=%u, ring=%u, seqno=%u, flags=%x",
@@ -398,8 +400,8 @@ TRACE_EVENT(i915_gem_ring_flush,
 );
 
 DECLARE_EVENT_CLASS(i915_gem_request,
-	    TP_PROTO(struct intel_engine_cs *ring, u32 seqno),
-	    TP_ARGS(ring, seqno),
+	    TP_PROTO(struct drm_i915_gem_request *req),
+	    TP_ARGS(req),
 
 	    TP_STRUCT__entry(
 			     __field(u32, dev)
@@ -408,9 +410,11 @@ DECLARE_EVENT_CLASS(i915_gem_request,
 			     ),
 
 	    TP_fast_assign(
+			   struct intel_engine_cs *ring =
+						i915_gem_request_get_ring(req);
 			   __entry->dev = ring->dev->primary->index;
 			   __entry->ring = ring->id;
-			   __entry->seqno = seqno;
+			   __entry->seqno = i915_gem_request_get_seqno(req);
 			   ),
 
 	    TP_printk("dev=%u, ring=%u, seqno=%u",
@@ -418,8 +422,8 @@ DECLARE_EVENT_CLASS(i915_gem_request,
 );
 
 DEFINE_EVENT(i915_gem_request, i915_gem_request_add,
-	    TP_PROTO(struct intel_engine_cs *ring, u32 seqno),
-	    TP_ARGS(ring, seqno)
+	    TP_PROTO(struct drm_i915_gem_request *req),
+	    TP_ARGS(req)
 );
 
 TRACE_EVENT(i915_gem_request_complete,
@@ -443,13 +447,13 @@ TRACE_EVENT(i915_gem_request_complete,
 );
 
 DEFINE_EVENT(i915_gem_request, i915_gem_request_retire,
-	    TP_PROTO(struct intel_engine_cs *ring, u32 seqno),
-	    TP_ARGS(ring, seqno)
+	    TP_PROTO(struct drm_i915_gem_request *req),
+	    TP_ARGS(req)
 );
 
 TRACE_EVENT(i915_gem_request_wait_begin,
-	    TP_PROTO(struct intel_engine_cs *ring, u32 seqno),
-	    TP_ARGS(ring, seqno),
+	    TP_PROTO(struct drm_i915_gem_request *req),
+	    TP_ARGS(req),
 
 	    TP_STRUCT__entry(
 			     __field(u32, dev)
@@ -465,10 +469,13 @@ TRACE_EVENT(i915_gem_request_wait_begin,
 	     * less desirable.
 	     */
 	    TP_fast_assign(
+			   struct intel_engine_cs *ring =
+						i915_gem_request_get_ring(req);
 			   __entry->dev = ring->dev->primary->index;
 			   __entry->ring = ring->id;
-			   __entry->seqno = seqno;
-			   __entry->blocking = mutex_is_locked(&ring->dev->struct_mutex);
+			   __entry->seqno = i915_gem_request_get_seqno(req);
+			   __entry->blocking =
+				     mutex_is_locked(&ring->dev->struct_mutex);
 			   ),
 
 	    TP_printk("dev=%u, ring=%u, seqno=%u, blocking=%s",
@@ -477,8 +484,8 @@ TRACE_EVENT(i915_gem_request_wait_begin,
 );
 
 DEFINE_EVENT(i915_gem_request, i915_gem_request_wait_end,
-	    TP_PROTO(struct intel_engine_cs *ring, u32 seqno),
-	    TP_ARGS(ring, seqno)
+	    TP_PROTO(struct drm_i915_gem_request *req),
+	    TP_ARGS(req)
 );
 
 DECLARE_EVENT_CLASS(i915_ring,
-- 
1.7.9.5

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

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

* [PATCH v3 17/28] drm/i915: Convert 'trace_irq' to use requests rather than seqnos
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (15 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 16/28] drm/i915: Convert trace functions from seqno to request John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-26 13:24   ` Daniel Vetter
  2014-11-24 18:49 ` [PATCH v3 18/28] drm/i915: Convert 'ring_idle()' to use requests not seqnos John.C.Harrison
                   ` (12 subsequent siblings)
  29 siblings, 1 reply; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Updated the trace_irq code to use requests instead of seqnos. This includes
reference counting the request object to ensure it sticks around when required.
Note that getting access to the reference counting functions means moving the
inline i915_trace_irq_get() function from intel_ringbuffer.h to i915_drv.h.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h         |    7 +++++++
 drivers/gpu/drm/i915/i915_gem.c         |    7 ++++---
 drivers/gpu/drm/i915/i915_trace.h       |    2 +-
 drivers/gpu/drm/i915/intel_ringbuffer.h |    8 +-------
 4 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8bfdac6..831fae2 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3130,4 +3130,11 @@ wait_remaining_ms_from_jiffies(unsigned long timestamp_jiffies, int to_wait_ms)
 	}
 }
 
+static inline void i915_trace_irq_get(struct intel_engine_cs *ring,
+				      struct drm_i915_gem_request *req)
+{
+	if (ring->trace_irq_req == NULL && ring->irq_get(ring))
+		i915_gem_request_assign(&ring->trace_irq_req, req);
+}
+
 #endif
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 69c3e50..69bddcb 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2810,10 +2810,11 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
 		i915_gem_free_request(request);
 	}
 
-	if (unlikely(ring->trace_irq_seqno &&
-		     i915_seqno_passed(seqno, ring->trace_irq_seqno))) {
+	if (unlikely(ring->trace_irq_req &&
+		     i915_seqno_passed(seqno,
+			 i915_gem_request_get_seqno(ring->trace_irq_req)))) {
 		ring->irq_put(ring);
-		ring->trace_irq_seqno = 0;
+		i915_gem_request_assign(&ring->trace_irq_req, NULL);
 	}
 
 	while (!list_empty(&ring->delayed_free_list)) {
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h
index 2c0327b..2ade958 100644
--- a/drivers/gpu/drm/i915/i915_trace.h
+++ b/drivers/gpu/drm/i915/i915_trace.h
@@ -369,7 +369,7 @@ TRACE_EVENT(i915_gem_ring_dispatch,
 			   __entry->ring = ring->id;
 			   __entry->seqno = i915_gem_request_get_seqno(req);
 			   __entry->flags = flags;
-			   i915_trace_irq_get(ring, __entry->seqno);
+			   i915_trace_irq_get(ring, req);
 			   ),
 
 	    TP_printk("dev=%u, ring=%u, seqno=%u, flags=%x",
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index cd1a9f9..c8b84de 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -142,7 +142,7 @@ struct  intel_engine_cs {
 
 	unsigned irq_refcount; /* protected by dev_priv->irq_lock */
 	u32		irq_enable_mask;	/* bitmask to enable ring interrupt */
-	u32		trace_irq_seqno;
+	struct drm_i915_gem_request *trace_irq_req;
 	bool __must_check (*irq_get)(struct intel_engine_cs *ring);
 	void		(*irq_put)(struct intel_engine_cs *ring);
 
@@ -444,10 +444,4 @@ intel_ring_get_request(struct intel_engine_cs *ring)
 	return ring->outstanding_lazy_request;
 }
 
-static inline void i915_trace_irq_get(struct intel_engine_cs *ring, u32 seqno)
-{
-	if (ring->trace_irq_seqno == 0 && ring->irq_get(ring))
-		ring->trace_irq_seqno = seqno;
-}
-
 #endif /* _INTEL_RINGBUFFER_H_ */
-- 
1.7.9.5

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

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

* [PATCH v3 18/28] drm/i915: Convert 'ring_idle()' to use requests not seqnos
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (16 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 17/28] drm/i915: Convert 'trace_irq' to use requests rather than seqnos John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-24 18:49 ` [PATCH v3 19/28] drm/i915: Connect requests to rings at creation not submission John.C.Harrison
                   ` (11 subsequent siblings)
  29 siblings, 0 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

More seqno value to request structure conversions. Note, this change temporarily
moves the 'get_seqno()' call inside ring_idle() but this will disappear again in
a later patch when i915_seqno_passed() itself is converted.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c |   13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 5908580d..2042d62 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2738,18 +2738,19 @@ static void gen8_disable_vblank(struct drm_device *dev, int pipe)
 	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
 }
 
-static u32
-ring_last_seqno(struct intel_engine_cs *ring)
+static struct drm_i915_gem_request *
+ring_last_request(struct intel_engine_cs *ring)
 {
 	return list_entry(ring->request_list.prev,
-			  struct drm_i915_gem_request, list)->seqno;
+			  struct drm_i915_gem_request, list);
 }
 
 static bool
-ring_idle(struct intel_engine_cs *ring, u32 seqno)
+ring_idle(struct intel_engine_cs *ring)
 {
 	return (list_empty(&ring->request_list) ||
-		i915_seqno_passed(seqno, ring_last_seqno(ring)));
+		i915_seqno_passed(ring->get_seqno(ring, false),
+			i915_gem_request_get_seqno(ring_last_request(ring))));
 }
 
 static bool
@@ -2969,7 +2970,7 @@ static void i915_hangcheck_elapsed(unsigned long data)
 		acthd = intel_ring_get_active_head(ring);
 
 		if (ring->hangcheck.seqno == seqno) {
-			if (ring_idle(ring, seqno)) {
+			if (ring_idle(ring)) {
 				ring->hangcheck.action = HANGCHECK_IDLE;
 
 				if (waitqueue_active(&ring->irq_queue)) {
-- 
1.7.9.5

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

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

* [PATCH v3 19/28] drm/i915: Connect requests to rings at creation not submission
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (17 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 18/28] drm/i915: Convert 'ring_idle()' to use requests not seqnos John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-24 18:49 ` [PATCH v3 20/28] drm/i915: Convert 'i915_seqno_passed' calls into 'i915_gem_request_completed' John.C.Harrison
                   ` (10 subsequent siblings)
  29 siblings, 0 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

It makes a lot more sense (and makes future seqno -> request conversion patches
simpler) to fill in the 'ring' field of the request structure at the point of
creation rather than submission. Given that the request structure is assigned by
ring specific code and thus is locked to a ring from the start, there really is
no reason to defer this assignment.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c         |    1 -
 drivers/gpu/drm/i915/intel_lrc.c        |    1 +
 drivers/gpu/drm/i915/intel_ringbuffer.c |    1 +
 3 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 69bddcb..dd879dd 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2463,7 +2463,6 @@ int __i915_add_request(struct intel_engine_cs *ring,
 			return ret;
 	}
 
-	request->ring = ring;
 	request->head = request_start;
 	request->tail = request_ring_position;
 
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 4cd02e8..0acb448 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -898,6 +898,7 @@ static int logical_ring_alloc_request(struct intel_engine_cs *ring,
 	}
 
 	kref_init(&request->ref);
+	request->ring = ring;
 
 	ret = i915_gem_get_seqno(ring->dev, &request->seqno);
 	if (ret) {
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 04b6d94..5a1e6fe 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -2046,6 +2046,7 @@ intel_ring_alloc_request(struct intel_engine_cs *ring)
 		return -ENOMEM;
 
 	kref_init(&request->ref);
+	request->ring = ring;
 
 	ret = i915_gem_get_seqno(ring->dev, &request->seqno);
 	if (ret) {
-- 
1.7.9.5

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

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

* [PATCH v3 20/28] drm/i915: Convert 'i915_seqno_passed' calls into 'i915_gem_request_completed'
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (18 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 19/28] drm/i915: Connect requests to rings at creation not submission John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-26 13:42   ` Daniel Vetter
  2014-11-24 18:49 ` [PATCH v3 21/28] drm/i915: Remove the now redundant 'obj->ring' John.C.Harrison
                   ` (9 subsequent siblings)
  29 siblings, 1 reply; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Almost everywhere that caled i915_seqno_passed() was really asking 'has the
given seqno popped out of the hardware yet?'. Thus it had to query the current
hardware seqno and then do a signed delta comparison (which copes with wrapping
around zero but not with seqno values more than 2GB apart, although the latter
is unlikely!).

Now that the majority of seqno instances have been replaced with request
structures, it is possible to convert this test to be request based as well.
There is now a 'i915_gem_request_completed()' function which takes a request and
returns true or false as appropriate. Note that this currently just wraps up the
original _passed() test but a later patch in the series will reduce this to
simply returning a cached internal value, i.e.:
  _completed(req) { return req->completed; }'

This checkin converts almost all _seqno_passed() calls. The only one left is in
the semaphore code which still requires seqnos not request structures.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c  |    3 +--
 drivers/gpu/drm/i915/i915_drv.h      |   18 ++++++++++++++++++
 drivers/gpu/drm/i915/i915_gem.c      |   26 +++++++-------------------
 drivers/gpu/drm/i915/i915_irq.c      |    3 +--
 drivers/gpu/drm/i915/intel_display.c |    6 +-----
 5 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index bc9b1c8..3dc893c 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -549,8 +549,7 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data)
 					   i915_gem_request_get_seqno(work->flip_queued_req),
 					   dev_priv->next_seqno,
 					   work->flip_queued_ring->get_seqno(work->flip_queued_ring, true),
-					   i915_seqno_passed(work->flip_queued_ring->get_seqno(work->flip_queued_ring, true),
-							     i915_gem_request_get_seqno(work->flip_queued_req)));
+					   i915_gem_request_completed(work->flip_queued_req, true));
 			} else
 				seq_printf(m, "Flip not associated with any ring\n");
 			seq_printf(m, "Flip queued on frame %d, (was ready on frame %d), now %d\n",
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 831fae2..1325506 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2072,6 +2072,12 @@ static inline void i915_gem_request_assign(struct drm_i915_gem_request **pdst,
 	*pdst = src;
 }
 
+/*
+ * XXX: i915_gem_request_completed should be here but currently needs the
+ * definition of i915_seqno_passed() which is below. It will be moved in
+ * a later patch when the call to i915_seqno_passed() is obsoleted...
+ */
+
 struct drm_i915_file_private {
 	struct drm_i915_private *dev_priv;
 	struct drm_file *file;
@@ -3130,6 +3136,18 @@ wait_remaining_ms_from_jiffies(unsigned long timestamp_jiffies, int to_wait_ms)
 	}
 }
 
+static inline bool i915_gem_request_completed(struct drm_i915_gem_request *req,
+					      bool lazy_coherency)
+{
+	u32 seqno;
+
+	BUG_ON(req == NULL);
+
+	seqno = req->ring->get_seqno(req->ring, lazy_coherency);
+
+	return i915_seqno_passed(seqno, req->seqno);
+}
+
 static inline void i915_trace_irq_get(struct intel_engine_cs *ring,
 				      struct drm_i915_gem_request *req)
 {
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index dd879dd..cccca47 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1223,8 +1223,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
 
 	WARN(!intel_irqs_enabled(dev_priv), "IRQs disabled");
 
-	if (i915_seqno_passed(ring->get_seqno(ring, true),
-			      i915_gem_request_get_seqno(req)))
+	if (i915_gem_request_completed(req, true))
 		return 0;
 
 	timeout_expire = timeout ? jiffies + nsecs_to_jiffies((u64)*timeout) : 0;
@@ -1260,8 +1259,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
 			break;
 		}
 
-		if (i915_seqno_passed(ring->get_seqno(ring, false),
-				      i915_gem_request_get_seqno(req))) {
+		if (i915_gem_request_completed(req, false)) {
 			ret = 0;
 			break;
 		}
@@ -2333,8 +2331,7 @@ i915_gem_object_retire(struct drm_i915_gem_object *obj)
 	if (ring == NULL)
 		return;
 
-	if (i915_seqno_passed(ring->get_seqno(ring, true),
-			      i915_gem_request_get_seqno(obj->last_read_req)))
+	if (i915_gem_request_completed(obj->last_read_req, true))
 		i915_gem_object_move_to_inactive(obj);
 }
 
@@ -2601,12 +2598,9 @@ struct drm_i915_gem_request *
 i915_gem_find_active_request(struct intel_engine_cs *ring)
 {
 	struct drm_i915_gem_request *request;
-	u32 completed_seqno;
-
-	completed_seqno = ring->get_seqno(ring, false);
 
 	list_for_each_entry(request, &ring->request_list, list) {
-		if (i915_seqno_passed(completed_seqno, request->seqno))
+		if (i915_gem_request_completed(request, false))
 			continue;
 
 		return request;
@@ -2747,15 +2741,11 @@ void i915_gem_request_unreference_irq(struct drm_i915_gem_request *req)
 void
 i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
 {
-	uint32_t seqno;
-
 	if (list_empty(&ring->request_list))
 		return;
 
 	WARN_ON(i915_verify_lists(ring->dev));
 
-	seqno = ring->get_seqno(ring, true);
-
 	/* 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.
@@ -2767,8 +2757,7 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
 				      struct drm_i915_gem_object,
 				      ring_list);
 
-		if (!i915_seqno_passed(seqno,
-			     i915_gem_request_get_seqno(obj->last_read_req)))
+		if (!i915_gem_request_completed(obj->last_read_req, true))
 			break;
 
 		i915_gem_object_move_to_inactive(obj);
@@ -2783,7 +2772,7 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
 					   struct drm_i915_gem_request,
 					   list);
 
-		if (!i915_seqno_passed(seqno, request->seqno))
+		if (!i915_gem_request_completed(request, true))
 			break;
 
 		trace_i915_gem_request_retire(request);
@@ -2810,8 +2799,7 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
 	}
 
 	if (unlikely(ring->trace_irq_req &&
-		     i915_seqno_passed(seqno,
-			 i915_gem_request_get_seqno(ring->trace_irq_req)))) {
+		     i915_gem_request_completed(ring->trace_irq_req, true))) {
 		ring->irq_put(ring);
 		i915_gem_request_assign(&ring->trace_irq_req, NULL);
 	}
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 2042d62..b86b474 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2749,8 +2749,7 @@ static bool
 ring_idle(struct intel_engine_cs *ring)
 {
 	return (list_empty(&ring->request_list) ||
-		i915_seqno_passed(ring->get_seqno(ring, false),
-			i915_gem_request_get_seqno(ring_last_request(ring))));
+		i915_gem_request_completed(ring_last_request(ring), false));
 }
 
 static bool
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 4a801e4..0db41fb 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9670,11 +9670,7 @@ static bool __intel_pageflip_stall_check(struct drm_device *dev,
 
 	if (work->flip_ready_vblank == 0) {
 		if (work->flip_queued_ring) {
-			uint32_t s1 = work->flip_queued_ring->get_seqno(
-					       work->flip_queued_ring, true);
-			uint32_t s2 = i915_gem_request_get_seqno(
-						      work->flip_queued_req);
-			if (!i915_seqno_passed(s1, s2))
+			if (!i915_gem_request_completed(work->flip_queued_req, true))
 				return false;
 
 			i915_gem_request_unreference_irq(work->flip_queued_req);
-- 
1.7.9.5

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

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

* [PATCH v3 21/28] drm/i915: Remove the now redundant 'obj->ring'
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (19 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 20/28] drm/i915: Convert 'i915_seqno_passed' calls into 'i915_gem_request_completed' John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-26 13:43   ` Daniel Vetter
  2014-11-24 18:49 ` [PATCH v3 22/28] drm/i915: Cache request completion status John.C.Harrison
                   ` (8 subsequent siblings)
  29 siblings, 1 reply; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The ring member of the object structure was always updated with the
last_read_seqno member. Thus with the conversion to last_read_req, obj->ring is
now a direct copy of obj->last_read_req->ring. This makes it somewhat redundant
and potentially misleading (especially as there was no comment to explain its
purpose).

This checkin removes the redundant field. Many uses were simply testing for
non-null to see if the object is active on the GPU. Some of these have been
converted to check 'obj->active' instead. Others (where the last_read_req is
about to be used anyway) have been changed to check obj->last_read_req. The rest
simply pull the ring out from the request structure and proceed as before.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c     |    9 +++++----
 drivers/gpu/drm/i915/i915_drv.h         |    2 --
 drivers/gpu/drm/i915/i915_gem.c         |   32 +++++++++++++++++++------------
 drivers/gpu/drm/i915/i915_gem_context.c |    3 ++-
 drivers/gpu/drm/i915/i915_gpu_error.c   |    3 ++-
 drivers/gpu/drm/i915/intel_display.c    |    7 ++++---
 6 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 3dc893c..b4993fc 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -168,8 +168,9 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
 		*t = '\0';
 		seq_printf(m, " (%s mappable)", s);
 	}
-	if (obj->ring != NULL)
-		seq_printf(m, " (%s)", obj->ring->name);
+	if (obj->last_read_req != NULL)
+		seq_printf(m, " (%s)",
+			   i915_gem_request_get_ring(obj->last_read_req)->name);
 	if (obj->frontbuffer_bits)
 		seq_printf(m, " (frontbuffer: 0x%03x)", obj->frontbuffer_bits);
 }
@@ -336,7 +337,7 @@ static int per_file_stats(int id, void *ptr, void *data)
 			if (ppgtt->file_priv != stats->file_priv)
 				continue;
 
-			if (obj->ring) /* XXX per-vma statistic */
+			if (obj->active) /* XXX per-vma statistic */
 				stats->active += obj->base.size;
 			else
 				stats->inactive += obj->base.size;
@@ -346,7 +347,7 @@ static int per_file_stats(int id, void *ptr, void *data)
 	} else {
 		if (i915_gem_obj_ggtt_bound(obj)) {
 			stats->global += obj->base.size;
-			if (obj->ring)
+			if (obj->active)
 				stats->active += obj->base.size;
 			else
 				stats->inactive += obj->base.size;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1325506..36a4413 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1941,8 +1941,6 @@ struct drm_i915_gem_object {
 	void *dma_buf_vmapping;
 	int vmapping_count;
 
-	struct intel_engine_cs *ring;
-
 	/** Breadcrumb of last rendering to the buffer. */
 	struct drm_i915_gem_request *last_read_req;
 	struct drm_i915_gem_request *last_write_req;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index cccca47..68c23dd 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2263,14 +2263,18 @@ static void
 i915_gem_object_move_to_active(struct drm_i915_gem_object *obj,
 			       struct intel_engine_cs *ring)
 {
-	struct drm_i915_gem_request *req = intel_ring_get_request(ring);
+	struct drm_i915_gem_request *req;
+	struct intel_engine_cs *old_ring;
 
 	BUG_ON(ring == NULL);
-	if (obj->ring != ring && obj->last_write_req) {
+
+	req = intel_ring_get_request(ring);
+	old_ring = i915_gem_request_get_ring(obj->last_read_req);
+
+	if (old_ring != ring && obj->last_write_req) {
 		/* Keep the request relative to the current ring */
 		i915_gem_request_assign(&obj->last_write_req, req);
 	}
-	obj->ring = ring;
 
 	/* Add a reference if we're newly entering the active list. */
 	if (!obj->active) {
@@ -2309,7 +2313,6 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj)
 	intel_fb_obj_flush(obj, true);
 
 	list_del_init(&obj->ring_list);
-	obj->ring = NULL;
 
 	i915_gem_request_assign(&obj->last_read_req, NULL);
 	i915_gem_request_assign(&obj->last_write_req, NULL);
@@ -2326,9 +2329,7 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj)
 static void
 i915_gem_object_retire(struct drm_i915_gem_object *obj)
 {
-	struct intel_engine_cs *ring = obj->ring;
-
-	if (ring == NULL)
+	if (obj->last_read_req == NULL)
 		return;
 
 	if (i915_gem_request_completed(obj->last_read_req, true))
@@ -2892,14 +2893,17 @@ i915_gem_idle_work_handler(struct work_struct *work)
 static int
 i915_gem_object_flush_active(struct drm_i915_gem_object *obj)
 {
+	struct intel_engine_cs *ring;
 	int ret;
 
 	if (obj->active) {
+		ring = i915_gem_request_get_ring(obj->last_read_req);
+
 		ret = i915_gem_check_olr(obj->last_read_req);
 		if (ret)
 			return ret;
 
-		i915_gem_retire_requests_ring(obj->ring);
+		i915_gem_retire_requests_ring(ring);
 	}
 
 	return 0;
@@ -3002,10 +3006,12 @@ int
 i915_gem_object_sync(struct drm_i915_gem_object *obj,
 		     struct intel_engine_cs *to)
 {
-	struct intel_engine_cs *from = obj->ring;
+	struct intel_engine_cs *from;
 	u32 seqno;
 	int ret, idx;
 
+	from = i915_gem_request_get_ring(obj->last_read_req);
+
 	if (from == NULL || to == from)
 		return 0;
 
@@ -3964,7 +3970,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
 	bool was_pin_display;
 	int ret;
 
-	if (pipelined != obj->ring) {
+	if (pipelined != i915_gem_request_get_ring(obj->last_read_req)) {
 		ret = i915_gem_object_sync(obj, pipelined);
 		if (ret)
 			return ret;
@@ -4412,9 +4418,11 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
 	ret = i915_gem_object_flush_active(obj);
 
 	args->busy = obj->active;
-	if (obj->ring) {
+	if (obj->last_read_req) {
+		struct intel_engine_cs *ring;
 		BUILD_BUG_ON(I915_NUM_RINGS > 16);
-		args->busy |= intel_ring_flag(obj->ring) << 16;
+		ring = i915_gem_request_get_ring(obj->last_read_req);
+		args->busy |= intel_ring_flag(ring) << 16;
 	}
 
 	drm_gem_object_unreference(&obj->base);
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index d17ff43..3c3a9ff 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -619,7 +619,8 @@ static int do_switch(struct intel_engine_cs *ring,
 		 * swapped, but there is no way to do that yet.
 		 */
 		from->legacy_hw_ctx.rcs_state->dirty = 1;
-		BUG_ON(from->legacy_hw_ctx.rcs_state->ring != ring);
+		BUG_ON(i915_gem_request_get_ring(
+			from->legacy_hw_ctx.rcs_state->last_read_req) != ring);
 
 		/* 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_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 998bd8a..f3b163c 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -685,7 +685,8 @@ 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->ring ? obj->ring->id : -1;
+	err->ring = obj->last_read_req ?
+			i915_gem_request_get_ring(obj->last_read_req)->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 0db41fb..1cf9c82 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9459,7 +9459,7 @@ static bool use_mmio_flip(struct intel_engine_cs *ring,
 	else if (i915.enable_execlists)
 		return true;
 	else
-		return ring != obj->ring;
+		return ring != i915_gem_request_get_ring(obj->last_read_req);
 }
 
 static void skl_do_mmio_flip(struct intel_crtc *intel_crtc)
@@ -9820,7 +9820,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 	} else if (IS_IVYBRIDGE(dev)) {
 		ring = &dev_priv->ring[BCS];
 	} else if (INTEL_INFO(dev)->gen >= 7) {
-		ring = obj->ring;
+		ring = i915_gem_request_get_ring(obj->last_read_req);
 		if (ring == NULL || ring->id != RCS)
 			ring = &dev_priv->ring[BCS];
 	} else {
@@ -9842,7 +9842,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 
 		i915_gem_request_assign(&work->flip_queued_req,
 					obj->last_write_req);
-		work->flip_queued_ring = obj->ring;
+		work->flip_queued_ring =
+				i915_gem_request_get_ring(obj->last_write_req);
 	} else {
 		ret = dev_priv->display.queue_flip(dev, crtc, fb, obj, ring,
 						   page_flip_flags);
-- 
1.7.9.5

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

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

* [PATCH v3 22/28] drm/i915: Cache request completion status
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (20 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 21/28] drm/i915: Remove the now redundant 'obj->ring' John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-24 18:49 ` [PATCH v3 23/28] drm/i915: Zero fill the request structure John.C.Harrison
                   ` (7 subsequent siblings)
  29 siblings, 0 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Continuing the removal of seqno based operations - updated the request
completion query to not simply chain on to i915_seqno_passed(). Instead, it now
returns a pre-cached completion flag in the fast case. In the slow case it reads
the hardware seqno and, only if it has moved on since the last scan, looks
through the outstanding request list to see which requests can be marked as
completed.

Later in the patch series, this will be optimised further by only doing the
completion scan when an interrupt is raised to say that a request has actually
completed on the hardware. Thus the call to test the completion status of an
arbitrary request simply becomes 'return req->completed'.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h         |   32 +++++++++++++++----------------
 drivers/gpu/drm/i915/i915_gem.c         |   24 +++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_lrc.c        |    1 +
 drivers/gpu/drm/i915/intel_ringbuffer.c |    2 ++
 drivers/gpu/drm/i915/intel_ringbuffer.h |    3 +++
 5 files changed, 45 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 36a4413..d30823e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1996,6 +1996,9 @@ void i915_gem_track_fb(struct drm_i915_gem_object *old,
 struct drm_i915_gem_request {
 	struct kref ref;
 
+	/** Is this request known to be complete? */
+	bool complete;
+
 	/** On Which ring this request was generated */
 	struct intel_engine_cs *ring;
 
@@ -2030,6 +2033,8 @@ struct drm_i915_gem_request {
 };
 
 void i915_gem_request_free(struct kref *req_ref);
+void i915_gem_complete_requests_ring(struct intel_engine_cs *ring,
+				     bool lazy_coherency);
 
 static inline uint32_t
 i915_gem_request_get_seqno(struct drm_i915_gem_request *req)
@@ -2070,11 +2075,16 @@ static inline void i915_gem_request_assign(struct drm_i915_gem_request **pdst,
 	*pdst = src;
 }
 
-/*
- * XXX: i915_gem_request_completed should be here but currently needs the
- * definition of i915_seqno_passed() which is below. It will be moved in
- * a later patch when the call to i915_seqno_passed() is obsoleted...
- */
+static inline bool i915_gem_request_completed(struct drm_i915_gem_request *req,
+					      bool lazy_coherency)
+{
+	if (req->complete)
+		return true;
+
+	i915_gem_complete_requests_ring(req->ring, lazy_coherency);
+
+	return req->complete;
+}
 
 struct drm_i915_file_private {
 	struct drm_i915_private *dev_priv;
@@ -3134,18 +3144,6 @@ wait_remaining_ms_from_jiffies(unsigned long timestamp_jiffies, int to_wait_ms)
 	}
 }
 
-static inline bool i915_gem_request_completed(struct drm_i915_gem_request *req,
-					      bool lazy_coherency)
-{
-	u32 seqno;
-
-	BUG_ON(req == NULL);
-
-	seqno = req->ring->get_seqno(req->ring, lazy_coherency);
-
-	return i915_seqno_passed(seqno, req->seqno);
-}
-
 static inline void i915_trace_irq_get(struct intel_engine_cs *ring,
 				      struct drm_i915_gem_request *req)
 {
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 68c23dd..ce316fa 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2736,6 +2736,30 @@ void i915_gem_request_unreference_irq(struct drm_i915_gem_request *req)
 	spin_unlock_irqrestore(&ring->reqlist_lock, flags);
 }
 
+void i915_gem_complete_requests_ring(struct intel_engine_cs *ring,
+				     bool lazy_coherency)
+{
+	struct drm_i915_gem_request *req;
+	u32 seqno;
+
+	seqno = ring->get_seqno(ring, lazy_coherency);
+	if (!seqno)
+		return;
+
+	if (seqno == ring->last_read_seqno)
+		return;
+
+	list_for_each_entry(req, &ring->request_list, list) {
+		if (req->complete)
+			continue;
+
+		if (i915_seqno_passed(seqno, req->seqno))
+			req->complete = true;
+	}
+
+	ring->last_read_seqno = seqno;
+}
+
 /**
  * This function clears the request list as sequence numbers are passed.
  */
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 0acb448..6711020 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -899,6 +899,7 @@ static int logical_ring_alloc_request(struct intel_engine_cs *ring,
 
 	kref_init(&request->ref);
 	request->ring = ring;
+	request->complete = false;
 
 	ret = i915_gem_get_seqno(ring->dev, &request->seqno);
 	if (ret) {
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 5a1e6fe..92c72b3 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -2047,6 +2047,7 @@ intel_ring_alloc_request(struct intel_engine_cs *ring)
 
 	kref_init(&request->ref);
 	request->ring = ring;
+	request->complete = false;
 
 	ret = i915_gem_get_seqno(ring->dev, &request->seqno);
 	if (ret) {
@@ -2139,6 +2140,7 @@ void intel_ring_init_seqno(struct intel_engine_cs *ring, u32 seqno)
 			I915_WRITE(RING_SYNC_2(ring->mmio_base), 0);
 	}
 
+	ring->last_read_seqno = 0;
 	ring->set_seqno(ring, seqno);
 	ring->hangcheck.seqno = seqno;
 }
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index c8b84de..1c035c8 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -273,6 +273,9 @@ struct  intel_engine_cs {
 	bool gpu_caches_dirty;
 	bool fbc_dirty;
 
+	/* For optimising request completion events */
+	u32 last_read_seqno;
+
 	wait_queue_head_t irq_queue;
 
 	struct intel_context *default_context;
-- 
1.7.9.5

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

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

* [PATCH v3 23/28] drm/i915: Zero fill the request structure
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (21 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 22/28] drm/i915: Cache request completion status John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-24 18:49 ` [PATCH v3 24/28] drm/i915: Spinlock protection for request list John.C.Harrison
                   ` (6 subsequent siblings)
  29 siblings, 0 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

There is a general theory that kzmalloc is better/safer than kmalloc, especially
for interesting data structures. This change updates the request structure
allocation to be zero filled. That also means it is no longer necessary to
explicitly clear the 'complete' field.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/intel_lrc.c        |    3 +--
 drivers/gpu/drm/i915/intel_ringbuffer.c |    3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 6711020..a7d4b50 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -885,7 +885,7 @@ static int logical_ring_alloc_request(struct intel_engine_cs *ring,
 	if (ring->outstanding_lazy_request)
 		return 0;
 
-	request = kmalloc(sizeof(*request), GFP_KERNEL);
+	request = kzalloc(sizeof(*request), GFP_KERNEL);
 	if (request == NULL)
 		return -ENOMEM;
 
@@ -899,7 +899,6 @@ static int logical_ring_alloc_request(struct intel_engine_cs *ring,
 
 	kref_init(&request->ref);
 	request->ring = ring;
-	request->complete = false;
 
 	ret = i915_gem_get_seqno(ring->dev, &request->seqno);
 	if (ret) {
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 92c72b3..a62ac336 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -2041,13 +2041,12 @@ intel_ring_alloc_request(struct intel_engine_cs *ring)
 	if (ring->outstanding_lazy_request)
 		return 0;
 
-	request = kmalloc(sizeof(*request), GFP_KERNEL);
+	request = kzalloc(sizeof(*request), GFP_KERNEL);
 	if (request == NULL)
 		return -ENOMEM;
 
 	kref_init(&request->ref);
 	request->ring = ring;
-	request->complete = false;
 
 	ret = i915_gem_get_seqno(ring->dev, &request->seqno);
 	if (ret) {
-- 
1.7.9.5

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

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

* [PATCH v3 24/28] drm/i915: Spinlock protection for request list
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (22 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 23/28] drm/i915: Zero fill the request structure John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-24 18:49 ` [PATCH v3 25/28] drm/i915: Interrupt driven request completion John.C.Harrison
                   ` (5 subsequent siblings)
  29 siblings, 0 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The completion status for all entries in the request list is updated on demand.
This occurs whenever the code queries the completion status of a given request
and a new seqno value has popped out of the hardware. Unfortuntately, not all
such queries are done with the driver mutex lock held. Therefore there is a race
condition between the query processing and the retired request removal code
which can result in a dodgy pointer dereference.

The solution is to spinlock around those two points - the actual list entry
removal and the potentially asynchronous query. This ensures that the query will
never see a node that is in the process of being destroyed.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c |    8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index ce316fa..71fcbea 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2569,7 +2569,12 @@ static void i915_set_reset_status(struct drm_i915_private *dev_priv,
 
 static void i915_gem_free_request(struct drm_i915_gem_request *request)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&request->ring->reqlist_lock, flags);
 	list_del(&request->list);
+	spin_unlock_irqrestore(&request->ring->reqlist_lock, flags);
+
 	i915_gem_request_remove_from_client(request);
 
 	i915_gem_request_unreference(request);
@@ -2740,6 +2745,7 @@ void i915_gem_complete_requests_ring(struct intel_engine_cs *ring,
 				     bool lazy_coherency)
 {
 	struct drm_i915_gem_request *req;
+	unsigned long flags;
 	u32 seqno;
 
 	seqno = ring->get_seqno(ring, lazy_coherency);
@@ -2749,6 +2755,7 @@ void i915_gem_complete_requests_ring(struct intel_engine_cs *ring,
 	if (seqno == ring->last_read_seqno)
 		return;
 
+	spin_lock_irqsave(&ring->reqlist_lock, flags);
 	list_for_each_entry(req, &ring->request_list, list) {
 		if (req->complete)
 			continue;
@@ -2756,6 +2763,7 @@ void i915_gem_complete_requests_ring(struct intel_engine_cs *ring,
 		if (i915_seqno_passed(seqno, req->seqno))
 			req->complete = true;
 	}
+	spin_unlock_irqrestore(&ring->reqlist_lock, flags);
 
 	ring->last_read_seqno = seqno;
 }
-- 
1.7.9.5

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

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

* [PATCH v3 25/28] drm/i915: Interrupt driven request completion
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (23 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 24/28] drm/i915: Spinlock protection for request list John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-24 18:49 ` [PATCH v3 26/28] drm/i915: Remove obsolete parameter to i915_gem_request_completed() John.C.Harrison
                   ` (4 subsequent siblings)
  29 siblings, 0 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Added a hook to the ring noftification code to process request completion. This
means that there is no longer a need to explicitly process request completions
every time a request object is tested. Instead, the test code simply becomes
'return req->completed'. Obviously, this only works if ring interrupts are
enabled, however, this is already the case for the duration of __wait_request()
which is the point where the driver really needs to know.

To prevent stale requests floating around indefinitely, the retire work handler
also now performs a completion check periodically.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h |    5 -----
 drivers/gpu/drm/i915/i915_gem.c |   10 ++++++++++
 drivers/gpu/drm/i915/i915_irq.c |    2 ++
 3 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d30823e..c969499 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2078,11 +2078,6 @@ static inline void i915_gem_request_assign(struct drm_i915_gem_request **pdst,
 static inline bool i915_gem_request_completed(struct drm_i915_gem_request *req,
 					      bool lazy_coherency)
 {
-	if (req->complete)
-		return true;
-
-	i915_gem_complete_requests_ring(req->ring, lazy_coherency);
-
 	return req->complete;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 71fcbea..4aec1eb 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1239,6 +1239,11 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
 	if (!irq_test_in_progress && WARN_ON(!ring->irq_get(ring)))
 		return -ENODEV;
 
+	/* Completion status should be interrupt driven but it is possible
+	 * the request popped out before the interrupt was enabled. So do an
+	 * explicit check now... */
+	i915_gem_complete_requests_ring(req->ring, false);
+
 	/* Record current time in case interrupted by signal, or wedged */
 	trace_i915_gem_request_wait_begin(req);
 	before = ktime_get_raw_ns();
@@ -2485,6 +2490,10 @@ int __i915_add_request(struct intel_engine_cs *ring,
 	list_add_tail(&request->list, &ring->request_list);
 	request->file_priv = NULL;
 
+	/* Avoid race condition where the request completes before it has
+	 * been added to the list. */
+	ring->last_read_seqno = 0;
+
 	if (file) {
 		struct drm_i915_file_private *file_priv = file->driver_priv;
 
@@ -2868,6 +2877,7 @@ i915_gem_retire_requests(struct drm_device *dev)
 	int i;
 
 	for_each_ring(ring, dev_priv, i) {
+		i915_gem_complete_requests_ring(ring, false);
 		i915_gem_retire_requests_ring(ring);
 		idle &= list_empty(&ring->request_list);
 		if (i915.enable_execlists) {
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index b86b474..d425bb5 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1002,6 +1002,8 @@ static void notify_ring(struct drm_device *dev,
 
 	trace_i915_gem_request_complete(ring);
 
+	i915_gem_complete_requests_ring(ring, false);
+
 	wake_up_all(&ring->irq_queue);
 }
 
-- 
1.7.9.5

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

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

* [PATCH v3 26/28] drm/i915: Remove obsolete parameter to i915_gem_request_completed()
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (24 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 25/28] drm/i915: Interrupt driven request completion John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-24 18:49 ` [PATCH v3 27/28] drm/i915: Add unique id to the request structure for debugging John.C.Harrison
                   ` (3 subsequent siblings)
  29 siblings, 0 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The request completion test no longer chains on to the request completion
processing code. Thus it no longer needs to pass a 'lazy coherency' flag through
to the seqno query call. Hence that parameter can be removed.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c  |    2 +-
 drivers/gpu/drm/i915/i915_drv.h      |    3 +--
 drivers/gpu/drm/i915/i915_gem.c      |   14 +++++++-------
 drivers/gpu/drm/i915/i915_irq.c      |    2 +-
 drivers/gpu/drm/i915/intel_display.c |    2 +-
 5 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index b4993fc..13e8d5c 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -550,7 +550,7 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data)
 					   i915_gem_request_get_seqno(work->flip_queued_req),
 					   dev_priv->next_seqno,
 					   work->flip_queued_ring->get_seqno(work->flip_queued_ring, true),
-					   i915_gem_request_completed(work->flip_queued_req, true));
+					   i915_gem_request_completed(work->flip_queued_req));
 			} else
 				seq_printf(m, "Flip not associated with any ring\n");
 			seq_printf(m, "Flip queued on frame %d, (was ready on frame %d), now %d\n",
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c969499..cf9fc74 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2075,8 +2075,7 @@ static inline void i915_gem_request_assign(struct drm_i915_gem_request **pdst,
 	*pdst = src;
 }
 
-static inline bool i915_gem_request_completed(struct drm_i915_gem_request *req,
-					      bool lazy_coherency)
+static inline bool i915_gem_request_completed(struct drm_i915_gem_request *req)
 {
 	return req->complete;
 }
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 4aec1eb..4ec27e1 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1223,7 +1223,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
 
 	WARN(!intel_irqs_enabled(dev_priv), "IRQs disabled");
 
-	if (i915_gem_request_completed(req, true))
+	if (i915_gem_request_completed(req))
 		return 0;
 
 	timeout_expire = timeout ? jiffies + nsecs_to_jiffies((u64)*timeout) : 0;
@@ -1264,7 +1264,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req,
 			break;
 		}
 
-		if (i915_gem_request_completed(req, false)) {
+		if (i915_gem_request_completed(req)) {
 			ret = 0;
 			break;
 		}
@@ -2337,7 +2337,7 @@ i915_gem_object_retire(struct drm_i915_gem_object *obj)
 	if (obj->last_read_req == NULL)
 		return;
 
-	if (i915_gem_request_completed(obj->last_read_req, true))
+	if (i915_gem_request_completed(obj->last_read_req))
 		i915_gem_object_move_to_inactive(obj);
 }
 
@@ -2615,7 +2615,7 @@ i915_gem_find_active_request(struct intel_engine_cs *ring)
 	struct drm_i915_gem_request *request;
 
 	list_for_each_entry(request, &ring->request_list, list) {
-		if (i915_gem_request_completed(request, false))
+		if (i915_gem_request_completed(request))
 			continue;
 
 		return request;
@@ -2799,7 +2799,7 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
 				      struct drm_i915_gem_object,
 				      ring_list);
 
-		if (!i915_gem_request_completed(obj->last_read_req, true))
+		if (!i915_gem_request_completed(obj->last_read_req))
 			break;
 
 		i915_gem_object_move_to_inactive(obj);
@@ -2814,7 +2814,7 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
 					   struct drm_i915_gem_request,
 					   list);
 
-		if (!i915_gem_request_completed(request, true))
+		if (!i915_gem_request_completed(request))
 			break;
 
 		trace_i915_gem_request_retire(request);
@@ -2841,7 +2841,7 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
 	}
 
 	if (unlikely(ring->trace_irq_req &&
-		     i915_gem_request_completed(ring->trace_irq_req, true))) {
+		     i915_gem_request_completed(ring->trace_irq_req))) {
 		ring->irq_put(ring);
 		i915_gem_request_assign(&ring->trace_irq_req, NULL);
 	}
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index d425bb5..eb5441c 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2751,7 +2751,7 @@ static bool
 ring_idle(struct intel_engine_cs *ring)
 {
 	return (list_empty(&ring->request_list) ||
-		i915_gem_request_completed(ring_last_request(ring), false));
+		i915_gem_request_completed(ring_last_request(ring)));
 }
 
 static bool
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 1cf9c82..7010ed2 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9670,7 +9670,7 @@ static bool __intel_pageflip_stall_check(struct drm_device *dev,
 
 	if (work->flip_ready_vblank == 0) {
 		if (work->flip_queued_ring) {
-			if (!i915_gem_request_completed(work->flip_queued_req, true))
+			if (!i915_gem_request_completed(work->flip_queued_req))
 				return false;
 
 			i915_gem_request_unreference_irq(work->flip_queued_req);
-- 
1.7.9.5

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

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

* [PATCH v3 27/28] drm/i915: Add unique id to the request structure for debugging
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (25 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 26/28] drm/i915: Remove obsolete parameter to i915_gem_request_completed() John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-24 18:49 ` [PATCH v3 28/28] drm/i915: Additional request structure tracing John.C.Harrison
                   ` (2 subsequent siblings)
  29 siblings, 0 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

For debugging purposes, it is useful to be able to uniquely identify a given
request structure as it works its way through the system. This becomes
especially tricky once the seqno value is lazily allocated as then the request
has nothing but its pointer to identify it for much of its life.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h         |    4 ++++
 drivers/gpu/drm/i915/intel_lrc.c        |    2 ++
 drivers/gpu/drm/i915/intel_ringbuffer.c |    2 ++
 3 files changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index cf9fc74..20ff643 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1787,6 +1787,8 @@ struct drm_i915_private {
 		void (*stop_ring)(struct intel_engine_cs *ring);
 	} gt;
 
+	uint32_t request_uniq;
+
 	/*
 	 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
 	 * will be rejected. Instead look for a better place.
@@ -2030,6 +2032,8 @@ struct drm_i915_gem_request {
 	/** deferred free list for dereferencing from IRQ context */
 	struct list_head delay_free_list;
 	uint32_t delay_free_count;
+
+	uint32_t uniq;
 };
 
 void i915_gem_request_free(struct kref *req_ref);
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index a7d4b50..f82fc1a 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -880,6 +880,7 @@ static int logical_ring_alloc_request(struct intel_engine_cs *ring,
 				      struct intel_context *ctx)
 {
 	struct drm_i915_gem_request *request;
+	struct drm_i915_private *dev_private = ring->dev->dev_private;
 	int ret;
 
 	if (ring->outstanding_lazy_request)
@@ -899,6 +900,7 @@ static int logical_ring_alloc_request(struct intel_engine_cs *ring,
 
 	kref_init(&request->ref);
 	request->ring = ring;
+	request->uniq = dev_private->request_uniq++;
 
 	ret = i915_gem_get_seqno(ring->dev, &request->seqno);
 	if (ret) {
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index a62ac336..afc8974 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -2037,6 +2037,7 @@ intel_ring_alloc_request(struct intel_engine_cs *ring)
 {
 	int ret;
 	struct drm_i915_gem_request *request;
+	struct drm_i915_private *dev_private = ring->dev->dev_private;
 
 	if (ring->outstanding_lazy_request)
 		return 0;
@@ -2047,6 +2048,7 @@ intel_ring_alloc_request(struct intel_engine_cs *ring)
 
 	kref_init(&request->ref);
 	request->ring = ring;
+	request->uniq = dev_private->request_uniq++;
 
 	ret = i915_gem_get_seqno(ring->dev, &request->seqno);
 	if (ret) {
-- 
1.7.9.5

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

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

* [PATCH v3 28/28] drm/i915: Additional request structure tracing
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (26 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 27/28] drm/i915: Add unique id to the request structure for debugging John.C.Harrison
@ 2014-11-24 18:49 ` John.C.Harrison
  2014-11-25 11:59 ` [PATCH v3 00/28] Replace seqno values with request structures Daniel, Thomas
  2014-12-05 13:49 ` [PATCH v4 0/4] " John.C.Harrison
  29 siblings, 0 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-11-24 18:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Added the request structure's 'uniq' identifier to the trace information. Also
renamed the '_complete' trace event to '_notify' as it actually happens in the
IRQ 'notify_ring()' function. Additionally there is now a new '_complete' trace
event which occurs when a request structure is marked as complete.

v2: New patch added to series.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c   |    4 +++-
 drivers/gpu/drm/i915/i915_irq.c   |    2 +-
 drivers/gpu/drm/i915/i915_trace.h |   22 ++++++++++++++++------
 3 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 4ec27e1..197bac1 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2769,8 +2769,10 @@ void i915_gem_complete_requests_ring(struct intel_engine_cs *ring,
 		if (req->complete)
 			continue;
 
-		if (i915_seqno_passed(seqno, req->seqno))
+		if (i915_seqno_passed(seqno, req->seqno)) {
 			req->complete = true;
+			trace_i915_gem_request_complete(req);
+		}
 	}
 	spin_unlock_irqrestore(&ring->reqlist_lock, flags);
 
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index eb5441c..308e9da 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1000,7 +1000,7 @@ static void notify_ring(struct drm_device *dev,
 	if (!intel_ring_initialized(ring))
 		return;
 
-	trace_i915_gem_request_complete(ring);
+	trace_i915_gem_request_notify(ring);
 
 	i915_gem_complete_requests_ring(ring, false);
 
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h
index 2ade958..6058a01 100644
--- a/drivers/gpu/drm/i915/i915_trace.h
+++ b/drivers/gpu/drm/i915/i915_trace.h
@@ -406,6 +406,7 @@ DECLARE_EVENT_CLASS(i915_gem_request,
 	    TP_STRUCT__entry(
 			     __field(u32, dev)
 			     __field(u32, ring)
+			     __field(u32, uniq)
 			     __field(u32, seqno)
 			     ),
 
@@ -414,11 +415,13 @@ DECLARE_EVENT_CLASS(i915_gem_request,
 						i915_gem_request_get_ring(req);
 			   __entry->dev = ring->dev->primary->index;
 			   __entry->ring = ring->id;
+			   __entry->uniq = req ? req->uniq : 0;
 			   __entry->seqno = i915_gem_request_get_seqno(req);
 			   ),
 
-	    TP_printk("dev=%u, ring=%u, seqno=%u",
-		      __entry->dev, __entry->ring, __entry->seqno)
+	    TP_printk("dev=%u, ring=%u, uniq=%u, seqno=%u",
+		      __entry->dev, __entry->ring, __entry->uniq,
+		      __entry->seqno)
 );
 
 DEFINE_EVENT(i915_gem_request, i915_gem_request_add,
@@ -426,7 +429,7 @@ DEFINE_EVENT(i915_gem_request, i915_gem_request_add,
 	    TP_ARGS(req)
 );
 
-TRACE_EVENT(i915_gem_request_complete,
+TRACE_EVENT(i915_gem_request_notify,
 	    TP_PROTO(struct intel_engine_cs *ring),
 	    TP_ARGS(ring),
 
@@ -451,6 +454,11 @@ DEFINE_EVENT(i915_gem_request, i915_gem_request_retire,
 	    TP_ARGS(req)
 );
 
+DEFINE_EVENT(i915_gem_request, i915_gem_request_complete,
+	    TP_PROTO(struct drm_i915_gem_request *req),
+	    TP_ARGS(req)
+);
+
 TRACE_EVENT(i915_gem_request_wait_begin,
 	    TP_PROTO(struct drm_i915_gem_request *req),
 	    TP_ARGS(req),
@@ -458,6 +466,7 @@ TRACE_EVENT(i915_gem_request_wait_begin,
 	    TP_STRUCT__entry(
 			     __field(u32, dev)
 			     __field(u32, ring)
+			     __field(u32, uniq)
 			     __field(u32, seqno)
 			     __field(bool, blocking)
 			     ),
@@ -473,14 +482,15 @@ TRACE_EVENT(i915_gem_request_wait_begin,
 						i915_gem_request_get_ring(req);
 			   __entry->dev = ring->dev->primary->index;
 			   __entry->ring = ring->id;
+			   __entry->uniq = req ? req->uniq : 0;
 			   __entry->seqno = i915_gem_request_get_seqno(req);
 			   __entry->blocking =
 				     mutex_is_locked(&ring->dev->struct_mutex);
 			   ),
 
-	    TP_printk("dev=%u, ring=%u, seqno=%u, blocking=%s",
-		      __entry->dev, __entry->ring, __entry->seqno,
-		      __entry->blocking ?  "yes (NB)" : "no")
+	    TP_printk("dev=%u, ring=%u, uniq=%u, seqno=%u, blocking=%s",
+		      __entry->dev, __entry->ring, __entry->uniq,
+		      __entry->seqno, __entry->blocking ?  "yes (NB)" : "no")
 );
 
 DEFINE_EVENT(i915_gem_request, i915_gem_request_wait_end,
-- 
1.7.9.5

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

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

* Re: [PATCH v3 00/28] Replace seqno values with request structures
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (27 preceding siblings ...)
  2014-11-24 18:49 ` [PATCH v3 28/28] drm/i915: Additional request structure tracing John.C.Harrison
@ 2014-11-25 11:59 ` Daniel, Thomas
  2014-12-05 13:49 ` [PATCH v4 0/4] " John.C.Harrison
  29 siblings, 0 replies; 63+ messages in thread
From: Daniel, Thomas @ 2014-11-25 11:59 UTC (permalink / raw)
  To: Harrison, John C, Intel-GFX

> -----Original Message-----
> From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf
> Of John.C.Harrison@Intel.com
> Sent: Monday, November 24, 2014 6:49 PM
> To: Intel-GFX@Lists.FreeDesktop.Org
> Subject: [Intel-gfx] [PATCH v3 00/28] Replace seqno values with request
> structures
> 
> From: John Harrison <John.C.Harrison@Intel.com>
> v3: Rebased to yet another nightly tree which included execlist pin/unpin
> patches. NB: this is based on a tree including a pending update for an unpin
> bug. Also includes a fix for a clash with the shrinker.
Rebase and bug fix look good, assuming my ctx leak patch is applied beforehand.

Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>

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

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

* Re: [PATCH v3 11/28] drm/i915: Add IRQ friendly request deference facility
  2014-11-24 18:49 ` [PATCH v3 11/28] drm/i915: Add IRQ friendly request deference facility John.C.Harrison
@ 2014-11-26  9:19   ` Daniel Vetter
  2014-11-26 12:23     ` John Harrison
  0 siblings, 1 reply; 63+ messages in thread
From: Daniel Vetter @ 2014-11-26  9:19 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: Intel-GFX

On Mon, Nov 24, 2014 at 06:49:33PM +0000, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> The next patches in the series convert some display related seqno usage to
> request structure usage. However, the request dereference introduced must be
> done from interrupt context. As the dereference potentially involves freeing the
> request structure and thus calling lots of non-interrupt friendly code, this
> poses a problem.
> 
> The solution is to add an IRQ friendly version of the dereference function. All
> this does is to add the request structure to a 'delayed free' list and return.
> The retire code, which is run periodically, then processes this list and does
> the actual dereferencing of the request structures.
> 
> v2: Added a count to allow for multiple IRQ dereferences of the same request at
> a time.
> 
> For: VIZ-4377
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h         |    7 +++++++
>  drivers/gpu/drm/i915/i915_gem.c         |   33 +++++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_lrc.c        |    2 ++
>  drivers/gpu/drm/i915/intel_ringbuffer.c |    2 ++
>  drivers/gpu/drm/i915/intel_ringbuffer.h |    2 ++
>  5 files changed, 46 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 149532e6..e9b01e1 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2025,6 +2025,10 @@ struct drm_i915_gem_request {
>  	struct drm_i915_file_private *file_priv;
>  	/** file_priv list entry for this request */
>  	struct list_head client_list;
> +
> +	/** deferred free list for dereferencing from IRQ context */
> +	struct list_head delay_free_list;
> +	uint32_t delay_free_count;
>  };
>  
>  void i915_gem_request_free(struct kref *req_ref);
> @@ -2050,9 +2054,12 @@ i915_gem_request_reference(struct drm_i915_gem_request *req)
>  static inline void
>  i915_gem_request_unreference(struct drm_i915_gem_request *req)
>  {
> +	WARN_ON(!mutex_is_locked(&req->ring->dev->struct_mutex));
>  	kref_put(&req->ref, i915_gem_request_free);
>  }
>  
> +void i915_gem_request_unreference_irq(struct drm_i915_gem_request *req);
> +
>  static inline void i915_gem_request_assign(struct drm_i915_gem_request **pdst,
>  					   struct drm_i915_gem_request *src)
>  {
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 8e2c530..b62b9d9 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -2732,6 +2732,19 @@ void i915_gem_reset(struct drm_device *dev)
>  	i915_gem_restore_fences(dev);
>  }
>  
> +void i915_gem_request_unreference_irq(struct drm_i915_gem_request *req)
> +{
> +	struct intel_engine_cs *ring = req->ring;
> +	unsigned long flags;
> +
> +	/* Need to add the req to a deferred dereference list to be processed
> +	 * outside of interrupt time */
> +	spin_lock_irqsave(&ring->reqlist_lock, flags);
> +	if (req->delay_free_count++ == 0)
> +		list_add_tail(&req->delay_free_list, &ring->delayed_free_list);
> +	spin_unlock_irqrestore(&ring->reqlist_lock, flags);
> +}
> +
>  /**
>   * This function clears the request list as sequence numbers are passed.
>   */
> @@ -2806,6 +2819,25 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
>  		ring->trace_irq_seqno = 0;
>  	}
>  
> +	while (!list_empty(&ring->delayed_free_list)) {

This needs locking. It might work as-is but it's definitely too tricky to
be worth it.
-Daniel

> +		struct drm_i915_gem_request *request;
> +		unsigned long flags;
> +		uint32_t count;
> +
> +		request = list_first_entry(&ring->delayed_free_list,
> +					   struct drm_i915_gem_request,
> +					   delay_free_list);
> +
> +		spin_lock_irqsave(&request->ring->reqlist_lock, flags);
> +		list_del(&request->delay_free_list);
> +		count = request->delay_free_count;
> +		request->delay_free_count = 0;
> +		spin_unlock_irqrestore(&request->ring->reqlist_lock, flags);
> +
> +		while (count-- > 0)
> +			i915_gem_request_unreference(request);
> +	}
> +
>  	WARN_ON(i915_verify_lists(ring->dev));
>  }
>  
> @@ -5007,6 +5039,7 @@ init_ring_lists(struct intel_engine_cs *ring)
>  {
>  	INIT_LIST_HEAD(&ring->active_list);
>  	INIT_LIST_HEAD(&ring->request_list);
> +	INIT_LIST_HEAD(&ring->delayed_free_list);
>  }
>  
>  void i915_init_vm(struct drm_i915_private *dev_priv,
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index 6177179..09f4588 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -1381,7 +1381,9 @@ static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *rin
>  	ring->dev = dev;
>  	INIT_LIST_HEAD(&ring->active_list);
>  	INIT_LIST_HEAD(&ring->request_list);
> +	spin_lock_init(&ring->reqlist_lock);
>  	init_waitqueue_head(&ring->irq_queue);
> +	INIT_LIST_HEAD(&ring->delayed_free_list);
>  
>  	INIT_LIST_HEAD(&ring->execlist_queue);
>  	INIT_LIST_HEAD(&ring->execlist_retired_req_list);
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> index b9d0d29..e3082af 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> @@ -1807,6 +1807,8 @@ static int intel_init_ring_buffer(struct drm_device *dev,
>  	ring->dev = dev;
>  	INIT_LIST_HEAD(&ring->active_list);
>  	INIT_LIST_HEAD(&ring->request_list);
> +	spin_lock_init(&ring->reqlist_lock);
> +	INIT_LIST_HEAD(&ring->delayed_free_list);
>  	INIT_LIST_HEAD(&ring->execlist_queue);
>  	ringbuf->size = 32 * PAGE_SIZE;
>  	ringbuf->ring = ring;
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
> index 2a84bd9..cd1a9f9 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
> @@ -263,6 +263,8 @@ struct  intel_engine_cs {
>  	 * outstanding.
>  	 */
>  	struct list_head request_list;
> +	spinlock_t reqlist_lock;
> +	struct list_head delayed_free_list;
>  
>  	/**
>  	 * Do we have some not yet emitted requests outstanding?
> -- 
> 1.7.9.5
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v3 12/28] drm/i915: Convert mmio_flip::seqno to struct request
  2014-11-24 18:49 ` [PATCH v3 12/28] drm/i915: Convert mmio_flip::seqno to struct request John.C.Harrison
@ 2014-11-26  9:23   ` Daniel Vetter
  2014-11-26 12:12     ` John Harrison
  0 siblings, 1 reply; 63+ messages in thread
From: Daniel Vetter @ 2014-11-26  9:23 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: Intel-GFX

On Mon, Nov 24, 2014 at 06:49:34PM +0000, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> Converted the mmio_flip 'seqno' value to be a request structure as part of the
> on going seqno to request changes. This includes reference counting the request
> being saved away to ensure it can not be retired and freed while the flip code
> is still waiting on it.
> 
> v2: Used the IRQ friendly request dereference call in the notify handler as that
> code is called asynchronously without holding any useful mutex locks.
> 
> For: VIZ-4377
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c |   20 ++++++++++----------
>  drivers/gpu/drm/i915/intel_drv.h     |    3 +--
>  2 files changed, 11 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 097e8a1..cbf3cb7 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -9550,18 +9550,19 @@ static void intel_mmio_flip_work_func(struct work_struct *work)
>  {
>  	struct intel_crtc *intel_crtc =
>  		container_of(work, struct intel_crtc, mmio_flip.work);
> -	struct intel_engine_cs *ring;
> -	uint32_t seqno;
> -
> -	seqno = intel_crtc->mmio_flip.seqno;
> -	ring = intel_crtc->mmio_flip.ring;
> +	struct intel_mmio_flip *mmio_flip;
>  
> -	if (seqno)
> -		WARN_ON(__i915_wait_seqno(ring, seqno,
> +	mmio_flip = &intel_crtc->mmio_flip;
> +	if (mmio_flip->req)
> +		WARN_ON(__i915_wait_seqno(i915_gem_request_get_ring(mmio_flip->req),
> +					  i915_gem_request_get_seqno(mmio_flip->req),
>  					  intel_crtc->reset_counter,
>  					  false, NULL, NULL) != 0);
>  
>  	intel_do_mmio_flip(intel_crtc);
> +	if (mmio_flip->req)
> +		i915_gem_request_unreference_irq(mmio_flip->req);

Can't we just grab dev->struct_mutex around here and reuse the normal
request_unref? That would allow us to ditch all the unref_irq complexity.
-Daniel

> +	mmio_flip->req = NULL;
>  }
>  
>  static int intel_queue_mmio_flip(struct drm_device *dev,
> @@ -9573,9 +9574,8 @@ static int intel_queue_mmio_flip(struct drm_device *dev,
>  {
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  
> -	intel_crtc->mmio_flip.seqno =
> -			     i915_gem_request_get_seqno(obj->last_write_req);
> -	intel_crtc->mmio_flip.ring = obj->ring;
> +	i915_gem_request_assign(&intel_crtc->mmio_flip.req,
> +				obj->last_write_req);
>  
>  	schedule_work(&intel_crtc->mmio_flip.work);
>  
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 44b153c5..2755532 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -406,8 +406,7 @@ struct intel_pipe_wm {
>  };
>  
>  struct intel_mmio_flip {
> -	u32 seqno;
> -	struct intel_engine_cs *ring;
> +	struct drm_i915_gem_request *req;
>  	struct work_struct work;
>  };
>  
> -- 
> 1.7.9.5
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v3 12/28] drm/i915: Convert mmio_flip::seqno to struct request
  2014-11-26  9:23   ` Daniel Vetter
@ 2014-11-26 12:12     ` John Harrison
  2014-11-26 12:49       ` Daniel Vetter
  0 siblings, 1 reply; 63+ messages in thread
From: John Harrison @ 2014-11-26 12:12 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Intel-GFX

On 26/11/2014 09:23, Daniel Vetter wrote:
> On Mon, Nov 24, 2014 at 06:49:34PM +0000, John.C.Harrison@Intel.com wrote:
>> From: John Harrison <John.C.Harrison@Intel.com>
>>
>> Converted the mmio_flip 'seqno' value to be a request structure as part of the
>> on going seqno to request changes. This includes reference counting the request
>> being saved away to ensure it can not be retired and freed while the flip code
>> is still waiting on it.
>>
>> v2: Used the IRQ friendly request dereference call in the notify handler as that
>> code is called asynchronously without holding any useful mutex locks.
>>
>> For: VIZ-4377
>> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
>> Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
>> ---
>>   drivers/gpu/drm/i915/intel_display.c |   20 ++++++++++----------
>>   drivers/gpu/drm/i915/intel_drv.h     |    3 +--
>>   2 files changed, 11 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index 097e8a1..cbf3cb7 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -9550,18 +9550,19 @@ static void intel_mmio_flip_work_func(struct work_struct *work)
>>   {
>>   	struct intel_crtc *intel_crtc =
>>   		container_of(work, struct intel_crtc, mmio_flip.work);
>> -	struct intel_engine_cs *ring;
>> -	uint32_t seqno;
>> -
>> -	seqno = intel_crtc->mmio_flip.seqno;
>> -	ring = intel_crtc->mmio_flip.ring;
>> +	struct intel_mmio_flip *mmio_flip;
>>   
>> -	if (seqno)
>> -		WARN_ON(__i915_wait_seqno(ring, seqno,
>> +	mmio_flip = &intel_crtc->mmio_flip;
>> +	if (mmio_flip->req)
>> +		WARN_ON(__i915_wait_seqno(i915_gem_request_get_ring(mmio_flip->req),
>> +					  i915_gem_request_get_seqno(mmio_flip->req),
>>   					  intel_crtc->reset_counter,
>>   					  false, NULL, NULL) != 0);
>>   
>>   	intel_do_mmio_flip(intel_crtc);
>> +	if (mmio_flip->req)
>> +		i915_gem_request_unreference_irq(mmio_flip->req);
> Can't we just grab dev->struct_mutex around here and reuse the normal
> request_unref? That would allow us to ditch all the unref_irq complexity.
> -Daniel
The unref_irq is needed for the flip_queued_req as that is still 
dereferenced from interrupt time. Possibly this one could now be 
downgraded to a mutex lock but before the recent rebase, the mmio_flip 
request was also being dereferenced at interrupt time so definitely 
needed the irq friendly version. Is there a worry that waiting for the 
mutex lock could stall the flip handler so long that it misses the next 
flip?

>> +	mmio_flip->req = NULL;
>>   }
>>   
>>   static int intel_queue_mmio_flip(struct drm_device *dev,
>> @@ -9573,9 +9574,8 @@ static int intel_queue_mmio_flip(struct drm_device *dev,
>>   {
>>   	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>>   
>> -	intel_crtc->mmio_flip.seqno =
>> -			     i915_gem_request_get_seqno(obj->last_write_req);
>> -	intel_crtc->mmio_flip.ring = obj->ring;
>> +	i915_gem_request_assign(&intel_crtc->mmio_flip.req,
>> +				obj->last_write_req);
>>   
>>   	schedule_work(&intel_crtc->mmio_flip.work);
>>   
>> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
>> index 44b153c5..2755532 100644
>> --- a/drivers/gpu/drm/i915/intel_drv.h
>> +++ b/drivers/gpu/drm/i915/intel_drv.h
>> @@ -406,8 +406,7 @@ struct intel_pipe_wm {
>>   };
>>   
>>   struct intel_mmio_flip {
>> -	u32 seqno;
>> -	struct intel_engine_cs *ring;
>> +	struct drm_i915_gem_request *req;
>>   	struct work_struct work;
>>   };
>>   
>> -- 
>> 1.7.9.5
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH v3 11/28] drm/i915: Add IRQ friendly request deference facility
  2014-11-26  9:19   ` Daniel Vetter
@ 2014-11-26 12:23     ` John Harrison
  2014-11-26 12:35       ` Daniel Vetter
  0 siblings, 1 reply; 63+ messages in thread
From: John Harrison @ 2014-11-26 12:23 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Intel-GFX

On 26/11/2014 09:19, Daniel Vetter wrote:
> On Mon, Nov 24, 2014 at 06:49:33PM +0000, John.C.Harrison@Intel.com wrote:
>> From: John Harrison <John.C.Harrison@Intel.com>
>>
>> The next patches in the series convert some display related seqno usage to
>> request structure usage. However, the request dereference introduced must be
>> done from interrupt context. As the dereference potentially involves freeing the
>> request structure and thus calling lots of non-interrupt friendly code, this
>> poses a problem.
>>
>> The solution is to add an IRQ friendly version of the dereference function. All
>> this does is to add the request structure to a 'delayed free' list and return.
>> The retire code, which is run periodically, then processes this list and does
>> the actual dereferencing of the request structures.
>>
>> v2: Added a count to allow for multiple IRQ dereferences of the same request at
>> a time.
>>
>> For: VIZ-4377
>> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
>> Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
>> ---
>>   drivers/gpu/drm/i915/i915_drv.h         |    7 +++++++
>>   drivers/gpu/drm/i915/i915_gem.c         |   33 +++++++++++++++++++++++++++++++
>>   drivers/gpu/drm/i915/intel_lrc.c        |    2 ++
>>   drivers/gpu/drm/i915/intel_ringbuffer.c |    2 ++
>>   drivers/gpu/drm/i915/intel_ringbuffer.h |    2 ++
>>   5 files changed, 46 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>> index 149532e6..e9b01e1 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -2025,6 +2025,10 @@ struct drm_i915_gem_request {
>>   	struct drm_i915_file_private *file_priv;
>>   	/** file_priv list entry for this request */
>>   	struct list_head client_list;
>> +
>> +	/** deferred free list for dereferencing from IRQ context */
>> +	struct list_head delay_free_list;
>> +	uint32_t delay_free_count;
>>   };
>>   
>>   void i915_gem_request_free(struct kref *req_ref);
>> @@ -2050,9 +2054,12 @@ i915_gem_request_reference(struct drm_i915_gem_request *req)
>>   static inline void
>>   i915_gem_request_unreference(struct drm_i915_gem_request *req)
>>   {
>> +	WARN_ON(!mutex_is_locked(&req->ring->dev->struct_mutex));
>>   	kref_put(&req->ref, i915_gem_request_free);
>>   }
>>   
>> +void i915_gem_request_unreference_irq(struct drm_i915_gem_request *req);
>> +
>>   static inline void i915_gem_request_assign(struct drm_i915_gem_request **pdst,
>>   					   struct drm_i915_gem_request *src)
>>   {
>> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
>> index 8e2c530..b62b9d9 100644
>> --- a/drivers/gpu/drm/i915/i915_gem.c
>> +++ b/drivers/gpu/drm/i915/i915_gem.c
>> @@ -2732,6 +2732,19 @@ void i915_gem_reset(struct drm_device *dev)
>>   	i915_gem_restore_fences(dev);
>>   }
>>   
>> +void i915_gem_request_unreference_irq(struct drm_i915_gem_request *req)
>> +{
>> +	struct intel_engine_cs *ring = req->ring;
>> +	unsigned long flags;
>> +
>> +	/* Need to add the req to a deferred dereference list to be processed
>> +	 * outside of interrupt time */
>> +	spin_lock_irqsave(&ring->reqlist_lock, flags);
>> +	if (req->delay_free_count++ == 0)
>> +		list_add_tail(&req->delay_free_list, &ring->delayed_free_list);
>> +	spin_unlock_irqrestore(&ring->reqlist_lock, flags);
>> +}
>> +
>>   /**
>>    * This function clears the request list as sequence numbers are passed.
>>    */
>> @@ -2806,6 +2819,25 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
>>   		ring->trace_irq_seqno = 0;
>>   	}
>>   
>> +	while (!list_empty(&ring->delayed_free_list)) {
> This needs locking. It might work as-is but it's definitely too tricky to
> be worth it.
> -Daniel

The manipulation of the list is locked, only this test is unlocked. Do 
you really need to lock when testing for empty? Nothing can be removing 
items from the list although something could be asynchronously adding 
them. If the 'head->next == head' test goes wrong because head or next 
is being written to, it can't deference a dodgy pointer. It can only 
return an incorrect 'empty' in which case the clean up is delayed until 
later. An incorrect 'not-empty' is not possible.


>> +		struct drm_i915_gem_request *request;
>> +		unsigned long flags;
>> +		uint32_t count;
>> +
>> +		request = list_first_entry(&ring->delayed_free_list,
>> +					   struct drm_i915_gem_request,
>> +					   delay_free_list);
>> +
>> +		spin_lock_irqsave(&request->ring->reqlist_lock, flags);
>> +		list_del(&request->delay_free_list);
>> +		count = request->delay_free_count;
>> +		request->delay_free_count = 0;
>> +		spin_unlock_irqrestore(&request->ring->reqlist_lock, flags);
>> +
>> +		while (count-- > 0)
>> +			i915_gem_request_unreference(request);
>> +	}
>> +
>>   	WARN_ON(i915_verify_lists(ring->dev));
>>   }
>>   
>> @@ -5007,6 +5039,7 @@ init_ring_lists(struct intel_engine_cs *ring)
>>   {
>>   	INIT_LIST_HEAD(&ring->active_list);
>>   	INIT_LIST_HEAD(&ring->request_list);
>> +	INIT_LIST_HEAD(&ring->delayed_free_list);
>>   }
>>   
>>   void i915_init_vm(struct drm_i915_private *dev_priv,
>> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
>> index 6177179..09f4588 100644
>> --- a/drivers/gpu/drm/i915/intel_lrc.c
>> +++ b/drivers/gpu/drm/i915/intel_lrc.c
>> @@ -1381,7 +1381,9 @@ static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *rin
>>   	ring->dev = dev;
>>   	INIT_LIST_HEAD(&ring->active_list);
>>   	INIT_LIST_HEAD(&ring->request_list);
>> +	spin_lock_init(&ring->reqlist_lock);
>>   	init_waitqueue_head(&ring->irq_queue);
>> +	INIT_LIST_HEAD(&ring->delayed_free_list);
>>   
>>   	INIT_LIST_HEAD(&ring->execlist_queue);
>>   	INIT_LIST_HEAD(&ring->execlist_retired_req_list);
>> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
>> index b9d0d29..e3082af 100644
>> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
>> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
>> @@ -1807,6 +1807,8 @@ static int intel_init_ring_buffer(struct drm_device *dev,
>>   	ring->dev = dev;
>>   	INIT_LIST_HEAD(&ring->active_list);
>>   	INIT_LIST_HEAD(&ring->request_list);
>> +	spin_lock_init(&ring->reqlist_lock);
>> +	INIT_LIST_HEAD(&ring->delayed_free_list);
>>   	INIT_LIST_HEAD(&ring->execlist_queue);
>>   	ringbuf->size = 32 * PAGE_SIZE;
>>   	ringbuf->ring = ring;
>> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
>> index 2a84bd9..cd1a9f9 100644
>> --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
>> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
>> @@ -263,6 +263,8 @@ struct  intel_engine_cs {
>>   	 * outstanding.
>>   	 */
>>   	struct list_head request_list;
>> +	spinlock_t reqlist_lock;
>> +	struct list_head delayed_free_list;
>>   
>>   	/**
>>   	 * Do we have some not yet emitted requests outstanding?
>> -- 
>> 1.7.9.5
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH v3 06/28] drm/i915: Ensure requests stick around during waits
  2014-11-24 18:49 ` [PATCH v3 06/28] drm/i915: Ensure requests stick around during waits John.C.Harrison
@ 2014-11-26 12:27   ` John Harrison
  2014-11-26 13:14     ` Daniel Vetter
  0 siblings, 1 reply; 63+ messages in thread
From: John Harrison @ 2014-11-26 12:27 UTC (permalink / raw)
  To: Intel-GFX

NB: The v3 update was to fold in a new patch for asynchronous shrinker 
shenanigans. Unfortunately, the new patch was not actually valid at this 
point in the patch series, thus this patch now breaks the build until a 
later patch in the series fixes it up again! I'll post out an updated v4 
set with the order re-worked so that it still builds and runs at each 
step along the way...


On 24/11/2014 18:49, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
>
> Added reference counting of the request structure around __wait_seqno() calls.
> This is a precursor to updating the wait code itself to take the request rather
> than a seqno. At that point, it would be a Bad Idea for a request object to be
> retired and freed while the wait code is still using it.
>
> v3:
>
> Note that even though the mutex lock is held during a call to i915_wait_seqno(),
> it is still necessary to explicitly bump the reference count. It appears that
> the shrinker can asynchronously retire items even though the mutex is locked.
>
> For: VIZ-4377
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
> ---
>   drivers/gpu/drm/i915/i915_gem.c |   28 +++++++++++++++++++++++-----
>   1 file changed, 23 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 9ac9157..71303a1 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -1333,8 +1333,11 @@ i915_wait_seqno(struct intel_engine_cs *ring, uint32_t seqno)
>   		return ret;
>   
>   	reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
> -	return __i915_wait_seqno(ring, seqno, reset_counter, interruptible,
> -				 NULL, NULL);
> +	i915_gem_request_reference(req);
> +	ret = __i915_wait_seqno(ring, seqno, reset_counter, interruptible,
> +				NULL, NULL);
> +	i915_gem_request_unreference(req);
> +	return ret;
>   }
>   
>   static int
> @@ -1417,10 +1420,12 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj,
>   		return ret;
>   
>   	reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
> +	i915_gem_request_reference(req);
>   	mutex_unlock(&dev->struct_mutex);
>   	ret = __i915_wait_seqno(ring, seqno, reset_counter, true, NULL,
>   				file_priv);
>   	mutex_lock(&dev->struct_mutex);
> +	i915_gem_request_unreference(req);
>   	if (ret)
>   		return ret;
>   
> @@ -2920,6 +2925,7 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
>   	struct drm_i915_private *dev_priv = dev->dev_private;
>   	struct drm_i915_gem_wait *args = data;
>   	struct drm_i915_gem_object *obj;
> +	struct drm_i915_gem_request *req;
>   	struct intel_engine_cs *ring = NULL;
>   	unsigned reset_counter;
>   	u32 seqno = 0;
> @@ -2946,7 +2952,8 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
>   	if (!obj->active || !obj->last_read_req)
>   		goto out;
>   
> -	seqno = i915_gem_request_get_seqno(obj->last_read_req);
> +	req = obj->last_read_req;
> +	seqno = i915_gem_request_get_seqno(req);
>   	WARN_ON(seqno == 0);
>   	ring = obj->ring;
>   
> @@ -2960,10 +2967,15 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
>   
>   	drm_gem_object_unreference(&obj->base);
>   	reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
> +	i915_gem_request_reference(req);
>   	mutex_unlock(&dev->struct_mutex);
>   
> -	return __i915_wait_seqno(ring, seqno, reset_counter, true,
> -				 &args->timeout_ns, file->driver_priv);
> +	ret = __i915_wait_seqno(ring, seqno, reset_counter, true, &args->timeout_ns,
> +			   file->driver_priv);
> +	mutex_lock(&dev->struct_mutex);
> +	i915_gem_request_unreference(req);
> +	mutex_unlock(&dev->struct_mutex);
> +	return ret;
>   
>   out:
>   	drm_gem_object_unreference(&obj->base);
> @@ -4122,6 +4134,8 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file)
>   		target = request;
>   	}
>   	reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
> +	if (target)
> +		i915_gem_request_reference(target);
>   	spin_unlock(&file_priv->mm.lock);
>   
>   	if (target == NULL)
> @@ -4133,6 +4147,10 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file)
>   	if (ret == 0)
>   		queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0);
>   
> +	mutex_lock(&dev->struct_mutex);
> +	i915_gem_request_unreference(target);
> +	mutex_unlock(&dev->struct_mutex);
> +
>   	return ret;
>   }
>   

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

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

* Re: [PATCH v3 11/28] drm/i915: Add IRQ friendly request deference facility
  2014-11-26 12:23     ` John Harrison
@ 2014-11-26 12:35       ` Daniel Vetter
  0 siblings, 0 replies; 63+ messages in thread
From: Daniel Vetter @ 2014-11-26 12:35 UTC (permalink / raw)
  To: John Harrison; +Cc: intel-gfx

On Wed, Nov 26, 2014 at 1:23 PM, John Harrison
<John.C.Harrison@intel.com> wrote:
>> This needs locking. It might work as-is but it's definitely too tricky to
>> be worth it.
>
> The manipulation of the list is locked, only this test is unlocked. Do you
> really need to lock when testing for empty? Nothing can be removing items
> from the list although something could be asynchronously adding them. If the
> 'head->next == head' test goes wrong because head or next is being written
> to, it can't deference a dodgy pointer. It can only return an incorrect
> 'empty' in which case the clean up is delayed until later. An incorrect
> 'not-empty' is not possible.

The problem is not that it's broken but too tricky. And nothing in
either the commit message nor a code commit explains and justifies
this. Of course every time I stumble over this I can think hard for a
while and convince myself that it works, but GEM is already littered
with such inherent complexity, so adding accidental complexity for
locking tricks when they're not needed is a bad move.

Since we don't actually need this in current code I'll drop it.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v3 12/28] drm/i915: Convert mmio_flip::seqno to struct request
  2014-11-26 12:12     ` John Harrison
@ 2014-11-26 12:49       ` Daniel Vetter
  2014-11-26 15:21         ` John Harrison
  0 siblings, 1 reply; 63+ messages in thread
From: Daniel Vetter @ 2014-11-26 12:49 UTC (permalink / raw)
  To: John Harrison; +Cc: intel-gfx

On Wed, Nov 26, 2014 at 1:12 PM, John Harrison
<John.C.Harrison@intel.com> wrote:
> The unref_irq is needed for the flip_queued_req as that is still
> dereferenced from interrupt time. Possibly this one could now be downgraded
> to a mutex lock but before the recent rebase, the mmio_flip request was also
> being dereferenced at interrupt time so definitely needed the irq friendly
> version. Is there a worry that waiting for the mutex lock could stall the
> flip handler so long that it misses the next flip?

Yup this is only possible very recently. I've simply dropped the _irq
and wrapped with struct_mutex locking, but a lockless unref (which
only grabs the lock on the final kput in the free function) like Chris
suggested would indeed be tidier.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v3 15/28] drm/i915: Convert 'flip_queued_seqno' into 'flip_queued_request'
  2014-11-24 18:49 ` [PATCH v3 15/28] drm/i915: Convert 'flip_queued_seqno' into 'flip_queued_request' John.C.Harrison
@ 2014-11-26 13:07   ` Daniel Vetter
  0 siblings, 0 replies; 63+ messages in thread
From: Daniel Vetter @ 2014-11-26 13:07 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: Intel-GFX

On Mon, Nov 24, 2014 at 06:49:37PM +0000, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> Converted the flip_queued_seqno value to be a request structure as part of the
> on going seqno to request changes. This includes reference counting the request
> being saved away to ensure it can not be retired and freed while the flip code
> is still waiting on it.
> 
> For: VIZ-4377
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_debugfs.c  |    4 ++--
>  drivers/gpu/drm/i915/intel_display.c |   24 ++++++++++++++++--------
>  drivers/gpu/drm/i915/intel_drv.h     |    2 +-
>  3 files changed, 19 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 2720eb5..bc9b1c8 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -546,11 +546,11 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data)
>  			if (work->flip_queued_ring) {
>  				seq_printf(m, "Flip queued on %s at seqno %u, next seqno %u [current breadcrumb %u], completed? %d\n",
>  					   work->flip_queued_ring->name,
> -					   work->flip_queued_seqno,
> +					   i915_gem_request_get_seqno(work->flip_queued_req),
>  					   dev_priv->next_seqno,
>  					   work->flip_queued_ring->get_seqno(work->flip_queued_ring, true),
>  					   i915_seqno_passed(work->flip_queued_ring->get_seqno(work->flip_queued_ring, true),
> -							     work->flip_queued_seqno));
> +							     i915_gem_request_get_seqno(work->flip_queued_req)));
>  			} else
>  				seq_printf(m, "Flip not associated with any ring\n");
>  			seq_printf(m, "Flip queued on frame %d, (was ready on frame %d), now %d\n",
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 98a5ed0..4a801e4 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -9669,10 +9669,18 @@ static bool __intel_pageflip_stall_check(struct drm_device *dev,
>  		return false;
>  
>  	if (work->flip_ready_vblank == 0) {
> -		if (work->flip_queued_ring &&
> -		    !i915_seqno_passed(work->flip_queued_ring->get_seqno(work->flip_queued_ring, true),
> -				       work->flip_queued_seqno))
> -			return false;
> +		if (work->flip_queued_ring) {
> +			uint32_t s1 = work->flip_queued_ring->get_seqno(
> +					       work->flip_queued_ring, true);
> +			uint32_t s2 = i915_gem_request_get_seqno(
> +						      work->flip_queued_req);
> +			if (!i915_seqno_passed(s1, s2))
> +				return false;
> +
> +			i915_gem_request_unreference_irq(work->flip_queued_req);
> +			work->flip_queued_req  = NULL;
> +			work->flip_queued_ring = NULL;

Ok, here's the next one. I've fixed this up with


diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 1df3387af59b..c8eb109acc3b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9122,6 +9122,11 @@ static void intel_unpin_work_fn(struct work_struct *__work)
 	drm_gem_object_unreference(&work->old_fb_obj->base);
 
 	intel_update_fbc(dev);
+
+	if (work->flip_queued_req)
+		i915_gem_request_unreference_irq(work->flip_queued_req);
+	work->flip_queued_req  = NULL;
+	work->flip_queued_ring = NULL;
 	mutex_unlock(&dev->struct_mutex);
 
 	intel_frontbuffer_flip_complete(dev, INTEL_FRONTBUFFER_PRIMARY(pipe));
@@ -9733,10 +9738,6 @@ static bool __intel_pageflip_stall_check(struct drm_device *dev,
 						      work->flip_queued_req);
 			if (!i915_seqno_passed(s1, s2))
 				return false;
-
-			i915_gem_request_unreference_irq(work->flip_queued_req);
-			work->flip_queued_req  = NULL;
-			work->flip_queued_ring = NULL;
 		}
 
 		work->flip_ready_vblank = drm_vblank_count(dev, intel_crtc->pipe);
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v3 06/28] drm/i915: Ensure requests stick around during waits
  2014-11-26 12:27   ` John Harrison
@ 2014-11-26 13:14     ` Daniel Vetter
  0 siblings, 0 replies; 63+ messages in thread
From: Daniel Vetter @ 2014-11-26 13:14 UTC (permalink / raw)
  To: John Harrison; +Cc: Intel-GFX

On Wed, Nov 26, 2014 at 12:27:07PM +0000, John Harrison wrote:
> NB: The v3 update was to fold in a new patch for asynchronous shrinker
> shenanigans. Unfortunately, the new patch was not actually valid at this
> point in the patch series, thus this patch now breaks the build until a
> later patch in the series fixes it up again! I'll post out an updated v4 set
> with the order re-worked so that it still builds and runs at each step along
> the way...

Please don't, I already have your series partially merged. In general
never repost the entire series while discussions are ongoing, it makes a
big mess out of the threads on the m-l.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v3 17/28] drm/i915: Convert 'trace_irq' to use requests rather than seqnos
  2014-11-24 18:49 ` [PATCH v3 17/28] drm/i915: Convert 'trace_irq' to use requests rather than seqnos John.C.Harrison
@ 2014-11-26 13:24   ` Daniel Vetter
  2014-11-26 14:12     ` John Harrison
  0 siblings, 1 reply; 63+ messages in thread
From: Daniel Vetter @ 2014-11-26 13:24 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: Intel-GFX

On Mon, Nov 24, 2014 at 06:49:39PM +0000, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> Updated the trace_irq code to use requests instead of seqnos. This includes
> reference counting the request object to ensure it sticks around when required.
> Note that getting access to the reference counting functions means moving the
> inline i915_trace_irq_get() function from intel_ringbuffer.h to i915_drv.h.
> 
> For: VIZ-4377
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h         |    7 +++++++
>  drivers/gpu/drm/i915/i915_gem.c         |    7 ++++---
>  drivers/gpu/drm/i915/i915_trace.h       |    2 +-
>  drivers/gpu/drm/i915/intel_ringbuffer.h |    8 +-------
>  4 files changed, 13 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 8bfdac6..831fae2 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -3130,4 +3130,11 @@ wait_remaining_ms_from_jiffies(unsigned long timestamp_jiffies, int to_wait_ms)
>  	}
>  }
>  
> +static inline void i915_trace_irq_get(struct intel_engine_cs *ring,
> +				      struct drm_i915_gem_request *req)
> +{
> +	if (ring->trace_irq_req == NULL && ring->irq_get(ring))
> +		i915_gem_request_assign(&ring->trace_irq_req, req);

This looks a bit suspiciuos. Thus far ring->trace_irq_req was essentially
ot protected at all by anything. But that was nothing troublesome since we
didn't hang a real resource of it.

But now there's a refcounted request in that pointer, which means if we
race we leak. I'll skip this patch for now.
-Daniel

> +}
> +
>  #endif
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 69c3e50..69bddcb 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -2810,10 +2810,11 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
>  		i915_gem_free_request(request);
>  	}
>  
> -	if (unlikely(ring->trace_irq_seqno &&
> -		     i915_seqno_passed(seqno, ring->trace_irq_seqno))) {
> +	if (unlikely(ring->trace_irq_req &&
> +		     i915_seqno_passed(seqno,
> +			 i915_gem_request_get_seqno(ring->trace_irq_req)))) {
>  		ring->irq_put(ring);
> -		ring->trace_irq_seqno = 0;
> +		i915_gem_request_assign(&ring->trace_irq_req, NULL);
>  	}
>  
>  	while (!list_empty(&ring->delayed_free_list)) {
> diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h
> index 2c0327b..2ade958 100644
> --- a/drivers/gpu/drm/i915/i915_trace.h
> +++ b/drivers/gpu/drm/i915/i915_trace.h
> @@ -369,7 +369,7 @@ TRACE_EVENT(i915_gem_ring_dispatch,
>  			   __entry->ring = ring->id;
>  			   __entry->seqno = i915_gem_request_get_seqno(req);
>  			   __entry->flags = flags;
> -			   i915_trace_irq_get(ring, __entry->seqno);
> +			   i915_trace_irq_get(ring, req);
>  			   ),
>  
>  	    TP_printk("dev=%u, ring=%u, seqno=%u, flags=%x",
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
> index cd1a9f9..c8b84de 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
> @@ -142,7 +142,7 @@ struct  intel_engine_cs {
>  
>  	unsigned irq_refcount; /* protected by dev_priv->irq_lock */
>  	u32		irq_enable_mask;	/* bitmask to enable ring interrupt */
> -	u32		trace_irq_seqno;
> +	struct drm_i915_gem_request *trace_irq_req;
>  	bool __must_check (*irq_get)(struct intel_engine_cs *ring);
>  	void		(*irq_put)(struct intel_engine_cs *ring);
>  
> @@ -444,10 +444,4 @@ intel_ring_get_request(struct intel_engine_cs *ring)
>  	return ring->outstanding_lazy_request;
>  }
>  
> -static inline void i915_trace_irq_get(struct intel_engine_cs *ring, u32 seqno)
> -{
> -	if (ring->trace_irq_seqno == 0 && ring->irq_get(ring))
> -		ring->trace_irq_seqno = seqno;
> -}
> -
>  #endif /* _INTEL_RINGBUFFER_H_ */
> -- 
> 1.7.9.5
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v3 20/28] drm/i915: Convert 'i915_seqno_passed' calls into 'i915_gem_request_completed'
  2014-11-24 18:49 ` [PATCH v3 20/28] drm/i915: Convert 'i915_seqno_passed' calls into 'i915_gem_request_completed' John.C.Harrison
@ 2014-11-26 13:42   ` Daniel Vetter
  0 siblings, 0 replies; 63+ messages in thread
From: Daniel Vetter @ 2014-11-26 13:42 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: Intel-GFX

On Mon, Nov 24, 2014 at 06:49:42PM +0000, John.C.Harrison@Intel.com wrote:
> @@ -2767,8 +2757,7 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
>  				      struct drm_i915_gem_object,
>  				      ring_list);
>  
> -		if (!i915_seqno_passed(seqno,
> -			     i915_gem_request_get_seqno(obj->last_read_req)))
> +		if (!i915_gem_request_completed(obj->last_read_req, true))
>  			break;
>  
>  		i915_gem_object_move_to_inactive(obj);
> @@ -2783,7 +2772,7 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
>  					   struct drm_i915_gem_request,
>  					   list);
>  
> -		if (!i915_seqno_passed(seqno, request->seqno))
> +		if (!i915_gem_request_completed(request, true))
>  			break;
>  
>  		trace_i915_gem_request_retire(request);
> @@ -2810,8 +2799,7 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
>  	}
>  
>  	if (unlikely(ring->trace_irq_req &&
> -		     i915_seqno_passed(seqno,
> -			 i915_gem_request_get_seqno(ring->trace_irq_req)))) {
> +		     i915_gem_request_completed(ring->trace_irq_req, true))) {

I've had to drop this hunk since I've dropped the preceeding patch too.
And a little fumbling to directly call ring->get_seqno.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v3 21/28] drm/i915: Remove the now redundant 'obj->ring'
  2014-11-24 18:49 ` [PATCH v3 21/28] drm/i915: Remove the now redundant 'obj->ring' John.C.Harrison
@ 2014-11-26 13:43   ` Daniel Vetter
  2014-11-28 17:49     ` John Harrison
  0 siblings, 1 reply; 63+ messages in thread
From: Daniel Vetter @ 2014-11-26 13:43 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: Intel-GFX

On Mon, Nov 24, 2014 at 06:49:43PM +0000, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> The ring member of the object structure was always updated with the
> last_read_seqno member. Thus with the conversion to last_read_req, obj->ring is
> now a direct copy of obj->last_read_req->ring. This makes it somewhat redundant
> and potentially misleading (especially as there was no comment to explain its
> purpose).
> 
> This checkin removes the redundant field. Many uses were simply testing for
> non-null to see if the object is active on the GPU. Some of these have been
> converted to check 'obj->active' instead. Others (where the last_read_req is
> about to be used anyway) have been changed to check obj->last_read_req. The rest
> simply pull the ring out from the request structure and proceed as before.
> 
> For: VIZ-4377
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>

Ok merged up to this for now. I'd like to settle things a bit first (and
also figure out what to do with the trace_irq stuff).

Thanks for patches&review,
Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v3 17/28] drm/i915: Convert 'trace_irq' to use requests rather than seqnos
  2014-11-26 13:24   ` Daniel Vetter
@ 2014-11-26 14:12     ` John Harrison
  2014-11-26 14:31       ` Chris Wilson
  2014-11-26 14:42       ` Daniel Vetter
  0 siblings, 2 replies; 63+ messages in thread
From: John Harrison @ 2014-11-26 14:12 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Intel-GFX

On 26/11/2014 13:24, Daniel Vetter wrote:
> On Mon, Nov 24, 2014 at 06:49:39PM +0000, John.C.Harrison@Intel.com wrote:
>> From: John Harrison <John.C.Harrison@Intel.com>
>>
>> Updated the trace_irq code to use requests instead of seqnos. This includes
>> reference counting the request object to ensure it sticks around when required.
>> Note that getting access to the reference counting functions means moving the
>> inline i915_trace_irq_get() function from intel_ringbuffer.h to i915_drv.h.
>>
>> For: VIZ-4377
>> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
>> Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
>> ---
>>   drivers/gpu/drm/i915/i915_drv.h         |    7 +++++++
>>   drivers/gpu/drm/i915/i915_gem.c         |    7 ++++---
>>   drivers/gpu/drm/i915/i915_trace.h       |    2 +-
>>   drivers/gpu/drm/i915/intel_ringbuffer.h |    8 +-------
>>   4 files changed, 13 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>> index 8bfdac6..831fae2 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -3130,4 +3130,11 @@ wait_remaining_ms_from_jiffies(unsigned long timestamp_jiffies, int to_wait_ms)
>>   	}
>>   }
>>   
>> +static inline void i915_trace_irq_get(struct intel_engine_cs *ring,
>> +				      struct drm_i915_gem_request *req)
>> +{
>> +	if (ring->trace_irq_req == NULL && ring->irq_get(ring))
>> +		i915_gem_request_assign(&ring->trace_irq_req, req);
> This looks a bit suspiciuos. Thus far ring->trace_irq_req was essentially
> ot protected at all by anything. But that was nothing troublesome since we
> didn't hang a real resource of it.
>
> But now there's a refcounted request in that pointer, which means if we
> race we leak. I'll skip this patch for now.
> -Daniel

Race how? The assignment only ever occurs from inside execbuffer 
submission at which point the driver mutex lock is held. Therefore it is 
very definitely protected. Not doing the reference count means that 
there is now the possibility of a dangling pointer and thus the 
possibility of going bang with a kernel oops.

>
>> +}
>> +
>>   #endif
>> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
>> index 69c3e50..69bddcb 100644
>> --- a/drivers/gpu/drm/i915/i915_gem.c
>> +++ b/drivers/gpu/drm/i915/i915_gem.c
>> @@ -2810,10 +2810,11 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
>>   		i915_gem_free_request(request);
>>   	}
>>   
>> -	if (unlikely(ring->trace_irq_seqno &&
>> -		     i915_seqno_passed(seqno, ring->trace_irq_seqno))) {
>> +	if (unlikely(ring->trace_irq_req &&
>> +		     i915_seqno_passed(seqno,
>> +			 i915_gem_request_get_seqno(ring->trace_irq_req)))) {
>>   		ring->irq_put(ring);
>> -		ring->trace_irq_seqno = 0;
>> +		i915_gem_request_assign(&ring->trace_irq_req, NULL);
>>   	}
>>   
>>   	while (!list_empty(&ring->delayed_free_list)) {
>> diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h
>> index 2c0327b..2ade958 100644
>> --- a/drivers/gpu/drm/i915/i915_trace.h
>> +++ b/drivers/gpu/drm/i915/i915_trace.h
>> @@ -369,7 +369,7 @@ TRACE_EVENT(i915_gem_ring_dispatch,
>>   			   __entry->ring = ring->id;
>>   			   __entry->seqno = i915_gem_request_get_seqno(req);
>>   			   __entry->flags = flags;
>> -			   i915_trace_irq_get(ring, __entry->seqno);
>> +			   i915_trace_irq_get(ring, req);
>>   			   ),
>>   
>>   	    TP_printk("dev=%u, ring=%u, seqno=%u, flags=%x",
>> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
>> index cd1a9f9..c8b84de 100644
>> --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
>> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
>> @@ -142,7 +142,7 @@ struct  intel_engine_cs {
>>   
>>   	unsigned irq_refcount; /* protected by dev_priv->irq_lock */
>>   	u32		irq_enable_mask;	/* bitmask to enable ring interrupt */
>> -	u32		trace_irq_seqno;
>> +	struct drm_i915_gem_request *trace_irq_req;
>>   	bool __must_check (*irq_get)(struct intel_engine_cs *ring);
>>   	void		(*irq_put)(struct intel_engine_cs *ring);
>>   
>> @@ -444,10 +444,4 @@ intel_ring_get_request(struct intel_engine_cs *ring)
>>   	return ring->outstanding_lazy_request;
>>   }
>>   
>> -static inline void i915_trace_irq_get(struct intel_engine_cs *ring, u32 seqno)
>> -{
>> -	if (ring->trace_irq_seqno == 0 && ring->irq_get(ring))
>> -		ring->trace_irq_seqno = seqno;
>> -}
>> -
>>   #endif /* _INTEL_RINGBUFFER_H_ */
>> -- 
>> 1.7.9.5
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [PATCH v3 17/28] drm/i915: Convert 'trace_irq' to use requests rather than seqnos
  2014-11-26 14:12     ` John Harrison
@ 2014-11-26 14:31       ` Chris Wilson
  2014-11-26 14:42       ` Daniel Vetter
  1 sibling, 0 replies; 63+ messages in thread
From: Chris Wilson @ 2014-11-26 14:31 UTC (permalink / raw)
  To: John Harrison; +Cc: Intel-GFX

On Wed, Nov 26, 2014 at 02:12:53PM +0000, John Harrison wrote:
> On 26/11/2014 13:24, Daniel Vetter wrote:
> >On Mon, Nov 24, 2014 at 06:49:39PM +0000, John.C.Harrison@Intel.com wrote:
> >>From: John Harrison <John.C.Harrison@Intel.com>
> >>
> >>Updated the trace_irq code to use requests instead of seqnos. This includes
> >>reference counting the request object to ensure it sticks around when required.
> >>Note that getting access to the reference counting functions means moving the
> >>inline i915_trace_irq_get() function from intel_ringbuffer.h to i915_drv.h.
> >>
> >>For: VIZ-4377
> >>Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> >>Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
> >>---
> >>  drivers/gpu/drm/i915/i915_drv.h         |    7 +++++++
> >>  drivers/gpu/drm/i915/i915_gem.c         |    7 ++++---
> >>  drivers/gpu/drm/i915/i915_trace.h       |    2 +-
> >>  drivers/gpu/drm/i915/intel_ringbuffer.h |    8 +-------
> >>  4 files changed, 13 insertions(+), 11 deletions(-)
> >>
> >>diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> >>index 8bfdac6..831fae2 100644
> >>--- a/drivers/gpu/drm/i915/i915_drv.h
> >>+++ b/drivers/gpu/drm/i915/i915_drv.h
> >>@@ -3130,4 +3130,11 @@ wait_remaining_ms_from_jiffies(unsigned long timestamp_jiffies, int to_wait_ms)
> >>  	}
> >>  }
> >>+static inline void i915_trace_irq_get(struct intel_engine_cs *ring,
> >>+				      struct drm_i915_gem_request *req)
> >>+{
> >>+	if (ring->trace_irq_req == NULL && ring->irq_get(ring))
> >>+		i915_gem_request_assign(&ring->trace_irq_req, req);
> >This looks a bit suspiciuos. Thus far ring->trace_irq_req was essentially
> >ot protected at all by anything. But that was nothing troublesome since we
> >didn't hang a real resource of it.
> >
> >But now there's a refcounted request in that pointer, which means if we
> >race we leak. I'll skip this patch for now.
> >-Daniel
> 
> Race how? The assignment only ever occurs from inside execbuffer
> submission at which point the driver mutex lock is held. Therefore
> it is very definitely protected. Not doing the reference count means
> that there is now the possibility of a dangling pointer and thus the
> possibility of going bang with a kernel oops.

It's suspicious because the code is broken and you didn't read my patch.
 
> >
> >>+}
> >>+
> >>  #endif
> >>diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> >>index 69c3e50..69bddcb 100644
> >>--- a/drivers/gpu/drm/i915/i915_gem.c
> >>+++ b/drivers/gpu/drm/i915/i915_gem.c
> >>@@ -2810,10 +2810,11 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
> >>  		i915_gem_free_request(request);
> >>  	}
> >>-	if (unlikely(ring->trace_irq_seqno &&
> >>-		     i915_seqno_passed(seqno, ring->trace_irq_seqno))) {
> >>+	if (unlikely(ring->trace_irq_req &&
> >>+		     i915_seqno_passed(seqno,
> >>+			 i915_gem_request_get_seqno(ring->trace_irq_req)))) {

It simply does not need transitioning to requests.
-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] 63+ messages in thread

* Re: [PATCH v3 17/28] drm/i915: Convert 'trace_irq' to use requests rather than seqnos
  2014-11-26 14:12     ` John Harrison
  2014-11-26 14:31       ` Chris Wilson
@ 2014-11-26 14:42       ` Daniel Vetter
  2014-11-26 14:58         ` John Harrison
  1 sibling, 1 reply; 63+ messages in thread
From: Daniel Vetter @ 2014-11-26 14:42 UTC (permalink / raw)
  To: John Harrison; +Cc: intel-gfx

On Wed, Nov 26, 2014 at 3:12 PM, John Harrison
<John.C.Harrison@intel.com> wrote:
>>> diff --git a/drivers/gpu/drm/i915/i915_drv.h
>>> b/drivers/gpu/drm/i915/i915_drv.h
>>> index 8bfdac6..831fae2 100644
>>> --- a/drivers/gpu/drm/i915/i915_drv.h
>>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>>> @@ -3130,4 +3130,11 @@ wait_remaining_ms_from_jiffies(unsigned long
>>> timestamp_jiffies, int to_wait_ms)
>>>         }
>>>   }
>>>   +static inline void i915_trace_irq_get(struct intel_engine_cs *ring,
>>> +                                     struct drm_i915_gem_request *req)
>>> +{
>>> +       if (ring->trace_irq_req == NULL && ring->irq_get(ring))
>>> +               i915_gem_request_assign(&ring->trace_irq_req, req);
>>
>> This looks a bit suspiciuos. Thus far ring->trace_irq_req was essentially
>> ot protected at all by anything. But that was nothing troublesome since we
>> didn't hang a real resource of it.
>>
>> But now there's a refcounted request in that pointer, which means if we
>> race we leak. I'll skip this patch for now.
>> -Daniel
>
>
> Race how? The assignment only ever occurs from inside execbuffer submission
> at which point the driver mutex lock is held. Therefore it is very
> definitely protected. Not doing the reference count means that there is now
> the possibility of a dangling pointer and thus the possibility of going bang
> with a kernel oops.

Hm, ->trace_irq_seqno is indeed always touched from the a calling
context with dev->struct_mutex held. Somehow I've misrembered that
since the realtime/tracing folks are really freaked out about what
we're doing here. But from that pov your patch doesn't really make
things worse, so I'll pull it in.

Btw I don't see the oops really without this patch. What would blow up?
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v3 17/28] drm/i915: Convert 'trace_irq' to use requests rather than seqnos
  2014-11-26 14:42       ` Daniel Vetter
@ 2014-11-26 14:58         ` John Harrison
  2014-11-26 18:23           ` Daniel Vetter
  0 siblings, 1 reply; 63+ messages in thread
From: John Harrison @ 2014-11-26 14:58 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On 26/11/2014 14:42, Daniel Vetter wrote:
> On Wed, Nov 26, 2014 at 3:12 PM, John Harrison
> <John.C.Harrison@intel.com> wrote:
>>>> diff --git a/drivers/gpu/drm/i915/i915_drv.h
>>>> b/drivers/gpu/drm/i915/i915_drv.h
>>>> index 8bfdac6..831fae2 100644
>>>> --- a/drivers/gpu/drm/i915/i915_drv.h
>>>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>>>> @@ -3130,4 +3130,11 @@ wait_remaining_ms_from_jiffies(unsigned long
>>>> timestamp_jiffies, int to_wait_ms)
>>>>          }
>>>>    }
>>>>    +static inline void i915_trace_irq_get(struct intel_engine_cs *ring,
>>>> +                                     struct drm_i915_gem_request *req)
>>>> +{
>>>> +       if (ring->trace_irq_req == NULL && ring->irq_get(ring))
>>>> +               i915_gem_request_assign(&ring->trace_irq_req, req);
>>> This looks a bit suspiciuos. Thus far ring->trace_irq_req was essentially
>>> ot protected at all by anything. But that was nothing troublesome since we
>>> didn't hang a real resource of it.
>>>
>>> But now there's a refcounted request in that pointer, which means if we
>>> race we leak. I'll skip this patch for now.
>>> -Daniel
>>
>> Race how? The assignment only ever occurs from inside execbuffer submission
>> at which point the driver mutex lock is held. Therefore it is very
>> definitely protected. Not doing the reference count means that there is now
>> the possibility of a dangling pointer and thus the possibility of going bang
>> with a kernel oops.
> Hm, ->trace_irq_seqno is indeed always touched from the a calling
> context with dev->struct_mutex held. Somehow I've misrembered that
> since the realtime/tracing folks are really freaked out about what
> we're doing here. But from that pov your patch doesn't really make
> things worse, so I'll pull it in.
>
> Btw I don't see the oops really without this patch. What would blow up?
> -Daniel

The sole access (and clear to null) of the trace pointer is done from 
retire requests after the requests have been retired. Thus the request 
structure could have just been freed immediately before it is used. The 
code could be re-ordered to be safer but I'm not entirely sure what the 
trace pointer is for or what it might potentially be used for in the 
future. With the reference counting, the ordering is irrelevant. If the 
pointer exists then it is safe to use.

The point is that anywhere that keeps a copy of a request pointer really 
should reference count that copy. Otherwise there is the possibility 
that the pointer could become stale. Either now or with future code 
changes. If the copy is always done with the request_assign() function 
then the pointer is guaranteed safe for all time.

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

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

* Re: [PATCH v3 12/28] drm/i915: Convert mmio_flip::seqno to struct request
  2014-11-26 12:49       ` Daniel Vetter
@ 2014-11-26 15:21         ` John Harrison
  2014-11-26 18:22           ` Daniel Vetter
  0 siblings, 1 reply; 63+ messages in thread
From: John Harrison @ 2014-11-26 15:21 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On 26/11/2014 12:49, Daniel Vetter wrote:
> On Wed, Nov 26, 2014 at 1:12 PM, John Harrison
> <John.C.Harrison@intel.com> wrote:
>> The unref_irq is needed for the flip_queued_req as that is still
>> dereferenced from interrupt time. Possibly this one could now be downgraded
>> to a mutex lock but before the recent rebase, the mmio_flip request was also
>> being dereferenced at interrupt time so definitely needed the irq friendly
>> version. Is there a worry that waiting for the mutex lock could stall the
>> flip handler so long that it misses the next flip?
> Yup this is only possible very recently. I've simply dropped the _irq
> and wrapped with struct_mutex locking, but a lockless unref (which
> only grabs the lock on the final kput in the free function) like Chris
> suggested would indeed be tidier.
> -Daniel

A lockless unref only works if you can guarantee never to call it when 
you are holding the last reference. And that is something that is 
extremely difficult to prove in advance. Just because the flip code 
usually releases its reference before the request has been retired does 
not mean that it always will. I have definitely seen it occur the other 
way around in my testing.

Having a 'lockless' unref that can acquire the mutex lock internally is 
not much use when you are needing to call it from code that cannot lock 
(e.g. an interrupt handler). In that context, the free must be deferred 
until a later time.

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

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

* Re: [PATCH v3 12/28] drm/i915: Convert mmio_flip::seqno to struct request
  2014-11-26 15:21         ` John Harrison
@ 2014-11-26 18:22           ` Daniel Vetter
  0 siblings, 0 replies; 63+ messages in thread
From: Daniel Vetter @ 2014-11-26 18:22 UTC (permalink / raw)
  To: John Harrison; +Cc: intel-gfx

On Wed, Nov 26, 2014 at 03:21:30PM +0000, John Harrison wrote:
> On 26/11/2014 12:49, Daniel Vetter wrote:
> >On Wed, Nov 26, 2014 at 1:12 PM, John Harrison
> ><John.C.Harrison@intel.com> wrote:
> >>The unref_irq is needed for the flip_queued_req as that is still
> >>dereferenced from interrupt time. Possibly this one could now be downgraded
> >>to a mutex lock but before the recent rebase, the mmio_flip request was also
> >>being dereferenced at interrupt time so definitely needed the irq friendly
> >>version. Is there a worry that waiting for the mutex lock could stall the
> >>flip handler so long that it misses the next flip?
> >Yup this is only possible very recently. I've simply dropped the _irq
> >and wrapped with struct_mutex locking, but a lockless unref (which
> >only grabs the lock on the final kput in the free function) like Chris
> >suggested would indeed be tidier.
> >-Daniel
> 
> A lockless unref only works if you can guarantee never to call it when you
> are holding the last reference. And that is something that is extremely
> difficult to prove in advance. Just because the flip code usually releases
> its reference before the request has been retired does not mean that it
> always will. I have definitely seen it occur the other way around in my
> testing.
> 
> Having a 'lockless' unref that can acquire the mutex lock internally is not
> much use when you are needing to call it from code that cannot lock (e.g. an
> interrupt handler). In that context, the free must be deferred until a later
> time.

The idea is to implement something like
drm_gem_object_unreference_unlocked. It would be mostly for code tideness
and self-documentation really. That it avoids a needless mutex grabbing
cycle is just a free bonus.

And yeah still forbidden to call this from irq contexts or anything else
nasty.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v3 17/28] drm/i915: Convert 'trace_irq' to use requests rather than seqnos
  2014-11-26 14:58         ` John Harrison
@ 2014-11-26 18:23           ` Daniel Vetter
  2014-11-26 18:25             ` Daniel Vetter
  0 siblings, 1 reply; 63+ messages in thread
From: Daniel Vetter @ 2014-11-26 18:23 UTC (permalink / raw)
  To: John Harrison; +Cc: intel-gfx

On Wed, Nov 26, 2014 at 02:58:49PM +0000, John Harrison wrote:
> On 26/11/2014 14:42, Daniel Vetter wrote:
> >On Wed, Nov 26, 2014 at 3:12 PM, John Harrison
> ><John.C.Harrison@intel.com> wrote:
> >>>>diff --git a/drivers/gpu/drm/i915/i915_drv.h
> >>>>b/drivers/gpu/drm/i915/i915_drv.h
> >>>>index 8bfdac6..831fae2 100644
> >>>>--- a/drivers/gpu/drm/i915/i915_drv.h
> >>>>+++ b/drivers/gpu/drm/i915/i915_drv.h
> >>>>@@ -3130,4 +3130,11 @@ wait_remaining_ms_from_jiffies(unsigned long
> >>>>timestamp_jiffies, int to_wait_ms)
> >>>>         }
> >>>>   }
> >>>>   +static inline void i915_trace_irq_get(struct intel_engine_cs *ring,
> >>>>+                                     struct drm_i915_gem_request *req)
> >>>>+{
> >>>>+       if (ring->trace_irq_req == NULL && ring->irq_get(ring))
> >>>>+               i915_gem_request_assign(&ring->trace_irq_req, req);
> >>>This looks a bit suspiciuos. Thus far ring->trace_irq_req was essentially
> >>>ot protected at all by anything. But that was nothing troublesome since we
> >>>didn't hang a real resource of it.
> >>>
> >>>But now there's a refcounted request in that pointer, which means if we
> >>>race we leak. I'll skip this patch for now.
> >>>-Daniel
> >>
> >>Race how? The assignment only ever occurs from inside execbuffer submission
> >>at which point the driver mutex lock is held. Therefore it is very
> >>definitely protected. Not doing the reference count means that there is now
> >>the possibility of a dangling pointer and thus the possibility of going bang
> >>with a kernel oops.
> >Hm, ->trace_irq_seqno is indeed always touched from the a calling
> >context with dev->struct_mutex held. Somehow I've misrembered that
> >since the realtime/tracing folks are really freaked out about what
> >we're doing here. But from that pov your patch doesn't really make
> >things worse, so I'll pull it in.
> >
> >Btw I don't see the oops really without this patch. What would blow up?
> >-Daniel
> 
> The sole access (and clear to null) of the trace pointer is done from retire
> requests after the requests have been retired. Thus the request structure
> could have just been freed immediately before it is used. The code could be
> re-ordered to be safer but I'm not entirely sure what the trace pointer is
> for or what it might potentially be used for in the future. With the
> reference counting, the ordering is irrelevant. If the pointer exists then
> it is safe to use.
> 
> The point is that anywhere that keeps a copy of a request pointer really
> should reference count that copy. Otherwise there is the possibility that
> the pointer could become stale. Either now or with future code changes. If
> the copy is always done with the request_assign() function then the pointer
> is guaranteed safe for all time.

Oh, I guess you've misunderstood what I've done. Ive dropped the entire
patch here, not just the refcounting. Dropping the refcounting alone is
obviously oops-worthy.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v3 17/28] drm/i915: Convert 'trace_irq' to use requests rather than seqnos
  2014-11-26 18:23           ` Daniel Vetter
@ 2014-11-26 18:25             ` Daniel Vetter
  0 siblings, 0 replies; 63+ messages in thread
From: Daniel Vetter @ 2014-11-26 18:25 UTC (permalink / raw)
  To: John Harrison; +Cc: intel-gfx

On Wed, Nov 26, 2014 at 07:23:36PM +0100, Daniel Vetter wrote:
> On Wed, Nov 26, 2014 at 02:58:49PM +0000, John Harrison wrote:
> > On 26/11/2014 14:42, Daniel Vetter wrote:
> > >On Wed, Nov 26, 2014 at 3:12 PM, John Harrison
> > ><John.C.Harrison@intel.com> wrote:
> > >>>>diff --git a/drivers/gpu/drm/i915/i915_drv.h
> > >>>>b/drivers/gpu/drm/i915/i915_drv.h
> > >>>>index 8bfdac6..831fae2 100644
> > >>>>--- a/drivers/gpu/drm/i915/i915_drv.h
> > >>>>+++ b/drivers/gpu/drm/i915/i915_drv.h
> > >>>>@@ -3130,4 +3130,11 @@ wait_remaining_ms_from_jiffies(unsigned long
> > >>>>timestamp_jiffies, int to_wait_ms)
> > >>>>         }
> > >>>>   }
> > >>>>   +static inline void i915_trace_irq_get(struct intel_engine_cs *ring,
> > >>>>+                                     struct drm_i915_gem_request *req)
> > >>>>+{
> > >>>>+       if (ring->trace_irq_req == NULL && ring->irq_get(ring))
> > >>>>+               i915_gem_request_assign(&ring->trace_irq_req, req);
> > >>>This looks a bit suspiciuos. Thus far ring->trace_irq_req was essentially
> > >>>ot protected at all by anything. But that was nothing troublesome since we
> > >>>didn't hang a real resource of it.
> > >>>
> > >>>But now there's a refcounted request in that pointer, which means if we
> > >>>race we leak. I'll skip this patch for now.
> > >>>-Daniel
> > >>
> > >>Race how? The assignment only ever occurs from inside execbuffer submission
> > >>at which point the driver mutex lock is held. Therefore it is very
> > >>definitely protected. Not doing the reference count means that there is now
> > >>the possibility of a dangling pointer and thus the possibility of going bang
> > >>with a kernel oops.
> > >Hm, ->trace_irq_seqno is indeed always touched from the a calling
> > >context with dev->struct_mutex held. Somehow I've misrembered that
> > >since the realtime/tracing folks are really freaked out about what
> > >we're doing here. But from that pov your patch doesn't really make
> > >things worse, so I'll pull it in.
> > >
> > >Btw I don't see the oops really without this patch. What would blow up?
> > >-Daniel
> > 
> > The sole access (and clear to null) of the trace pointer is done from retire
> > requests after the requests have been retired. Thus the request structure
> > could have just been freed immediately before it is used. The code could be
> > re-ordered to be safer but I'm not entirely sure what the trace pointer is
> > for or what it might potentially be used for in the future. With the
> > reference counting, the ordering is irrelevant. If the pointer exists then
> > it is safe to use.
> > 
> > The point is that anywhere that keeps a copy of a request pointer really
> > should reference count that copy. Otherwise there is the possibility that
> > the pointer could become stale. Either now or with future code changes. If
> > the copy is always done with the request_assign() function then the pointer
> > is guaranteed safe for all time.
> 
> Oh, I guess you've misunderstood what I've done. Ive dropped the entire
> patch here, not just the refcounting. Dropping the refcounting alone is
> obviously oops-worthy.

Trying to clarify more: The problem I've thought I've seen is _not_ with
the unref/ref done without holding struct mutex. But with different people
accessing ring->trace_irq_* without locks. Somehow I've thought we've had
no common lock thus far for that - iirc there was a bit of that code in
the irq handler once, but I can't find it any more.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v3 21/28] drm/i915: Remove the now redundant 'obj->ring'
  2014-11-26 13:43   ` Daniel Vetter
@ 2014-11-28 17:49     ` John Harrison
  2014-11-28 18:06       ` Daniel Vetter
  0 siblings, 1 reply; 63+ messages in thread
From: John Harrison @ 2014-11-28 17:49 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Intel-GFX

On 26/11/2014 13:43, Daniel Vetter wrote:
> On Mon, Nov 24, 2014 at 06:49:43PM +0000, John.C.Harrison@Intel.com wrote:
>> From: John Harrison <John.C.Harrison@Intel.com>
>>
>> The ring member of the object structure was always updated with the
>> last_read_seqno member. Thus with the conversion to last_read_req, obj->ring is
>> now a direct copy of obj->last_read_req->ring. This makes it somewhat redundant
>> and potentially misleading (especially as there was no comment to explain its
>> purpose).
>>
>> This checkin removes the redundant field. Many uses were simply testing for
>> non-null to see if the object is active on the GPU. Some of these have been
>> converted to check 'obj->active' instead. Others (where the last_read_req is
>> about to be used anyway) have been changed to check obj->last_read_req. The rest
>> simply pull the ring out from the request structure and proceed as before.
>>
>> For: VIZ-4377
>> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
>> Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
> Ok merged up to this for now. I'd like to settle things a bit first (and
> also figure out what to do with the trace_irq stuff).
>
> Thanks for patches&review,
> Daniel

Now that the 3.19 pull request has gone, are you going to continue 
merging these patches? Or is there something else you particularly want 
to wait for?

Thanks,
John.

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

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

* Re: [PATCH v3 21/28] drm/i915: Remove the now redundant 'obj->ring'
  2014-11-28 17:49     ` John Harrison
@ 2014-11-28 18:06       ` Daniel Vetter
  2014-12-01 12:44         ` John Harrison
  0 siblings, 1 reply; 63+ messages in thread
From: Daniel Vetter @ 2014-11-28 18:06 UTC (permalink / raw)
  To: John Harrison; +Cc: Intel-GFX

On Fri, Nov 28, 2014 at 05:49:26PM +0000, John Harrison wrote:
> On 26/11/2014 13:43, Daniel Vetter wrote:
> >On Mon, Nov 24, 2014 at 06:49:43PM +0000, John.C.Harrison@Intel.com wrote:
> >>From: John Harrison <John.C.Harrison@Intel.com>
> >>
> >>The ring member of the object structure was always updated with the
> >>last_read_seqno member. Thus with the conversion to last_read_req, obj->ring is
> >>now a direct copy of obj->last_read_req->ring. This makes it somewhat redundant
> >>and potentially misleading (especially as there was no comment to explain its
> >>purpose).
> >>
> >>This checkin removes the redundant field. Many uses were simply testing for
> >>non-null to see if the object is active on the GPU. Some of these have been
> >>converted to check 'obj->active' instead. Others (where the last_read_req is
> >>about to be used anyway) have been changed to check obj->last_read_req. The rest
> >>simply pull the ring out from the request structure and proceed as before.
> >>
> >>For: VIZ-4377
> >>Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> >>Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
> >Ok merged up to this for now. I'd like to settle things a bit first (and
> >also figure out what to do with the trace_irq stuff).
> >
> >Thanks for patches&review,
> >Daniel
> 
> Now that the 3.19 pull request has gone, are you going to continue merging
> these patches? Or is there something else you particularly want to wait for?

Well I'm still not convinced that those patches are what we want. For
android (and a few other things) we really want to support struct fence,
and that already provides all the necessary code to cache the completion
state. So I don't see why we have to do a detour just to get caching into
place if for the long-term plan we'll need to rip all that code out again
anyway. And the scheduler without fence/syncpt integration doesn't make a
lot of sense on Android I think.

Now if there's a seriuos performance issue with requests without this then
maybe this detour makes sense. But I don't see any benchmark data attached
to justify the patches from that pov.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v3 21/28] drm/i915: Remove the now redundant 'obj->ring'
  2014-11-28 18:06       ` Daniel Vetter
@ 2014-12-01 12:44         ` John Harrison
  2014-12-01 16:44           ` Daniel Vetter
  0 siblings, 1 reply; 63+ messages in thread
From: John Harrison @ 2014-12-01 12:44 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Intel-GFX

On 28/11/2014 18:06, Daniel Vetter wrote:
> On Fri, Nov 28, 2014 at 05:49:26PM +0000, John Harrison wrote:
>> On 26/11/2014 13:43, Daniel Vetter wrote:
>>> On Mon, Nov 24, 2014 at 06:49:43PM +0000, John.C.Harrison@Intel.com wrote:
>>>> From: John Harrison <John.C.Harrison@Intel.com>
>>>>
>>>> The ring member of the object structure was always updated with the
>>>> last_read_seqno member. Thus with the conversion to last_read_req, obj->ring is
>>>> now a direct copy of obj->last_read_req->ring. This makes it somewhat redundant
>>>> and potentially misleading (especially as there was no comment to explain its
>>>> purpose).
>>>>
>>>> This checkin removes the redundant field. Many uses were simply testing for
>>>> non-null to see if the object is active on the GPU. Some of these have been
>>>> converted to check 'obj->active' instead. Others (where the last_read_req is
>>>> about to be used anyway) have been changed to check obj->last_read_req. The rest
>>>> simply pull the ring out from the request structure and proceed as before.
>>>>
>>>> For: VIZ-4377
>>>> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
>>>> Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
>>> Ok merged up to this for now. I'd like to settle things a bit first (and
>>> also figure out what to do with the trace_irq stuff).
>>>
>>> Thanks for patches&review,
>>> Daniel
>> Now that the 3.19 pull request has gone, are you going to continue merging
>> these patches? Or is there something else you particularly want to wait for?
> Well I'm still not convinced that those patches are what we want. For
> android (and a few other things) we really want to support struct fence,
> and that already provides all the necessary code to cache the completion
> state. So I don't see why we have to do a detour just to get caching into
> place if for the long-term plan we'll need to rip all that code out again
> anyway. And the scheduler without fence/syncpt integration doesn't make a
> lot of sense on Android I think.
>
> Now if there's a seriuos performance issue with requests without this then
> maybe this detour makes sense. But I don't see any benchmark data attached
> to justify the patches from that pov.
> -Daniel

Firstly, not all the missing patches are about performance caching. For 
example, the kmalloc vs kzalloc patch is simply better code all round. 
The tracing patch is also a general purpose driver improvement and makes 
debugging/analysing the code easier.

Re the caching. My argument is that the request implementation, as it 
stands, is a significant step backwards over the original seqno version. 
In the original code, someone had evidently seen fit to make the 
completion test a minimal inline function. In the half merged request 
version, it is a function call with register reading and list traversal. 
As the cached version is already written, tested and reviewed, I do not 
see a reason to discard it in order to write a completely new version at 
some unspecified point in the future that may or may not be quite a 
large piece of work.

Also, the scheduler is already ported on top of the full request patch 
set and is running in the GMin Android code base with native sync 
included. Having to rewrite the underlying code yet again is going to be 
a significant delay in something that needs to be shipped last month. 
Delaying that short term work for a long term goal is really undesirable 
at this point. The plan has always been to rework for long term 
awesomeness (such as dmabuf sync integration) after something basic is 
implemented and shipped.

Do you have time for a phone call or meeting to discuss this?

Thanks,
John.

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

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

* Re: [PATCH v3 21/28] drm/i915: Remove the now redundant 'obj->ring'
  2014-12-01 12:44         ` John Harrison
@ 2014-12-01 16:44           ` Daniel Vetter
  0 siblings, 0 replies; 63+ messages in thread
From: Daniel Vetter @ 2014-12-01 16:44 UTC (permalink / raw)
  To: John Harrison; +Cc: Intel-GFX

On Mon, Dec 01, 2014 at 12:44:12PM +0000, John Harrison wrote:
> On 28/11/2014 18:06, Daniel Vetter wrote:
> >On Fri, Nov 28, 2014 at 05:49:26PM +0000, John Harrison wrote:
> >>On 26/11/2014 13:43, Daniel Vetter wrote:
> >>>On Mon, Nov 24, 2014 at 06:49:43PM +0000, John.C.Harrison@Intel.com wrote:
> >>>>From: John Harrison <John.C.Harrison@Intel.com>
> >>>>
> >>>>The ring member of the object structure was always updated with the
> >>>>last_read_seqno member. Thus with the conversion to last_read_req, obj->ring is
> >>>>now a direct copy of obj->last_read_req->ring. This makes it somewhat redundant
> >>>>and potentially misleading (especially as there was no comment to explain its
> >>>>purpose).
> >>>>
> >>>>This checkin removes the redundant field. Many uses were simply testing for
> >>>>non-null to see if the object is active on the GPU. Some of these have been
> >>>>converted to check 'obj->active' instead. Others (where the last_read_req is
> >>>>about to be used anyway) have been changed to check obj->last_read_req. The rest
> >>>>simply pull the ring out from the request structure and proceed as before.
> >>>>
> >>>>For: VIZ-4377
> >>>>Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> >>>>Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
> >>>Ok merged up to this for now. I'd like to settle things a bit first (and
> >>>also figure out what to do with the trace_irq stuff).
> >>>
> >>>Thanks for patches&review,
> >>>Daniel
> >>Now that the 3.19 pull request has gone, are you going to continue merging
> >>these patches? Or is there something else you particularly want to wait for?
> >Well I'm still not convinced that those patches are what we want. For
> >android (and a few other things) we really want to support struct fence,
> >and that already provides all the necessary code to cache the completion
> >state. So I don't see why we have to do a detour just to get caching into
> >place if for the long-term plan we'll need to rip all that code out again
> >anyway. And the scheduler without fence/syncpt integration doesn't make a
> >lot of sense on Android I think.
> >
> >Now if there's a seriuos performance issue with requests without this then
> >maybe this detour makes sense. But I don't see any benchmark data attached
> >to justify the patches from that pov.
> >-Daniel
> 
> Firstly, not all the missing patches are about performance caching. For
> example, the kmalloc vs kzalloc patch is simply better code all round. The
> tracing patch is also a general purpose driver improvement and makes
> debugging/analysing the code easier.

No concern with those patches from my side except that they're after the
caching change. I can cherry-pick them but it looks a bit like that might
backfire if I also don't pick the request state caching.

> Re the caching. My argument is that the request implementation, as it
> stands, is a significant step backwards over the original seqno version. In
> the original code, someone had evidently seen fit to make the completion
> test a minimal inline function. In the half merged request version, it is a
> function call with register reading and list traversal. As the cached
> version is already written, tested and reviewed, I do not see a reason to
> discard it in order to write a completely new version at some unspecified
> point in the future that may or may not be quite a large piece of work.
> 
> Also, the scheduler is already ported on top of the full request patch set
> and is running in the GMin Android code base with native sync included.
> Having to rewrite the underlying code yet again is going to be a significant
> delay in something that needs to be shipped last month. Delaying that short
> term work for a long term goal is really undesirable at this point. The plan
> has always been to rework for long term awesomeness (such as dmabuf sync
> integration) after something basic is implemented and shipped.
> 
> Do you have time for a phone call or meeting to discuss this?

Yeah, probably easier to discuss in a mtg. Jon Ewins should be there too I
think.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH v4 0/4] Replace seqno values with request structures
  2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
                   ` (28 preceding siblings ...)
  2014-11-25 11:59 ` [PATCH v3 00/28] Replace seqno values with request structures Daniel, Thomas
@ 2014-12-05 13:49 ` John.C.Harrison
  2014-12-05 13:49   ` [PATCH v4 1/4] drm/i915: Fix up seqno -> request merge issues John.C.Harrison
                     ` (3 more replies)
  29 siblings, 4 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-12-05 13:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

There is a general feeling that it is better to move away from using a simple
integer 'seqno' value to track batch buffer completion. Instead, the request
structure should be used. That provides for much more flexibility going
forwards. Especially which things like a GPU scheduler (which can re-order batch
buffers and hence seqnos after submission to the hardware), Android sync points
and other such features which potentially make seqno usage more and more
complex.

This patch set does the work of converting most of the driver to use request
structures in preference to seqno values. The only place left that still uses
seqnos is the semaphore code. It was decided to leave that alone for the time
being as the semaphores are hardware based and the hardware only understands
seqno values.

v2: Rebased to newer nightly tree which significantly changed some of the
display MMIO flip code (including making __wait_request public and renaming
it).

v3: Rebased to yet another nightly tree which included execlist pin/unpin
patches. NB: this is based on a tree including a pending update for an unpin
bug. Also includes a fix for a clash with the shrinker.

v4: Remaining patches rebased to remove caching of completion status patches.
This is now future work to be done in a different manner.

[Patches against drm-intel-nightly tree fetched 03/12/2014]

John Harrison (4):
  drm/i915: Fix up seqno -> request merge issues
  drm/i915: Zero fill the request structure
  drm/i915: Add unique id to the request structure for debugging
  drm/i915: Additional request structure tracing

 drivers/gpu/drm/i915/i915_drv.h         |    4 ++++
 drivers/gpu/drm/i915/i915_irq.c         |    2 +-
 drivers/gpu/drm/i915/i915_trace.h       |   22 ++++++++++++++++------
 drivers/gpu/drm/i915/intel_display.c    |    6 ++----
 drivers/gpu/drm/i915/intel_lrc.c        |    4 +++-
 drivers/gpu/drm/i915/intel_ringbuffer.c |    4 +++-
 6 files changed, 29 insertions(+), 13 deletions(-)

-- 
1.7.9.5

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

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

* [PATCH v4 1/4] drm/i915: Fix up seqno -> request merge issues
  2014-12-05 13:49 ` [PATCH v4 0/4] " John.C.Harrison
@ 2014-12-05 13:49   ` John.C.Harrison
  2014-12-05 20:37     ` Daniel Vetter
  2014-12-05 13:49   ` [PATCH v4 2/4] drm/i915: Zero fill the request structure John.C.Harrison
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 63+ messages in thread
From: John.C.Harrison @ 2014-12-05 13:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The display related patches earlier in this series were edited during merge to
improve the request unreferencing. Specifically, the need for de-referencing at
interrupt time was removed. However, the resulting code did a 'deref(req) ; req
= NULL' sequence rather than using the 'req_assign(req, NULL)' wrapper. The two
are functionally equivalent, but using the wrapper is more consistent with all
the other places where requests are assigned.

Note that the whole point of the wrapper is that using it everywhere that
request pointers are assigned means that the reference counting is done
automatically and can't be accidentally forgotten about. Plus it allows simpler
future maintainance if the reference counting mechanisms ever need to change.

For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 91f0c19..43d8022 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9127,8 +9127,7 @@ static void intel_unpin_work_fn(struct work_struct *__work)
 	intel_update_fbc(dev);
 
 	if (work->flip_queued_req)
-		i915_gem_request_unreference(work->flip_queued_req);
-	work->flip_queued_req  = NULL;
+		i915_gem_request_assign(&work->flip_queued_req, NULL);
 	mutex_unlock(&dev->struct_mutex);
 
 	intel_frontbuffer_flip_complete(dev, INTEL_FRONTBUFFER_PRIMARY(pipe));
@@ -9626,10 +9625,9 @@ static void intel_mmio_flip_work_func(struct work_struct *work)
 	intel_do_mmio_flip(crtc);
 	if (mmio_flip->req) {
 		mutex_lock(&crtc->base.dev->struct_mutex);
-		i915_gem_request_unreference(mmio_flip->req);
+		i915_gem_request_assign(&mmio_flip->req, NULL);
 		mutex_unlock(&crtc->base.dev->struct_mutex);
 	}
-	mmio_flip->req = NULL;
 }
 
 static int intel_queue_mmio_flip(struct drm_device *dev,
-- 
1.7.9.5

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

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

* [PATCH v4 2/4] drm/i915: Zero fill the request structure
  2014-12-05 13:49 ` [PATCH v4 0/4] " John.C.Harrison
  2014-12-05 13:49   ` [PATCH v4 1/4] drm/i915: Fix up seqno -> request merge issues John.C.Harrison
@ 2014-12-05 13:49   ` John.C.Harrison
  2014-12-05 13:49   ` [PATCH v4 3/4] drm/i915: Add unique id to the request structure for debugging John.C.Harrison
  2014-12-05 13:49   ` [PATCH v4 4/4] drm/i915: Additional request structure tracing John.C.Harrison
  3 siblings, 0 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-12-05 13:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

There is a general theory that kzmalloc is better/safer than kmalloc, especially
for interesting data structures. This change updates the request structure
allocation to be zero filled.

Change-Id: I68715ef758025fab8db763941ef63bf60d7031e2
For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/intel_lrc.c        |    2 +-
 drivers/gpu/drm/i915/intel_ringbuffer.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 52e9952..35ed2f1 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -885,7 +885,7 @@ static int logical_ring_alloc_request(struct intel_engine_cs *ring,
 	if (ring->outstanding_lazy_request)
 		return 0;
 
-	request = kmalloc(sizeof(*request), GFP_KERNEL);
+	request = kzalloc(sizeof(*request), GFP_KERNEL);
 	if (request == NULL)
 		return -ENOMEM;
 
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 79b4ca5..2c6c6f8 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -2030,7 +2030,7 @@ intel_ring_alloc_request(struct intel_engine_cs *ring)
 	if (ring->outstanding_lazy_request)
 		return 0;
 
-	request = kmalloc(sizeof(*request), GFP_KERNEL);
+	request = kzalloc(sizeof(*request), GFP_KERNEL);
 	if (request == NULL)
 		return -ENOMEM;
 
-- 
1.7.9.5

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

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

* [PATCH v4 3/4] drm/i915: Add unique id to the request structure for debugging
  2014-12-05 13:49 ` [PATCH v4 0/4] " John.C.Harrison
  2014-12-05 13:49   ` [PATCH v4 1/4] drm/i915: Fix up seqno -> request merge issues John.C.Harrison
  2014-12-05 13:49   ` [PATCH v4 2/4] drm/i915: Zero fill the request structure John.C.Harrison
@ 2014-12-05 13:49   ` John.C.Harrison
  2014-12-05 13:49   ` [PATCH v4 4/4] drm/i915: Additional request structure tracing John.C.Harrison
  3 siblings, 0 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-12-05 13:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

For debugging purposes, it is useful to be able to uniquely identify a given
request structure as it works its way through the system. This becomes
especially tricky once the seqno value is lazily allocated as then the request
has nothing but its pointer to identify it for much of its life.

Change-Id: Ie76b2268b940467f4cdf5a4ba6f5a54cbb96445d
For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h         |    4 ++++
 drivers/gpu/drm/i915/intel_lrc.c        |    2 ++
 drivers/gpu/drm/i915/intel_ringbuffer.c |    2 ++
 3 files changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 049482f..18dfa1e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1787,6 +1787,8 @@ struct drm_i915_private {
 		void (*stop_ring)(struct intel_engine_cs *ring);
 	} gt;
 
+	uint32_t request_uniq;
+
 	/*
 	 * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
 	 * will be rejected. Instead look for a better place.
@@ -2019,6 +2021,8 @@ struct drm_i915_gem_request {
 	struct drm_i915_file_private *file_priv;
 	/** file_priv list entry for this request */
 	struct list_head client_list;
+
+	uint32_t uniq;
 };
 
 void i915_gem_request_free(struct kref *req_ref);
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 35ed2f1..1882e11 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -880,6 +880,7 @@ static int logical_ring_alloc_request(struct intel_engine_cs *ring,
 				      struct intel_context *ctx)
 {
 	struct drm_i915_gem_request *request;
+	struct drm_i915_private *dev_private = ring->dev->dev_private;
 	int ret;
 
 	if (ring->outstanding_lazy_request)
@@ -899,6 +900,7 @@ static int logical_ring_alloc_request(struct intel_engine_cs *ring,
 
 	kref_init(&request->ref);
 	request->ring = ring;
+	request->uniq = dev_private->request_uniq++;
 
 	ret = i915_gem_get_seqno(ring->dev, &request->seqno);
 	if (ret) {
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 2c6c6f8..d496c97 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -2026,6 +2026,7 @@ intel_ring_alloc_request(struct intel_engine_cs *ring)
 {
 	int ret;
 	struct drm_i915_gem_request *request;
+	struct drm_i915_private *dev_private = ring->dev->dev_private;
 
 	if (ring->outstanding_lazy_request)
 		return 0;
@@ -2036,6 +2037,7 @@ intel_ring_alloc_request(struct intel_engine_cs *ring)
 
 	kref_init(&request->ref);
 	request->ring = ring;
+	request->uniq = dev_private->request_uniq++;
 
 	ret = i915_gem_get_seqno(ring->dev, &request->seqno);
 	if (ret) {
-- 
1.7.9.5

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

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

* [PATCH v4 4/4] drm/i915: Additional request structure tracing
  2014-12-05 13:49 ` [PATCH v4 0/4] " John.C.Harrison
                     ` (2 preceding siblings ...)
  2014-12-05 13:49   ` [PATCH v4 3/4] drm/i915: Add unique id to the request structure for debugging John.C.Harrison
@ 2014-12-05 13:49   ` John.C.Harrison
  2014-12-05 19:01     ` shuang.he
  2014-12-05 20:48     ` Daniel Vetter
  3 siblings, 2 replies; 63+ messages in thread
From: John.C.Harrison @ 2014-12-05 13:49 UTC (permalink / raw)
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Added the request structure's 'uniq' identifier to the trace information. Also
renamed the '_complete' trace event to '_notify' as it actually happens in the
IRQ 'notify_ring()' function. The intention is to add a new '_complete' trace
event which occurs when a request structure is actually marked as complete.
However, at the moment the completion status is re-tested every time the query
is made so there isn't a completion event as such.

v2: New patch added to series.

v3: Rebased to remove completion caching as that is apparently contentious.

Change-Id: Ic9bcde67d175c6c03b96217cdcb6e4cc4aa45d67
For: VIZ-4377
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c   |    2 +-
 drivers/gpu/drm/i915/i915_trace.h |   22 ++++++++++++++++------
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 7913a72..08a5a4b 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1013,7 +1013,7 @@ static void notify_ring(struct drm_device *dev,
 	if (!intel_ring_initialized(ring))
 		return;
 
-	trace_i915_gem_request_complete(ring);
+	trace_i915_gem_request_notify(ring);
 
 	wake_up_all(&ring->irq_queue);
 }
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h
index 2ade958..6058a01 100644
--- a/drivers/gpu/drm/i915/i915_trace.h
+++ b/drivers/gpu/drm/i915/i915_trace.h
@@ -406,6 +406,7 @@ DECLARE_EVENT_CLASS(i915_gem_request,
 	    TP_STRUCT__entry(
 			     __field(u32, dev)
 			     __field(u32, ring)
+			     __field(u32, uniq)
 			     __field(u32, seqno)
 			     ),
 
@@ -414,11 +415,13 @@ DECLARE_EVENT_CLASS(i915_gem_request,
 						i915_gem_request_get_ring(req);
 			   __entry->dev = ring->dev->primary->index;
 			   __entry->ring = ring->id;
+			   __entry->uniq = req ? req->uniq : 0;
 			   __entry->seqno = i915_gem_request_get_seqno(req);
 			   ),
 
-	    TP_printk("dev=%u, ring=%u, seqno=%u",
-		      __entry->dev, __entry->ring, __entry->seqno)
+	    TP_printk("dev=%u, ring=%u, uniq=%u, seqno=%u",
+		      __entry->dev, __entry->ring, __entry->uniq,
+		      __entry->seqno)
 );
 
 DEFINE_EVENT(i915_gem_request, i915_gem_request_add,
@@ -426,7 +429,7 @@ DEFINE_EVENT(i915_gem_request, i915_gem_request_add,
 	    TP_ARGS(req)
 );
 
-TRACE_EVENT(i915_gem_request_complete,
+TRACE_EVENT(i915_gem_request_notify,
 	    TP_PROTO(struct intel_engine_cs *ring),
 	    TP_ARGS(ring),
 
@@ -451,6 +454,11 @@ DEFINE_EVENT(i915_gem_request, i915_gem_request_retire,
 	    TP_ARGS(req)
 );
 
+DEFINE_EVENT(i915_gem_request, i915_gem_request_complete,
+	    TP_PROTO(struct drm_i915_gem_request *req),
+	    TP_ARGS(req)
+);
+
 TRACE_EVENT(i915_gem_request_wait_begin,
 	    TP_PROTO(struct drm_i915_gem_request *req),
 	    TP_ARGS(req),
@@ -458,6 +466,7 @@ TRACE_EVENT(i915_gem_request_wait_begin,
 	    TP_STRUCT__entry(
 			     __field(u32, dev)
 			     __field(u32, ring)
+			     __field(u32, uniq)
 			     __field(u32, seqno)
 			     __field(bool, blocking)
 			     ),
@@ -473,14 +482,15 @@ TRACE_EVENT(i915_gem_request_wait_begin,
 						i915_gem_request_get_ring(req);
 			   __entry->dev = ring->dev->primary->index;
 			   __entry->ring = ring->id;
+			   __entry->uniq = req ? req->uniq : 0;
 			   __entry->seqno = i915_gem_request_get_seqno(req);
 			   __entry->blocking =
 				     mutex_is_locked(&ring->dev->struct_mutex);
 			   ),
 
-	    TP_printk("dev=%u, ring=%u, seqno=%u, blocking=%s",
-		      __entry->dev, __entry->ring, __entry->seqno,
-		      __entry->blocking ?  "yes (NB)" : "no")
+	    TP_printk("dev=%u, ring=%u, uniq=%u, seqno=%u, blocking=%s",
+		      __entry->dev, __entry->ring, __entry->uniq,
+		      __entry->seqno, __entry->blocking ?  "yes (NB)" : "no")
 );
 
 DEFINE_EVENT(i915_gem_request, i915_gem_request_wait_end,
-- 
1.7.9.5

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

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

* Re: [PATCH v4 4/4] drm/i915: Additional request structure tracing
  2014-12-05 13:49   ` [PATCH v4 4/4] drm/i915: Additional request structure tracing John.C.Harrison
@ 2014-12-05 19:01     ` shuang.he
  2014-12-05 20:48     ` Daniel Vetter
  1 sibling, 0 replies; 63+ messages in thread
From: shuang.he @ 2014-12-05 19:01 UTC (permalink / raw)
  To: shuang.he, intel-gfx, John.C.Harrison

Tested-By: PRC QA PRTS (Patch Regression Test System Contact: shuang.he@intel.com)
-------------------------------------Summary-------------------------------------
Platform          Delta          drm-intel-nightly          Series Applied
PNV                                  364/364              364/364
ILK                                  366/366              366/366
SNB                 -1              450/450              449/450
IVB              +17                 481/498              498/498
BYT                                  289/289              289/289
HSW                 -1              564/564              563/564
BDW                                  417/417              417/417
-------------------------------------Detailed-------------------------------------
Platform  Test                                drm-intel-nightly          Series Applied
 SNB  igt_kms_force_connector      NRUN(3, M35M22)PASS(1, M35)      NRUN(1, M35)
 IVB  igt_kms_3d      DMESG_WARN(1, M34)PASS(13, M4M34M21)      PASS(1, M4)
 IVB  igt_kms_cursor_crc_cursor-128x128-onscreen      NSPT(1, M34)PASS(13, M4M34M21)      PASS(1, M4)
 IVB  igt_kms_cursor_crc_cursor-128x128-random      NSPT(1, M34)PASS(13, M4M34M21)      PASS(1, M4)
 IVB  igt_kms_cursor_crc_cursor-128x128-sliding      NSPT(1, M34)PASS(13, M4M34M21)      PASS(1, M4)
 IVB  igt_kms_cursor_crc_cursor-256x256-offscreen      NSPT(1, M34)PASS(13, M4M34M21)      PASS(1, M4)
 IVB  igt_kms_cursor_crc_cursor-256x256-onscreen      NSPT(1, M34)PASS(13, M4M34M21)      PASS(1, M4)
 IVB  igt_kms_cursor_crc_cursor-256x256-sliding      NSPT(1, M34)PASS(13, M4M34M21)      PASS(1, M4)
 IVB  igt_kms_cursor_crc_cursor-64x64-offscreen      NSPT(1, M34)PASS(13, M4M34M21)      PASS(1, M4)
 IVB  igt_kms_cursor_crc_cursor-64x64-onscreen      NSPT(1, M34)PASS(13, M4M34M21)      PASS(1, M4)
 IVB  igt_kms_cursor_crc_cursor-64x64-random      NSPT(1, M34)PASS(13, M4M34M21)      PASS(1, M4)
 IVB  igt_kms_cursor_crc_cursor-64x64-sliding      NSPT(1, M34)PASS(13, M4M34M21)      PASS(1, M4)
 IVB  igt_kms_cursor_crc_cursor-size-change      NSPT(1, M34)PASS(13, M4M34M21)      PASS(1, M4)
 IVB  igt_kms_fence_pin_leak      NSPT(1, M34)PASS(13, M4M34M21)      PASS(1, M4)
 IVB  igt_kms_mmio_vs_cs_flip_setcrtc_vs_cs_flip      NSPT(1, M34)PASS(13, M4M34M21)      PASS(1, M4)
 IVB  igt_kms_mmio_vs_cs_flip_setplane_vs_cs_flip      NSPT(1, M34)PASS(13, M4M34M21)      PASS(1, M4)
 IVB  igt_kms_rotation_crc_primary-rotation      NSPT(1, M34)PASS(13, M4M34M21)      PASS(1, M4)
 IVB  igt_kms_rotation_crc_sprite-rotation      NSPT(1, M34)PASS(13, M4M34M21)      PASS(1, M4)
 HSW  igt_kms_force_connector      NRUN(3, M40M19M20)PASS(1, M40)      NRUN(1, M20)
Note: You need to pay more attention to line start with '*'
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v4 1/4] drm/i915: Fix up seqno -> request merge issues
  2014-12-05 13:49   ` [PATCH v4 1/4] drm/i915: Fix up seqno -> request merge issues John.C.Harrison
@ 2014-12-05 20:37     ` Daniel Vetter
  0 siblings, 0 replies; 63+ messages in thread
From: Daniel Vetter @ 2014-12-05 20:37 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: Intel-GFX

On Fri, Dec 05, 2014 at 01:49:33PM +0000, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> The display related patches earlier in this series were edited during merge to
> improve the request unreferencing. Specifically, the need for de-referencing at
> interrupt time was removed. However, the resulting code did a 'deref(req) ; req
> = NULL' sequence rather than using the 'req_assign(req, NULL)' wrapper. The two
> are functionally equivalent, but using the wrapper is more consistent with all
> the other places where requests are assigned.
> 
> Note that the whole point of the wrapper is that using it everywhere that
> request pointers are assigned means that the reference counting is done
> automatically and can't be accidentally forgotten about. Plus it allows simpler
> future maintainance if the reference counting mechanisms ever need to change.
> 
> For: VIZ-4377
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>

I guess it's fairly clear that i915 hasn't used this patter previously ;-)

Thanks for fixing this up. Aside, if you have a slow day: Coccinelle might
be able to automatically hunt for refactorings like this for you. And even
if not playing with that tool is worth it all on its own.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v4 4/4] drm/i915: Additional request structure tracing
  2014-12-05 13:49   ` [PATCH v4 4/4] drm/i915: Additional request structure tracing John.C.Harrison
  2014-12-05 19:01     ` shuang.he
@ 2014-12-05 20:48     ` Daniel Vetter
  2014-12-05 20:50       ` Daniel Vetter
  1 sibling, 1 reply; 63+ messages in thread
From: Daniel Vetter @ 2014-12-05 20:48 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: Intel-GFX

On Fri, Dec 05, 2014 at 01:49:36PM +0000, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> Added the request structure's 'uniq' identifier to the trace information. Also
> renamed the '_complete' trace event to '_notify' as it actually happens in the
> IRQ 'notify_ring()' function. The intention is to add a new '_complete' trace
> event which occurs when a request structure is actually marked as complete.
> However, at the moment the completion status is re-tested every time the query
> is made so there isn't a completion event as such.
> 
> v2: New patch added to series.
> 
> v3: Rebased to remove completion caching as that is apparently contentious.
> 
> Change-Id: Ic9bcde67d175c6c03b96217cdcb6e4cc4aa45d67
> For: VIZ-4377
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>

Ok I guess you'll hate this by now, but struct fence provides all this
already, too. It doesn't use the uniq id trick you have put instead just
uses the pointer. But there's create/destroy tracepoints too afaik, so I
think we're covered.

I've merged the first two patches from this series, thanks.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v4 4/4] drm/i915: Additional request structure tracing
  2014-12-05 20:48     ` Daniel Vetter
@ 2014-12-05 20:50       ` Daniel Vetter
  0 siblings, 0 replies; 63+ messages in thread
From: Daniel Vetter @ 2014-12-05 20:50 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: Intel-GFX

On Fri, Dec 05, 2014 at 09:48:03PM +0100, Daniel Vetter wrote:
> On Fri, Dec 05, 2014 at 01:49:36PM +0000, John.C.Harrison@Intel.com wrote:
> > From: John Harrison <John.C.Harrison@Intel.com>
> > 
> > Added the request structure's 'uniq' identifier to the trace information. Also
> > renamed the '_complete' trace event to '_notify' as it actually happens in the
> > IRQ 'notify_ring()' function. The intention is to add a new '_complete' trace
> > event which occurs when a request structure is actually marked as complete.
> > However, at the moment the completion status is re-tested every time the query
> > is made so there isn't a completion event as such.
> > 
> > v2: New patch added to series.
> > 
> > v3: Rebased to remove completion caching as that is apparently contentious.
> > 
> > Change-Id: Ic9bcde67d175c6c03b96217cdcb6e4cc4aa45d67
> > For: VIZ-4377
> > Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> > Reviewed-by: Thomas Daniel <Thomas.Daniel@intel.com>
> 
> Ok I guess you'll hate this by now, but struct fence provides all this
> already, too. It doesn't use the uniq id trick you have put instead just
> uses the pointer. But there's create/destroy tracepoints too afaik, so I
> think we're covered.
> 
> I've merged the first two patches from this series, thanks.

Well changed my mind again since it's just an extension of what we have.
So patches 3&4 are merged, too.  But yeah I think we really sould switch
over to the fence stuff for all this.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

end of thread, other threads:[~2014-12-05 20:50 UTC | newest]

Thread overview: 63+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-24 18:49 [PATCH v3 00/28] Replace seqno values with request structures John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 01/28] drm/i915: Ensure OLS & PLR are always in sync John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 02/28] drm/i915: Add reference count to request structure John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 03/28] drm/i915: Add helper functions to aid seqno -> request transition John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 04/28] drm/i915: Replace last_[rwf]_seqno with last_[rwf]_req John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 05/28] drm/i915: Convert i915_gem_ring_throttle to use requests John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 06/28] drm/i915: Ensure requests stick around during waits John.C.Harrison
2014-11-26 12:27   ` John Harrison
2014-11-26 13:14     ` Daniel Vetter
2014-11-24 18:49 ` [PATCH v3 07/28] drm/i915: Remove 'outstanding_lazy_seqno' John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 08/28] drm/i915: Make 'i915_gem_check_olr' actually check by request not seqno John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 09/28] drm/i915: Convert 'last_flip_req' to be a request not a seqno John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 10/28] drm/i915: Convert i915_wait_seqno to i915_wait_request John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 11/28] drm/i915: Add IRQ friendly request deference facility John.C.Harrison
2014-11-26  9:19   ` Daniel Vetter
2014-11-26 12:23     ` John Harrison
2014-11-26 12:35       ` Daniel Vetter
2014-11-24 18:49 ` [PATCH v3 12/28] drm/i915: Convert mmio_flip::seqno to struct request John.C.Harrison
2014-11-26  9:23   ` Daniel Vetter
2014-11-26 12:12     ` John Harrison
2014-11-26 12:49       ` Daniel Vetter
2014-11-26 15:21         ` John Harrison
2014-11-26 18:22           ` Daniel Vetter
2014-11-24 18:49 ` [PATCH v3 13/28] drm/i915: Convert __wait_seqno() to __wait_request() John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 14/28] drm/i915: Remove obsolete seqno parameter from 'i915_add_request' John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 15/28] drm/i915: Convert 'flip_queued_seqno' into 'flip_queued_request' John.C.Harrison
2014-11-26 13:07   ` Daniel Vetter
2014-11-24 18:49 ` [PATCH v3 16/28] drm/i915: Convert trace functions from seqno to request John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 17/28] drm/i915: Convert 'trace_irq' to use requests rather than seqnos John.C.Harrison
2014-11-26 13:24   ` Daniel Vetter
2014-11-26 14:12     ` John Harrison
2014-11-26 14:31       ` Chris Wilson
2014-11-26 14:42       ` Daniel Vetter
2014-11-26 14:58         ` John Harrison
2014-11-26 18:23           ` Daniel Vetter
2014-11-26 18:25             ` Daniel Vetter
2014-11-24 18:49 ` [PATCH v3 18/28] drm/i915: Convert 'ring_idle()' to use requests not seqnos John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 19/28] drm/i915: Connect requests to rings at creation not submission John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 20/28] drm/i915: Convert 'i915_seqno_passed' calls into 'i915_gem_request_completed' John.C.Harrison
2014-11-26 13:42   ` Daniel Vetter
2014-11-24 18:49 ` [PATCH v3 21/28] drm/i915: Remove the now redundant 'obj->ring' John.C.Harrison
2014-11-26 13:43   ` Daniel Vetter
2014-11-28 17:49     ` John Harrison
2014-11-28 18:06       ` Daniel Vetter
2014-12-01 12:44         ` John Harrison
2014-12-01 16:44           ` Daniel Vetter
2014-11-24 18:49 ` [PATCH v3 22/28] drm/i915: Cache request completion status John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 23/28] drm/i915: Zero fill the request structure John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 24/28] drm/i915: Spinlock protection for request list John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 25/28] drm/i915: Interrupt driven request completion John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 26/28] drm/i915: Remove obsolete parameter to i915_gem_request_completed() John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 27/28] drm/i915: Add unique id to the request structure for debugging John.C.Harrison
2014-11-24 18:49 ` [PATCH v3 28/28] drm/i915: Additional request structure tracing John.C.Harrison
2014-11-25 11:59 ` [PATCH v3 00/28] Replace seqno values with request structures Daniel, Thomas
2014-12-05 13:49 ` [PATCH v4 0/4] " John.C.Harrison
2014-12-05 13:49   ` [PATCH v4 1/4] drm/i915: Fix up seqno -> request merge issues John.C.Harrison
2014-12-05 20:37     ` Daniel Vetter
2014-12-05 13:49   ` [PATCH v4 2/4] drm/i915: Zero fill the request structure John.C.Harrison
2014-12-05 13:49   ` [PATCH v4 3/4] drm/i915: Add unique id to the request structure for debugging John.C.Harrison
2014-12-05 13:49   ` [PATCH v4 4/4] drm/i915: Additional request structure tracing John.C.Harrison
2014-12-05 19:01     ` shuang.he
2014-12-05 20:48     ` Daniel Vetter
2014-12-05 20:50       ` Daniel Vetter

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.