All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ben Widawsky <ben@bwidawsk.net>
To: intel-gfx@lists.freedesktop.org
Cc: Ben Widawsky <ben@bwidawsk.net>, Mika Kuoppala <mika.kuoppala@intel.com>
Subject: [PATCH 1/2] [v3] drm/i915: reference count for i915_hw_contexts
Date: Tue,  2 Apr 2013 15:45:42 -0700	[thread overview]
Message-ID: <1364942743-6041-1-git-send-email-ben@bwidawsk.net> (raw)
In-Reply-To: <1363276337-12509-4-git-send-email-mika.kuoppala@intel.com>
In-Reply-To: <1363276337-12509-4-git-send-email-mika.kuoppala@intel.com>

From: Mika Kuoppala <mika.kuoppala@linux.intel.com>

In preparation to do analysis of which context was
guilty of gpu hung, store kreffed context pointer
into request struct.

This allows us to inspect contexts when gpu is reset
even if those contexts would already be released
by userspace.

v2: track i915_hw_context pointers instead of using ctx_ids
    (from Chris Wilson)

v3 (Ben): Get rid of do_release() and handle refcounting more compactly.
(recommended by Chris)

Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
 drivers/gpu/drm/i915/i915_drv.h            | 10 ++++++++--
 drivers/gpu/drm/i915/i915_gem.c            | 16 +++++++++++++++-
 drivers/gpu/drm/i915/i915_gem_context.c    | 17 +++++++++++++----
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |  7 ++++---
 4 files changed, 40 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 5b0c699..b88b67d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -437,6 +437,7 @@ struct i915_hw_ppgtt {
 /* This must match up with the value previously used for execbuf2.rsvd1. */
 #define DEFAULT_CONTEXT_ID 0
 struct i915_hw_context {
+	struct kref ref;
 	int id;
 	bool is_initialized;
 	struct drm_i915_file_private *file_priv;
@@ -1240,6 +1241,9 @@ struct drm_i915_gem_request {
 	/** Postion in the ringbuffer of the end of the request */
 	u32 tail;
 
+	/** Context related to this request */
+	struct i915_hw_context *ctx;
+
 	/** Time at which this request was emitted, in jiffies. */
 	unsigned long emitted_jiffies;
 
@@ -1630,9 +1634,10 @@ int __must_check i915_gpu_idle(struct drm_device *dev);
 int __must_check i915_gem_idle(struct drm_device *dev);
 int i915_do_add_request(struct intel_ring_buffer *ring,
 			u32 *seqno,
-			struct drm_file *file);
+			struct drm_file *file,
+			struct i915_hw_context *ctx);
 #define i915_add_request(ring, seqno) \
-	i915_do_add_request(ring, seqno, NULL)
+	i915_do_add_request(ring, seqno, NULL, NULL)
 int __must_check i915_wait_seqno(struct intel_ring_buffer *ring,
 				 uint32_t seqno);
 int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
@@ -1676,6 +1681,7 @@ void i915_gem_context_close(struct drm_device *dev, struct drm_file *file);
 struct i915_hw_context * __must_check
 i915_switch_context(struct intel_ring_buffer *ring,
 		    struct drm_file *file, int to_id);
+void i915_gem_context_free(struct kref *ctx_ref);
 int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
 				  struct drm_file *file);
 int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index fbbe7d9..e55c4a8 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1997,7 +1997,8 @@ i915_gem_get_seqno(struct drm_device *dev, u32 *seqno)
 int
 i915_do_add_request(struct intel_ring_buffer *ring,
 		    u32 *out_seqno,
-		    struct drm_file *file)
+		    struct drm_file *file,
+		    struct i915_hw_context *ctx)
 {
 	drm_i915_private_t *dev_priv = ring->dev->dev_private;
 	struct drm_i915_gem_request *request;
@@ -2037,6 +2038,11 @@ i915_do_add_request(struct intel_ring_buffer *ring,
 	request->seqno = intel_ring_get_seqno(ring);
 	request->ring = ring;
 	request->tail = request_ring_position;
+	request->ctx = ctx;
+
+	if (request->ctx)
+		kref_get(&request->ctx->ref);
+
 	request->emitted_jiffies = jiffies;
 	was_empty = list_empty(&ring->request_list);
 	list_add_tail(&request->list, &ring->request_list);
@@ -2101,6 +2107,10 @@ static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv,
 
 		list_del(&request->list);
 		i915_gem_request_remove_from_client(request);
+
+		if (request->ctx)
+			kref_put(&request->ctx->ref, i915_gem_context_free);
+
 		kfree(request);
 	}
 
@@ -2195,6 +2205,10 @@ i915_gem_retire_requests_ring(struct intel_ring_buffer *ring)
 
 		list_del(&request->list);
 		i915_gem_request_remove_from_client(request);
+
+		if (request->ctx)
+			kref_put(&request->ctx->ref, i915_gem_context_free);
+
 		kfree(request);
 	}
 
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index ddf26a6..19feeb6 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -126,11 +126,18 @@ static int get_context_size(struct drm_device *dev)
 
 static void do_destroy(struct i915_hw_context *ctx)
 {
+	drm_gem_object_unreference(&ctx->obj->base);
+	kfree(ctx);
+}
+
+void i915_gem_context_free(struct kref *ctx_ref)
+{
+	struct i915_hw_context *ctx = container_of(ctx_ref,
+						   typeof(*ctx), ref);
 	if (ctx->file_priv)
 		idr_remove(&ctx->file_priv->context_idr, ctx->id);
 
-	drm_gem_object_unreference(&ctx->obj->base);
-	kfree(ctx);
+	do_destroy(ctx);
 }
 
 static struct i915_hw_context *
