[Intel-gfx] [PATCH 07/33] drm/i915: Move active request tracking to a vfunc

2021-07-26 Thread Matthew Brost
Move active request tracking to a backend vfunc rather than assuming all
backends want to do this in the manner. In the of case execlists /
ring submission the tracking is on the physical engine while with GuC
submission it is on the context.

Signed-off-by: Matthew Brost 
Reviewed-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/intel_context.c   |  3 ++
 drivers/gpu/drm/i915/gt/intel_context_types.h |  7 
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |  6 +++
 .../drm/i915/gt/intel_execlists_submission.c  | 40 ++
 .../gpu/drm/i915/gt/intel_ring_submission.c   | 22 ++
 drivers/gpu/drm/i915/gt/mock_engine.c | 30 ++
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 33 +++
 drivers/gpu/drm/i915/i915_request.c   | 41 ++-
 drivers/gpu/drm/i915/i915_request.h   |  2 +
 9 files changed, 147 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index baa05fddd690..0bf4a13e9759 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -393,6 +393,9 @@ intel_context_init(struct intel_context *ce, struct 
intel_engine_cs *engine)
spin_lock_init(>guc_state.lock);
INIT_LIST_HEAD(>guc_state.fences);
 
+   spin_lock_init(>guc_active.lock);
+   INIT_LIST_HEAD(>guc_active.requests);
+
ce->guc_id = GUC_INVALID_LRC_ID;
INIT_LIST_HEAD(>guc_id_link);
 
diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h 
b/drivers/gpu/drm/i915/gt/intel_context_types.h
index 542c98418771..035108c10b2c 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -162,6 +162,13 @@ struct intel_context {
struct list_head fences;
} guc_state;
 
