---
 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

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

Reply via email to