--- 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@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx