All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Wilson <chris@chris-wilson.co.uk>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH v4 09/16] drm/i915: Take a reference whilst processing the signaler request
Date: Thu, 23 Feb 2017 07:44:15 +0000	[thread overview]
Message-ID: <20170223074422.4125-10-chris@chris-wilson.co.uk> (raw)
In-Reply-To: <20170223074422.4125-1-chris@chris-wilson.co.uk>

The plan in the near-future is to allow requests to be removed from the
signaler. We can no longer then rely on holding a reference to the
request for the duration it is in the signaling tree, and instead must
obtain a reference to the request for the current operation using RCU.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
 drivers/gpu/drm/i915/intel_breadcrumbs.c | 22 +++++++++++++++-------
 drivers/gpu/drm/i915/intel_ringbuffer.h  |  2 +-
 2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c
index d5bf4c0b2deb..a35d59d00bfb 100644
--- a/drivers/gpu/drm/i915/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c
@@ -496,7 +496,11 @@ static int intel_breadcrumbs_signaler(void *arg)
 		 * need to wait for a new interrupt from the GPU or for
 		 * a new client.
 		 */
-		request = READ_ONCE(b->first_signal);
+		rcu_read_lock();
+		request = rcu_dereference(b->first_signal);
+		if (request)
+			request = i915_gem_request_get_rcu(request);
+		rcu_read_unlock();
 		if (signal_complete(request)) {
 			local_bh_disable();
 			dma_fence_signal(&request->fence);
@@ -515,24 +519,28 @@ static int intel_breadcrumbs_signaler(void *arg)
 			 * the oldest before picking the next one.
 			 */
 			spin_lock_irq(&b->lock);
-			if (request == b->first_signal) {
+			if (request == rcu_access_pointer(b->first_signal)) {
 				struct rb_node *rb =
 					rb_next(&request->signaling.node);
-				b->first_signal = rb ? to_signaler(rb) : NULL;
+				rcu_assign_pointer(b->first_signal,
+						   rb ? to_signaler(rb) : NULL);
 			}
 			rb_erase(&request->signaling.node, &b->signals);
 			spin_unlock_irq(&b->lock);
 
 			i915_gem_request_put(request);
 		} else {
-			if (kthread_should_stop())
+			if (kthread_should_stop()) {
+				GEM_BUG_ON(request);
 				break;
+			}
 
 			schedule();
 
 			if (kthread_should_park())
 				kthread_parkme();
 		}
+		i915_gem_request_put(request);
 	} while (1);
 	__set_current_state(TASK_RUNNING);
 
@@ -597,7 +605,7 @@ void intel_engine_enable_signaling(struct drm_i915_gem_request *request)
 	rb_link_node(&request->signaling.node, parent, p);
 	rb_insert_color(&request->signaling.node, &b->signals);
 	if (first)
-		smp_store_mb(b->first_signal, request);
+		rcu_assign_pointer(b->first_signal, request);
 
 	spin_unlock(&b->lock);
 
@@ -670,7 +678,7 @@ void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine)
 	/* The engines should be idle and all requests accounted for! */
 	WARN_ON(READ_ONCE(b->first_wait));
 	WARN_ON(!RB_EMPTY_ROOT(&b->waiters));
-	WARN_ON(READ_ONCE(b->first_signal));
+	WARN_ON(rcu_access_pointer(b->first_signal));
 	WARN_ON(!RB_EMPTY_ROOT(&b->signals));
 
 	if (!IS_ERR_OR_NULL(b->signaler))
@@ -691,7 +699,7 @@ bool intel_breadcrumbs_busy(struct intel_engine_cs *engine)
 		busy |= intel_engine_flag(engine);
 	}
 
-	if (b->first_signal) {
+	if (rcu_access_pointer(b->first_signal)) {
 		wake_up_process(b->signaler);
 		busy |= intel_engine_flag(engine);
 	}
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 04e7d5a9ee3a..fbf34af7bc77 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -242,7 +242,7 @@ struct intel_engine_cs {
 		struct rb_root signals; /* sorted by retirement */
 		struct intel_wait *first_wait; /* oldest waiter by retirement */
 		struct task_struct *signaler; /* used for fence signalling */
-		struct drm_i915_gem_request *first_signal;
+		struct drm_i915_gem_request __rcu *first_signal;
 		struct timer_list fake_irq; /* used after a missed interrupt */
 		struct timer_list hangcheck; /* detect missed interrupts */
 
-- 
2.11.0

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

  parent reply	other threads:[~2017-02-23  7:44 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-23  7:44 Preemption preparation pass phaw Chris Wilson
2017-02-23  7:44 ` [PATCH v4 01/16] drm/i915: Check against the signaled bit for fences/requests Chris Wilson
2017-02-23  7:44 ` [PATCH v4 02/16] drm/i915: Keep a global seqno per-engine Chris Wilson
2017-02-23  7:44 ` [PATCH v4 03/16] drm/i915: Move reserve_seqno() next to unreserve_seqno() Chris Wilson
2017-02-23  7:44 ` [PATCH v4 04/16] drm/i915: Use a local to shorten req->i915->gpu_error.wait_queue Chris Wilson
2017-02-23  7:44 ` [PATCH v4 05/16] drm/i915: Add ourselves to the gpu error waitqueue for the entire wait Chris Wilson
2017-02-23  7:44 ` [PATCH v4 06/16] drm/i915: Inline __i915_gem_request_wait_for_execute() Chris Wilson
2017-02-23  7:44 ` [PATCH v4 07/16] drm/i915: Deconstruct execute fence Chris Wilson
2017-02-23  7:44 ` [PATCH v4 08/16] drm/i915: Protect the request->global_seqno with the engine->timeline lock Chris Wilson
2017-02-23  7:44 ` Chris Wilson [this message]
2017-02-23  7:44 ` [PATCH v4 10/16] drm/i915: Allow a request to be cancelled Chris Wilson
2017-02-23  7:44 ` [PATCH v4 11/16] drm/i915: Remove the preempted request from the execution queue Chris Wilson
2017-02-23 12:11   ` Tvrtko Ursulin
2017-02-23  7:44 ` [PATCH v4 12/16] drm/i915: Exercise request cancellation using a mock selftest Chris Wilson
2017-02-23 12:21   ` Tvrtko Ursulin
2017-02-23  7:44 ` [PATCH v4 13/16] drm/i915: Replace reset_wait_queue with default_wake_function Chris Wilson
2017-02-23  7:44 ` [PATCH v4 14/16] drm/i915: Refactor direct GPU reset from request waiters Chris Wilson
2017-02-23 12:23   ` Tvrtko Ursulin
2017-02-23  7:44 ` [PATCH v4 15/16] drm/i915: Immediately process a reset before starting waiting Chris Wilson
2017-02-23 12:35   ` Tvrtko Ursulin
2017-02-23 12:41     ` Chris Wilson
2017-02-23 12:45       ` Tvrtko Ursulin
2017-02-23  7:44 ` [PATCH v4 16/16] drm/i915: Remove one level of indention from wait-for-execute Chris Wilson
2017-02-23  8:18 ` ✓ Fi.CI.BAT: success for series starting with [v4,01/16] drm/i915: Check against the signaled bit for fences/requests Patchwork
2017-02-23 15:21   ` Chris Wilson

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=20170223074422.4125-10-chris@chris-wilson.co.uk \
    --to=chris@chris-wilson.co.uk \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

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

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