[Intel-gfx] [PATCH 1/3] drm/i915/guc: Clear preempt status before use
Chris Wilson
chris at chris-wilson.co.uk
Sun Oct 14 17:02:00 UTC 2018
---
drivers/gpu/drm/i915/intel_guc.h | 4 ++-
drivers/gpu/drm/i915/intel_guc_submission.c | 33 +++++++++++----------
2 files changed, 21 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index 0f1c4f9ebfd8..5703e62a3d33 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -34,6 +34,8 @@
#include "intel_uc_fw.h"
#include "i915_vma.h"
+struct guc_shared_ctx_data;
+
struct guc_preempt_work {
struct work_struct work;
struct intel_engine_cs *engine;
@@ -62,7 +64,7 @@ struct intel_guc {
void *stage_desc_pool_vaddr;
struct ida stage_ids;
struct i915_vma *shared_data;
- void *shared_data_vaddr;
+ struct guc_shared_ctx_data *shared_data_vaddr;
struct intel_guc_client *execbuf_client;
struct intel_guc_client *preempt_client;
diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c b/drivers/gpu/drm/i915/intel_guc_submission.c
index eae668442ebe..fb0499f80b62 100644
--- a/drivers/gpu/drm/i915/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/intel_guc_submission.c
@@ -555,6 +555,8 @@ static void inject_preempt_context(struct work_struct *work)
struct intel_guc_client *client = guc->preempt_client;
struct guc_stage_desc *stage_desc = __get_stage_desc(client);
struct intel_context *ce = to_intel_context(client->owner, engine);
+ struct guc_ctx_report *report =
+ &guc->shared_data_vaddr->preempt_ctx_report[engine->guc_id];
u32 data[7];
if (!ce->ring->emit) { /* recreate upon load/resume */
@@ -587,6 +589,14 @@ static void inject_preempt_context(struct work_struct *work)
GUC_PREEMPT_BREADCRUMB_BYTES / sizeof(u64), 0);
spin_unlock_irq(&client->wq_lock);
+ /*
+ * GuC is expecting that we're also going to clear the affected context
+ * counter, let's also reset the return status to not depend on GuC
+ * resetting it after recieving another preempt action
+ */
+ report->affected_count = 0;
+ report->report_return_status = INTEL_GUC_REPORT_STATUS_UNKNOWN;
+
/*
* If GuC firmware performs an engine reset while that engine had
* a preemption pending, it will set the terminated attribute bit
@@ -629,20 +639,12 @@ static void inject_preempt_context(struct work_struct *work)
static void wait_for_guc_preempt_report(struct intel_engine_cs *engine)
{
struct intel_guc *guc = &engine->i915->guc;
- struct guc_shared_ctx_data *data = guc->shared_data_vaddr;
struct guc_ctx_report *report =
- &data->preempt_ctx_report[engine->guc_id];
+ &guc->shared_data_vaddr->preempt_ctx_report[engine->guc_id];
- WARN_ON(wait_for_atomic(report->report_return_status ==
+ WARN_ON(wait_for_atomic(READ_ONCE(report->report_return_status) ==
INTEL_GUC_REPORT_STATUS_COMPLETE,
GUC_PREEMPT_POSTPROCESS_DELAY_MS));
- /*
- * GuC is expecting that we're also going to clear the affected context
- * counter, let's also reset the return status to not depend on GuC
- * resetting it after recieving another preempt action
- */
- report->affected_count = 0;
- report->report_return_status = INTEL_GUC_REPORT_STATUS_UNKNOWN;
}
static void complete_preempt_context(struct intel_engine_cs *engine)
@@ -654,11 +656,10 @@ static void complete_preempt_context(struct intel_engine_cs *engine)
if (inject_preempt_hang(execlists))
return;
+ wait_for_guc_preempt_report(engine);
+
execlists_cancel_port_requests(execlists);
execlists_unwind_incomplete_requests(execlists);
-
- wait_for_guc_preempt_report(engine);
- intel_write_status_page(engine, I915_GEM_HWS_PREEMPT_INDEX, 0);
}
/**
@@ -726,6 +727,9 @@ static bool __guc_dequeue(struct intel_engine_cs *engine)
int prio = execlists->queue_priority;
if (__execlists_need_preempt(prio, port_prio(port))) {
+ intel_write_status_page(engine,
+ I915_GEM_HWS_PREEMPT_INDEX,
+ 0);
execlists_set_active(execlists,
EXECLISTS_ACTIVE_PREEMPT);
queue_work(engine->i915->guc.preempt_wq,
@@ -816,8 +820,7 @@ static void guc_submission_tasklet(unsigned long data)
}
if (execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT) &&
- intel_read_status_page(engine, I915_GEM_HWS_PREEMPT_INDEX) ==
- GUC_PREEMPT_FINISHED)
+ intel_read_status_page(engine, I915_GEM_HWS_PREEMPT_INDEX))
complete_preempt_context(engine);
if (!execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT))
--
2.19.1
More information about the Intel-gfx
mailing list