[PATCH 14/14] drm/i915/breadcrumbs: Convert the signal rbtree to the cached variant

Chris Wilson chris at chris-wilson.co.uk
Wed Jan 3 11:40:31 UTC 2018


As we keep track of the leftmost element of the rbtree ourselves, we can
simply switch over to the new library variant of rbtree that provides
the caching itself.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/intel_breadcrumbs.c | 24 +++++++++---------------
 drivers/gpu/drm/i915/intel_ringbuffer.h  |  4 ++--
 2 files changed, 11 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c
index 6cfffa68f71a..6dd6bc9811a8 100644
--- a/drivers/gpu/drm/i915/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c
@@ -663,13 +663,7 @@ static void __intel_engine_remove_signal(struct intel_engine_cs *engine,
 	 * the oldest before picking the next one.
 	 */
 	if (request->signaling.wait.seqno) {
-		if (request == rcu_access_pointer(b->first_signal)) {
-			struct rb_node *rb = rb_next(&request->signaling.node);
-			rcu_assign_pointer(b->first_signal,
-					   rb ? to_signaler(rb) : NULL);
-		}
-
-		rb_erase(&request->signaling.node, &b->signals);
+		rb_erase_cached(&request->signaling.node, &b->signals);
 		request->signaling.wait.seqno = 0;
 	}
 }
@@ -697,7 +691,9 @@ static int intel_breadcrumbs_signaler(void *arg)
 		 * a new client.
 		 */
 		rcu_read_lock();
-		request = rcu_dereference(b->first_signal);
+		request = rb_entry_safe(rb_first_cached(&b->signals),
+					struct drm_i915_gem_request,
+					signaling.node);
 		if (request)
 			request = i915_gem_request_get_rcu(request);
 		rcu_read_unlock();
@@ -790,7 +786,7 @@ void intel_engine_enable_signaling(struct drm_i915_gem_request *request,
 		 */
 		parent = NULL;
 		first = true;
-		p = &b->signals.rb_node;
+		p = &b->signals.rb_root.rb_node;
 		while (*p) {
 			parent = *p;
 			if (i915_seqno_passed(seqno,
@@ -802,9 +798,8 @@ 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)
-			rcu_assign_pointer(b->first_signal, request);
+		rb_insert_color_cached(&request->signaling.node,
+				       &b->signals, first);
 	} else {
 		__intel_engine_remove_wait(engine, &request->signaling.wait);
 		request->signaling.wait.seqno = 0;
@@ -902,8 +897,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->irq_wait));
 	WARN_ON(!RB_EMPTY_ROOT(&b->waiters));
-	WARN_ON(rcu_access_pointer(b->first_signal));
-	WARN_ON(!RB_EMPTY_ROOT(&b->signals));
+	WARN_ON(!RB_EMPTY_ROOT(&b->signals.rb_root));
 
 	if (!IS_ERR_OR_NULL(b->signaler))
 		kthread_stop(b->signaler);
@@ -923,7 +917,7 @@ bool intel_breadcrumbs_busy(struct intel_engine_cs *engine)
 		busy = true;
 	}
 
-	if (rcu_access_pointer(b->first_signal)) {
+	if (!RB_EMPTY_ROOT(&b->signals.rb_root)) {
 		wake_up_process(b->signaler);
 		busy = true;
 	}
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 0b762a4d4612..5dade4d144de 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -327,9 +327,9 @@ struct intel_engine_cs {
 
 		spinlock_t rb_lock; /* protects the rb and wraps irq_lock */
 		struct rb_root waiters; /* sorted by retirement, priority */
-		struct rb_root signals; /* sorted by retirement */
+		struct rb_root_cached signals; /* sorted by retirement */
+
 		struct task_struct *signaler; /* used for fence signalling */
-		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.15.1



More information about the Intel-gfx-trybot mailing list