]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
accel/ivpu: fix HWS command queue leak on registration failure
authorKarol Wachowski <karol.wachowski@linux.intel.com>
Thu, 11 Jun 2026 05:51:40 +0000 (07:51 +0200)
committerKarol Wachowski <karol.wachowski@linux.intel.com>
Mon, 15 Jun 2026 07:01:01 +0000 (09:01 +0200)
A command queue is considered valid and usable by the driver only when
it has a doorbell ID assigned (db_id != 0), meaning both the FW cmdq
creation and doorbell registration completed successfully.

However, when either ivpu_register_db() or set_context_sched_properties()
fails after ivpu_hws_cmdq_init() has already created the cmdq in FW,
the command queue is left registered in FW while the driver treats it as
uninitialized (db_id remains 0). On the next submission attempt the
driver tries to register the same cmdq again, which fails because FW
already has an entry for it.

Fix by calling ivpu_jsm_hws_destroy_cmdq() on error paths to properly
unwind FW state and allow subsequent registration attempts to succeed.

Fixes: 465a3914b254 ("accel/ivpu: Add API for command queue create/destroy/submit")
Reviewed-by: Andrzej Kacprowski <andrzej.kacprowski@linux.intel.com>
Signed-off-by: Karol Wachowski <karol.wachowski@linux.intel.com>
Link: https://patch.msgid.link/20260611055140.948684-1-karol.wachowski@linux.intel.com
drivers/accel/ivpu/ivpu_job.c

index 521931d1f7fcaf6cb7e2becda09b7e025356023b..b24f31a8b5672b6a2e782e1c188741e561a00ea4 100644 (file)
@@ -208,9 +208,9 @@ static int ivpu_hws_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq
        ret = ivpu_jsm_hws_set_context_sched_properties(vdev, file_priv->ctx.id, cmdq->id,
                                                        priority);
        if (ret)
-               return ret;
+               ivpu_jsm_hws_destroy_cmdq(vdev, file_priv->ctx.id, cmdq->id);
 
-       return 0;
+       return ret;
 }
 
 static int ivpu_register_db(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq)
@@ -281,10 +281,10 @@ static int ivpu_cmdq_register(struct ivpu_file_priv *file_priv, struct ivpu_cmdq
        }
 
        ret = ivpu_register_db(file_priv, cmdq);
-       if (ret)
-               return ret;
+       if (ret && vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW)
+               ivpu_jsm_hws_destroy_cmdq(vdev, file_priv->ctx.id, cmdq->id);
 
-       return 0;
+       return ret;
 }
 
 static int ivpu_cmdq_unregister(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq)