Hi Adrian,

On Thu, 28 Aug 2025 at 04:35, Adrián Larumbe
<adrian.laru...@collabora.com> wrote:
> -void panfrost_job_close(struct panfrost_file_priv *panfrost_priv)
> +int panfrost_jm_ctx_destroy(struct drm_file *file, u32 handle)
>  {
> -       struct panfrost_device *pfdev = panfrost_priv->pfdev;
> -       int i;
> +       struct panfrost_file_priv *priv = file->driver_priv;
> +       struct panfrost_device *pfdev = priv->pfdev;
> +       struct panfrost_jm_ctx *jm_ctx;
>
> -       for (i = 0; i < NUM_JOB_SLOTS; i++)
> -               drm_sched_entity_destroy(&panfrost_priv->sched_entity[i]);
> +       jm_ctx = xa_erase(&priv->jm_ctxs, handle);
> +       if (!jm_ctx)
> +               return -EINVAL;
> +
> +       for (u32 i = 0; i < ARRAY_SIZE(jm_ctx->slots); i++) {
> +               if (jm_ctx->slots[i].enabled)
> +                       
> drm_sched_entity_destroy(&jm_ctx->slots[i].sched_entity);
> +       }
>
>         /* Kill in-flight jobs */
>         spin_lock(&pfdev->js->job_lock);
> -       for (i = 0; i < NUM_JOB_SLOTS; i++) {
> -               struct drm_sched_entity *entity = 
> &panfrost_priv->sched_entity[i];
> -               int j;
> +       for (u32 i = 0; i < ARRAY_SIZE(jm_ctx->slots); i++) {
> +               struct drm_sched_entity *entity = 
> &jm_ctx->slots[i].sched_entity;
> +
> +               if (!jm_ctx->slots[i].enabled)
> +                       continue;
>
> -               for (j = ARRAY_SIZE(pfdev->jobs[0]) - 1; j >= 0; j--) {
> +               for (int j = ARRAY_SIZE(pfdev->jobs[0]) - 1; j >= 0; j--) {
>                         struct panfrost_job *job = pfdev->jobs[i][j];
>                         u32 cmd;
>
> @@ -980,18 +1161,7 @@ void panfrost_job_close(struct panfrost_file_priv 
> *panfrost_priv)
>                 }
>         }
>         spin_unlock(&pfdev->js->job_lock);
> -}
> -
> -int panfrost_job_is_idle(struct panfrost_device *pfdev)
> -{
> -       struct panfrost_job_slot *js = pfdev->js;
> -       int i;
> -
> -       for (i = 0; i < NUM_JOB_SLOTS; i++) {
> -               /* If there are any jobs in the HW queue, we're not idle */
> -               if (atomic_read(&js->queue[i].sched.credit_count))
> -                       return false;
> -       }
>
> -       return true;
> +       panfrost_jm_ctx_put(jm_ctx);
> +       return 0;
>  }

It seems odd that both panfrost_jm_ctx_destroy() and
panfrost_jm_ctx_release() share lifetime responsibilities. I'd expect
calling panfrost_jm_ctx_destroy() to just release the xarray handle
and drop the refcount.

I can see why calling panfrost_jm_ctx_destroy() is the one to go try
to cancel the jobs - because the jobs keep a refcount on the context,
so we need to break that cycle somehow. But having both the
handle-release and object-release function drop a ref on the sched
entity seems odd?

It doesn't help much that panfrost_job is used both for actual jobs
(as the type) and the capability for a device to have multiple
job-manager contexts (as a function prefix). Would be great to clean
that up, so you don't have to think about whether e.g.
panfrost_job_close() is actually operating on a panfrost_job, or
operating on multiple panfrost_jm_ctx which operate on multiple
panfrost_job.

Cheers,
Daniel

Reply via email to