+   struct {
+   /** lock: protects everything in guc_active */
+   spinlock_t lock;
+   /** requests: active requests on this context */
+   struct list_head requests;
+   } guc_active;
+
/* GuC scheduling state flags that do not require a lock. */
atomic_t guc_sched_state_no_lock;
 
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h 
b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index e55776e27a2a..1c7e2724cdae 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -414,6 +414,12 @@ struct intel_engine_cs {
 
void(*release)(struct intel_engine_cs *engine);
 
+   /*
+* Add / remove request from engine active tracking
+*/
+   void(*add_active_request)(struct i915_request *rq);
+   void(*remove_active_request)(struct i915_request *rq);
+
struct intel_engine_execlists execlists;
 
/*
diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c 
b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
index 6e4959ee5065..b4a876736074 100644
--- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
@@ -3157,6 +3157,42 @@ static void execlists_park(struct intel_engine_cs 
*engine)
cancel_timer(>execlists.preempt);
 }
 
+static void add_to_engine(struct i915_request *rq)
+{
+   lockdep_assert_held(>engine->sched_engine->lock);
+   list_move_tail(>sched.link, >engine->sched_engine->requests);
+}
+
+static void remove_from_engine(struct i915_request *rq)
+{
+   struct intel_engine_cs *engine, *locked;
+
+   /*
+* Virtual engines complicate acquiring the engine timeline lock,
+* as their rq->engine pointer is not stable until under that
+* engine lock. The simple ploy we use is to take the lock then
+* check that the rq still belongs to the newly locked engine.
+*/
+   locked = READ_ONCE(rq->engine);
+   spin_lock_irq(>sched_engine->lock);
+   while (unlikely(locked != (engine = READ_ONCE(rq->engine {
+   spin_unlock(>sched_engine->lock);
+   spin_lock(>sched_engine->lock);
+   locked = engine;
+   }
+   list_del_init(>sched.link);
+
+   clear_bit(I915_FENCE_FLAG_PQUEUE, >fence.flags);
+   clear_bit(I915_FENCE_FLAG_HOLD, >fence.flags);
+
+   /* Prevent further __await_execution() registering a cb, then flush */
+   set_bit(I915_FENCE_FLAG_ACTIVE, >fence.flags);
+
+   spin_unlock_irq(>sched_engine->lock);
+
+   i915_request_notify_execute_cb_imm(rq);
+}
+
 static bool can_preempt(struct intel_engine_cs *engine)
 {
if (GRAPHICS_VER(engine->i915) > 8)
@@ -3251,6 +3287,8 @@ logical_ring_default_vfuncs(struct intel_engine_cs 
*engine)
 
engine->cops = _context_ops;
engine->request_alloc = execlists_request_alloc;
+   engine->add_active_request = add_to_engine;
+   engine->remove_active_request = remove_from_engine;
 

[Intel-gfx] [PATCH 07/33] drm/i915: Move active request tracking to a vfunc

2021-07-22 Thread Matthew Brost
Move active request tracking to a backend vfunc rather than assuming all
backends want to do this in the manner. In the of case execlists /
ring submission the tracking is on the physical engine while with GuC
submission it is on the context.

Signed-off-by: Matthew Brost 
Reviewed-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/intel_context.c   |  3 ++
 drivers/gpu/drm/i915/gt/intel_context_types.h |  7 
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |  6 +++
 .../drm/i915/gt/intel_execlists_submission.c  | 40 ++
 .../gpu/drm/i915/gt/intel_ring_submission.c   | 22 ++
 drivers/gpu/drm/i915/gt/mock_engine.c | 30 ++
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 33 +++
 drivers/gpu/drm/i915/i915_request.c   | 41 ++-
 drivers/gpu/drm/i915/i915_request.h   |  2 +
 9 files changed, 147 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index baa05fddd690..0bf4a13e9759 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -393,6 +393,9 @@ intel_context_init(struct intel_context *ce, struct 
intel_engine_cs *engine)
spin_lock_init(>guc_state.lock);
INIT_LIST_HEAD(>guc_state.fences);
 
+   spin_lock_init(>guc_active.lock);
+   INIT_LIST_HEAD(>guc_active.requests);
+
ce->guc_id = GUC_INVALID_LRC_ID;
INIT_LIST_HEAD(>guc_id_link);
 
diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h 
b/drivers/gpu/drm/i915/gt/intel_context_types.h
index 542c98418771..035108c10b2c 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -162,6 +162,13 @@ struct intel_context {
struct list_head fences;
} guc_state;
 
+   struct {
+   /** lock: protects everything in guc_active */
+   spinlock_t lock;
+   /** requests: active requests on this context */
+   struct list_head requests;
+   } guc_active;
+
/* GuC scheduling state flags that do not require a lock. */
atomic_t guc_sched_state_no_lock;
 
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h 
b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index 03a81e8d87f4..950fc73ed6af 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -420,6 +420,12 @@ struct intel_engine_cs {
 
void(*release)(struct intel_engine_cs *engine);
 
+   /*
+* Add / remove request from engine active tracking
+*/
+   void(*add_active_request)(struct i915_request *rq);
+   void(*remove_active_request)(struct i915_request *rq);
+
struct intel_engine_execlists execlists;
 
/*
diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c 
b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
index 605dd7cb2901..60427b106bad 100644
--- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
@@ -3157,6 +3157,42 @@ static void execlists_park(struct intel_engine_cs 
*engine)
cancel_timer(>execlists.preempt);
 }
 
+static void add_to_engine(struct i915_request *rq)
+{
+   lockdep_assert_held(>engine->sched_engine->lock);
+   list_move_tail(>sched.link, >engine->sched_engine->requests);
+}
+
+static void remove_from_engine(struct i915_request *rq)
+{
+   struct intel_engine_cs *engine, *locked;
+
+   /*
+* Virtual engines complicate acquiring the engine timeline lock,
+* as their rq->engine pointer is not stable until under that
+* engine lock. The simple ploy we use is to take the lock then
+* check that the rq still belongs to the newly locked engine.
+*/
+   locked = READ_ONCE(rq->engine);
+   spin_lock_irq(>sched_engine->lock);
+   while (unlikely(locked != (engine = READ_ONCE(rq->engine {
+   spin_unlock(>sched_engine->lock);
+   spin_lock(>sched_engine->lock);
+   locked = engine;
+   }
+   list_del_init(>sched.link);
+
+   clear_bit(I915_FENCE_FLAG_PQUEUE, >fence.flags);
+   clear_bit(I915_FENCE_FLAG_HOLD, >fence.flags);
+
+   /* Prevent further __await_execution() registering a cb, then flush */
+   set_bit(I915_FENCE_FLAG_ACTIVE, >fence.flags);
+
+   spin_unlock_irq(>sched_engine->lock);
+
+   i915_request_notify_execute_cb_imm(rq);
+}
+
 static bool can_preempt(struct intel_engine_cs *engine)
 {
if (GRAPHICS_VER(engine->i915) > 8)
@@ -3251,6 +3287,8 @@ logical_ring_default_vfuncs(struct intel_engine_cs 
*engine)
 
engine->cops = _context_ops;
engine->request_alloc = execlists_request_alloc;
+   engine->add_active_request = add_to_engine;
+   engine->remove_active_request = remove_from_engine;