@@ -145,6 +152,7 @@ create_hw_context(struct drm_device *dev,
 	if (ctx == NULL)
 		return ERR_PTR(-ENOMEM);
 
+	kref_init(&ctx->ref);
 	ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size);
 	if (ctx->obj == NULL) {
 		kfree(ctx);
@@ -275,7 +283,8 @@ static int context_idr_cleanup(int id, void *p, void *data)
 
 	BUG_ON(id == DEFAULT_CONTEXT_ID);
 
-	do_destroy(ctx);
+	ctx->file_priv = NULL;
+	kref_put(&ctx->ref, i915_gem_context_free);
 
 	return 0;
 }
@@ -511,7 +520,7 @@ int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
 		return -ENOENT;
 	}
 
-	do_destroy(ctx);
+	kref_put(&ctx->ref, i915_gem_context_free);
 
 	mutex_unlock(&dev->struct_mutex);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index d87b94b..7f58b2e 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -794,13 +794,14 @@ i915_gem_execbuffer_move_to_active(struct list_head *objects,
 static void
 i915_gem_execbuffer_retire_commands(struct drm_device *dev,
 				    struct drm_file *file,
-				    struct intel_ring_buffer *ring)
+				    struct intel_ring_buffer *ring,
+				    struct i915_hw_context *ctx)
 {
 	/* Unconditionally force add_request to emit a full flush. */
 	ring->gpu_caches_dirty = true;
 
 	/* Add a breadcrumb for the completion of the batch buffer */
-	(void)i915_do_add_request(ring, NULL, file);
+	(void)i915_do_add_request(ring, NULL, file, ctx);
 }
 
 static int
@@ -1076,7 +1077,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 	trace_i915_gem_ring_dispatch(ring, intel_ring_get_seqno(ring), flags);
 
 	i915_gem_execbuffer_move_to_active(&eb->objects, ring);
-	i915_gem_execbuffer_retire_commands(dev, file, ring);
+	i915_gem_execbuffer_retire_commands(dev, file, ring, ctx);
 
 err:
 	eb_destroy(eb);
-- 
1.8.2

  parent reply	other threads:[~2013-04-02 22:43 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-14 15:52 [PATCH v2 00/16] arb robustness enablers v2 Mika Kuoppala
2013-03-14 15:52 ` [PATCH v2 01/16] drm/i915: return context from i915_switch_context() Mika Kuoppala
2013-03-14 15:52 ` [PATCH v2 02/16] drm/i915: cleanup i915_add_request Mika Kuoppala
2013-03-15  9:43   ` Chris Wilson
2013-03-14 15:52 ` [PATCH v2 03/16] drm/i915: reference count for i915_hw_contexts Mika Kuoppala
2013-03-15  9:44   ` Chris Wilson
2013-04-02 22:45   ` Ben Widawsky [this message]
2013-04-02 22:45     ` [PATCH 2/2] drm/i915: Print all contexts in debugfs Ben Widawsky
2013-04-03  1:27     ` [PATCH 1/2] [v3] drm/i915: reference count for i915_hw_contexts Ben Widawsky
2013-04-03 11:56       ` Chris Wilson
2013-04-03 16:37         ` Daniel Vetter
2013-03-14 15:52 ` [PATCH v2 04/16] drm/i915: Resurrect ring kicking for semaphores, selectively Mika Kuoppala
2013-03-17 21:53   ` Daniel Vetter
2013-03-14 15:52 ` [PATCH v2 05/16] drm/i915: pass seqno to i915_hangcheck_ring_idle Mika Kuoppala
2013-03-14 15:52 ` [PATCH v2 06/16] drm/i915: track ring progression using seqnos Mika Kuoppala
2013-03-15  9:48   ` Chris Wilson
2013-03-14 15:52 ` [PATCH v2 07/16] drm/i915: introduce i915_hangcheck_ring_hung Mika Kuoppala
2013-03-14 15:52 ` [PATCH v2 08/16] drm/i915: detect hang using per ring hangcheck_score Mika Kuoppala
2013-03-14 15:52 ` [PATCH v2 09/16] drm/i915: remove i915_hangcheck_hung Mika Kuoppala
2013-03-14 15:52 ` [PATCH v2 10/16] drm/i915: add struct ctx_reset_state Mika Kuoppala
2013-03-15  9:52   ` Chris Wilson
2013-03-17 21:51     ` Daniel Vetter
2013-03-18 20:18   ` Ian Romanick
2013-03-14 15:52 ` [PATCH v2 11/16] drm/i915: add reset_state for hw_contexts Mika Kuoppala
2013-03-15  9:53   ` Chris Wilson
2013-03-14 15:52 ` [PATCH v2 12/16] drm/i915: add batch object and context to i915_add_request() Mika Kuoppala
2013-03-14 15:52 ` [PATCH v2 13/16] drm/i915: mark rings which were waiting when hang happened Mika Kuoppala
2013-03-14 15:52 ` [PATCH v2 14/16] drm/i915: find guilty batch buffer on ring resets Mika Kuoppala
2013-03-14 15:52 ` [PATCH v2 15/16] drm/i915: refuse to submit more batchbuffers from guilty context Mika Kuoppala
2013-03-14 15:52 ` [PATCH v2 16/16] drm/i915: add i915_gem_context_get_reset_status_ioctl Mika Kuoppala
2013-03-15 10:01   ` Chris Wilson
2013-03-18 20:26   ` Ian Romanick
2013-03-19 12:58     ` Mika Kuoppala
2013-03-19 19:02       ` Ian Romanick
2013-03-19 19:21         ` Daniel Vetter

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=1364942743-6041-1-git-send-email-ben@bwidawsk.net \
    --to=ben@bwidawsk.net \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=mika.kuoppala@intel.com \
    /path/to/YOUR_REPLY

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

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.