[Intel-gfx] [PATCH] drm/i915/guc: Clear terminated attribute bit on GuC preemption context

Michel Thierry michel.thierry at intel.com
Wed Nov 1 23:29:13 UTC 2017


On 01/11/17 15:16, jeff.mcgee at intel.com wrote:
> From: Jeff McGee <jeff.mcgee at intel.com>
> 
> If GuC firmware performs an engine reset while that engine had a
> preemption pending, it will set the terminated attribute bit on our
> preemption stage descriptor. GuC firmware retains all pending work
> items for a high-priority GuC client, unlike the normal-priority GuC
> client where work items are dropped. It wants to make sure the preempt-
> to-idle work doesn't run when scheduling resumes, and uses this bit to
> inform its scheduler and presumably us as well. Our job is to clear it
> for the next preemption after reset, otherwise that and future
> preemptions will never complete. We'll just clear it every time.
> 
> Signed-off-by: Jeff McGee <jeff.mcgee at intel.com>
> ---
>   drivers/gpu/drm/i915/i915_guc_submission.c | 15 +++++++++++++++
>   1 file changed, 15 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
> index 3049a0781b88..d14c1342f09d 100644
> --- a/drivers/gpu/drm/i915/i915_guc_submission.c
> +++ b/drivers/gpu/drm/i915/i915_guc_submission.c
> @@ -590,6 +590,7 @@ static void inject_preempt_context(struct work_struct *work)
>          struct intel_guc *guc = container_of(preempt_work, typeof(*guc),
>                                               preempt_work[engine->id]);
>          struct i915_guc_client *client = guc->preempt_client;
> +       struct guc_stage_desc *stage_desc = __get_stage_desc(client);
>          struct intel_ring *ring = client->owner->engine[engine->id].ring;
>          u32 ctx_desc = lower_32_bits(intel_lr_context_descriptor(client->owner,
>                                                                   engine));
> @@ -623,6 +624,20 @@ static void inject_preempt_context(struct work_struct *work)
>                             ring->tail / sizeof(u64), 0);
>          spin_unlock_irq(&client->wq_lock);
> 
> +       /*
> +        * If GuC firmware performs an engine reset while that engine had
> +        * a preemption pending, it will set the terminated attribute bit
> +        * on our preemption stage descriptor. GuC firmware retains all
> +        * pending work items for a high-priority GuC client, unlike the
> +        * normal-priority GuC client where work items are dropped. It
> +        * wants to make sure the preempt-to-idle work doesn't run when
> +        * scheduling resumes, and uses this bit to inform its scheduler
> +        * and presumably us as well. Our job is to clear it for the next
> +        * preemption after reset, otherwise that and future preemptions
> +        * will never complete. We'll just clear it every time.
> +        */
> +       stage_desc->attribute &= ~GUC_STAGE_DESC_ATTR_TERMINATED;
> +

I looked around and yes, the firmware will set the terminated bit in the 
stage_desc of the preempt client if it had a pending preemption request. 
No harm in clearing it unconditionally.

>          data[0] = INTEL_GUC_ACTION_REQUEST_PREEMPTION;
>          data[1] = client->stage_id;
>          data[2] = INTEL_GUC_PREEMPT_OPTION_DROP_WORK_Q |
> --
> 2.14.2

Since Michał is not around,

Reviewed-by: Michel Thierry <michel.thierry at intel.com>


More information about the Intel-gfx mailing list