[Intel-gfx] [PATCH 1/2] drm/i915: Push the wakeref->count deferral to the backend
Chris Wilson
chris at chris-wilson.co.uk
Fri Aug 9 21:01:41 UTC 2019
If the backend wishes to defer the wakeref parking, make it responsible
for unlocking the wakeref (i.e. bumping the counter). This allows it to
time the unlock much more carefully in case it happens to needs the
wakeref to be active during its deferral.
For instance, during engine parking we may choose to emit an idle
barrier (a request). To do so, we borrow the engine->kernel_context
timeline and to ensure exclusive access we keep the
engine->wakeref.count as 0. However, to submit that request to HW may
require a intel_engine_pm_get() (e.g. to keep the submission tasklet
alive) and before we allow that we have to rewake our wakeref to avoid a
recursive deadlock.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio at intel.com>
---
drivers/gpu/drm/i915/gt/intel_engine_pm.c | 4 +++-
drivers/gpu/drm/i915/i915_request.c | 10 ++++++++--
drivers/gpu/drm/i915/i915_request.h | 1 +
drivers/gpu/drm/i915/intel_wakeref.c | 4 +---
4 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.c b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
index 6b15e3335dd6..ca12938d9f8d 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
@@ -68,9 +68,11 @@ static bool switch_to_kernel_context(struct intel_engine_cs *engine)
/* Check again on the next retirement. */
engine->wakeref_serial = engine->serial + 1;
-
i915_request_add_active_barriers(rq);
+
__i915_request_commit(rq);
+ atomic_inc(&engine->wakeref.count);
+ __i915_request_queue(rq);
return false;
}
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index 43175bada09e..3a0760ad56eb 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -1186,6 +1186,13 @@ struct i915_request *__i915_request_commit(struct i915_request *rq)
list_add(&ring->active_link, &rq->i915->gt.active_rings);
rq->emitted_jiffies = jiffies;
+ return prev;
+}
+
+void __i915_request_queue(struct i915_request *rq)
+{
+ struct intel_engine_cs *engine = rq->engine;
+
/*
* Let the backend know a new request has arrived that may need
* to adjust the existing execution schedule due to a high priority
@@ -1230,8 +1237,6 @@ struct i915_request *__i915_request_commit(struct i915_request *rq)
}
i915_sw_fence_commit(&rq->submit);
local_bh_enable(); /* Kick the execlists tasklet if just scheduled */
-
- return prev;
}
void i915_request_add(struct i915_request *rq)
@@ -1244,6 +1249,7 @@ void i915_request_add(struct i915_request *rq)
trace_i915_request_add(rq);
prev = __i915_request_commit(rq);
+ __i915_request_queue(rq);
/*
* In typical scenarios, we do not expect the previous request on
diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h
index 313df3c37158..984c8205a185 100644
--- a/drivers/gpu/drm/i915/i915_request.h
+++ b/drivers/gpu/drm/i915/i915_request.h
@@ -251,6 +251,7 @@ struct i915_request * __must_check
i915_request_create(struct intel_context *ce);
struct i915_request *__i915_request_commit(struct i915_request *request);
+void __i915_request_queue(struct i915_request *rq);
void i915_request_retire_upto(struct i915_request *rq);
diff --git a/drivers/gpu/drm/i915/intel_wakeref.c b/drivers/gpu/drm/i915/intel_wakeref.c
index d4443e81c1c8..868cc78048d0 100644
--- a/drivers/gpu/drm/i915/intel_wakeref.c
+++ b/drivers/gpu/drm/i915/intel_wakeref.c
@@ -57,12 +57,10 @@ static void ____intel_wakeref_put_last(struct intel_wakeref *wf)
if (!atomic_dec_and_test(&wf->count))
goto unlock;
+ /* ops->put() must reschedule its own release on error/deferral */
if (likely(!wf->ops->put(wf))) {
rpm_put(wf);
wake_up_var(&wf->wakeref);
- } else {
- /* ops->put() must schedule its own release on deferral */
- atomic_set_release(&wf->count, 1);
}
unlock:
--
2.23.0.rc1
More information about the Intel-gfx
mailing list