Re: [Intel-gfx] [PATCH 2/5] drm/i915/gt: Restore ce->signal flush before releasing virtual engine

2021-01-08 Thread Andi Shyti
> > > +void intel_context_remove_breadcrumbs(struct intel_context *ce,
> > > +   struct intel_breadcrumbs *b)
> > > +{
> > > + struct i915_request *rq, *rn;
> > > + bool release = false;
> > > + unsigned long flags;
> > > +
> > > + spin_lock_irqsave(&ce->signal_lock, flags);
> > > +
> > > + if (list_empty(&ce->signals))
> > > + goto unlock;
> > 
> > does "list_empty" need to be under lock or you've been lazy?
> 
> This check is required to be under the lock, we have to be careful about
> not calling remove_signaling_context() from here and signal_irq_work.
> I put the unlocked check in the caller to avoid the function call as well.

OK...

Reviewed-by: Andi Shyti 

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


Re: [Intel-gfx] [PATCH 2/5] drm/i915/gt: Restore ce->signal flush before releasing virtual engine

2021-01-08 Thread Andi Shyti
Hi Chris,

> +void intel_context_remove_breadcrumbs(struct intel_context *ce,
> +   struct intel_breadcrumbs *b)
> +{
> + struct i915_request *rq, *rn;
> + bool release = false;
> + unsigned long flags;
> +
> + spin_lock_irqsave(&ce->signal_lock, flags);
> +
> + if (list_empty(&ce->signals))
> + goto unlock;

does "list_empty" need to be under lock or you've been lazy?

The rest looks fine,
Andi

> + list_for_each_entry_safe(rq, rn, &ce->signals, signal_link) {
> + GEM_BUG_ON(!__i915_request_is_complete(rq));
> + if (!test_and_clear_bit(I915_FENCE_FLAG_SIGNAL,
> + &rq->fence.flags))
> + continue;
> +
> + list_del_rcu(&rq->signal_link);
> + irq_signal_request(rq, b);
> + i915_request_put(rq);
> + }
> + release = remove_signaling_context(b, ce);
> +
> +unlock:
> + spin_unlock_irqrestore(&ce->signal_lock, flags);
> + if (release)
> + intel_context_put(ce);
> +
> + while (atomic_read(&b->signaler_active))
> + cpu_relax();
> +}
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 2/5] drm/i915/gt: Restore ce->signal flush before releasing virtual engine

2021-01-08 Thread Chris Wilson
Quoting Andi Shyti (2021-01-08 15:18:22)
> Hi Chris,
> 
> > +void intel_context_remove_breadcrumbs(struct intel_context *ce,
> > +   struct intel_breadcrumbs *b)
> > +{
> > + struct i915_request *rq, *rn;
> > + bool release = false;
> > + unsigned long flags;
> > +
> > + spin_lock_irqsave(&ce->signal_lock, flags);
> > +
> > + if (list_empty(&ce->signals))
> > + goto unlock;
> 
> does "list_empty" need to be under lock or you've been lazy?

This check is required to be under the lock, we have to be careful about
not calling remove_signaling_context() from here and signal_irq_work.
I put the unlocked check in the caller to avoid the function call as well.
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 2/5] drm/i915/gt: Restore ce->signal flush before releasing virtual engine

2021-01-07 Thread Chris Wilson
Before we mark the virtual engine as no longer inflight, flush any
ongoing signaling that may be using the ce->signal_link along the
previous breadcrumbs. On switch to a new physical engine, that link will
be inserted into the new set of breadcrumbs, causing confusion to an
ongoing iterator.

This patch undoes a last minute mistake introduced into commit
bab0557c8dca ("drm/i915/gt: Remove virtual breadcrumb before transfer"),
whereby instead of unconditionally applying the flush, it was only
applied if the request itself was going to be reused.

v2: Generalise and cancel all remaining ce->signals

Fixes: bab0557c8dca ("drm/i915/gt: Remove virtual breadcrumb before transfer")
Signed-off-by: Chris Wilson 
---
 drivers/gpu/drm/i915/gt/intel_breadcrumbs.c   | 33 +++
 drivers/gpu/drm/i915/gt/intel_breadcrumbs.h   |  4 +++
 .../drm/i915/gt/intel_execlists_submission.c  | 25 ++
 3 files changed, 47 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c 
b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
index 2eabb9ab5d47..7137b6f24f55 100644
--- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
@@ -472,6 +472,39 @@ void i915_request_cancel_breadcrumb(struct i915_request 
*rq)
i915_request_put(rq);
 }
 
+void intel_context_remove_breadcrumbs(struct intel_context *ce,
+ struct intel_breadcrumbs *b)
+{
+   struct i915_request *rq, *rn;
+   bool release = false;
+   unsigned long flags;
+
+   spin_lock_irqsave(&ce->signal_lock, flags);
+
+   if (list_empty(&ce->signals))
+   goto unlock;
+
+   list_for_each_entry_safe(rq, rn, &ce->signals, signal_link) {
+   GEM_BUG_ON(!__i915_request_is_complete(rq));
+   if (!test_and_clear_bit(I915_FENCE_FLAG_SIGNAL,
+   &rq->fence.flags))
+   continue;
+
+   list_del_rcu(&rq->signal_link);
+   irq_signal_request(rq, b);
+   i915_request_put(rq);
+   }
+   release = remove_signaling_context(b, ce);
+
+unlock:
+   spin_unlock_irqrestore(&ce->signal_lock, flags);
+   if (release)
+   intel_context_put(ce);
+
+   while (atomic_read(&b->signaler_active))
+   cpu_relax();
+}
+
 static void print_signals(struct intel_breadcrumbs *b, struct drm_printer *p)
 {
struct intel_context *ce;
diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.h 
b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.h
index 75cc9cff3ae3..3ce5ce270b04 100644
--- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.h
+++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.h
@@ -6,6 +6,7 @@
 #ifndef __INTEL_BREADCRUMBS__
 #define __INTEL_BREADCRUMBS__
 
+#include 
 #include 
 
 #include "intel_engine_types.h"
@@ -44,4 +45,7 @@ void intel_engine_print_breadcrumbs(struct intel_engine_cs 
*engine,
 bool i915_request_enable_breadcrumb(struct i915_request *request);
 void i915_request_cancel_breadcrumb(struct i915_request *request);
 
+void intel_context_remove_breadcrumbs(struct intel_context *ce,
+ struct intel_breadcrumbs *b);
+
 #endif /* __INTEL_BREADCRUMBS__ */
diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c 
b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
index 2f8e10450f7e..eb69eef9d7db 100644
--- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
@@ -581,21 +581,6 @@ resubmit_virtual_request(struct i915_request *rq, struct 
virtual_engine *ve)
 {
struct intel_engine_cs *engine = rq->engine;
 
-   /* Flush concurrent rcu iterators in signal_irq_work */
-   if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &rq->fence.flags)) {
-   /*
-* After this point, the rq may be transferred to a new
-* sibling, so before we clear ce->inflight make sure that
-* the context has been removed from the b->signalers and
-* furthermore we need to make sure that the concurrent
-* iterator in signal_irq_work is no longer following
-* ce->signal_link.
-*/
-   i915_request_cancel_breadcrumb(rq);
-   while (atomic_read(&engine->breadcrumbs->signaler_active))
-   cpu_relax();
-   }
-
spin_lock_irq(&engine->active.lock);
 
clear_bit(I915_FENCE_FLAG_PQUEUE, &rq->fence.flags);
@@ -610,6 +595,16 @@ static void kick_siblings(struct i915_request *rq, struct 
intel_context *ce)
struct virtual_engine *ve = container_of(ce, typeof(*ve), context);
struct intel_engine_cs *engine = rq->engine;
 
+   /*
+* After this point, the rq may be transferred to a new sibling, so
+* before we clear ce->inflight make sure that the context has been
+* removed from the b->signal