]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/xe/queue: Call fini on exec queue creation fail
authorTomasz Lis <tomasz.lis@intel.com>
Thu, 26 Feb 2026 21:26:58 +0000 (22:26 +0100)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Mon, 2 Mar 2026 16:12:40 +0000 (11:12 -0500)
Every call to queue init should have a corresponding fini call.
Skipping this would mean skipping removal of the queue from GuC list
(which is part of guc_id allocation). A damaged queue stored in
exec_queue_lookup list would lead to invalid memory reference,
sooner or later.

Call fini to free guc_id. This must be done before any internal
LRCs are freed.

Since the finalization with this extra call became very similar to
__xe_exec_queue_fini(), reuse that. To make this reuse possible,
alter xe_lrc_put() so it can survive NULL parameters, like other
similar functions.

v2: Reuse _xe_exec_queue_fini(). Make xe_lrc_put() aware of NULLs.

Fixes: 3c1fa4aa60b1 ("drm/xe: Move queue init before LRC creation")
Signed-off-by: Tomasz Lis <tomasz.lis@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com> (v1)
Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
Link: https://patch.msgid.link/20260226212701.2937065-2-tomasz.lis@intel.com
(cherry picked from commit 393e5fea6f7d7054abc2c3d97a4cfe8306cd6079)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
drivers/gpu/drm/xe/xe_exec_queue.c
drivers/gpu/drm/xe/xe_lrc.h

index 0ddae7fcfc97fa9d2bdf6a4e0253c93089afd356..8ecdf949f9e4c82243271cd698519fe0963cb29d 100644 (file)
@@ -266,6 +266,16 @@ static struct xe_exec_queue *__xe_exec_queue_alloc(struct xe_device *xe,
        return q;
 }
 
+static void __xe_exec_queue_fini(struct xe_exec_queue *q)
+{
+       int i;
+
+       q->ops->fini(q);
+
+       for (i = 0; i < q->width; ++i)
+               xe_lrc_put(q->lrc[i]);
+}
+
 static int __xe_exec_queue_init(struct xe_exec_queue *q, u32 exec_queue_flags)
 {
        int i, err;
@@ -320,21 +330,10 @@ static int __xe_exec_queue_init(struct xe_exec_queue *q, u32 exec_queue_flags)
        return 0;
 
 err_lrc:
-       for (i = i - 1; i >= 0; --i)
-               xe_lrc_put(q->lrc[i]);
+       __xe_exec_queue_fini(q);
        return err;
 }
 
-static void __xe_exec_queue_fini(struct xe_exec_queue *q)
-{
-       int i;
-
-       q->ops->fini(q);
-
-       for (i = 0; i < q->width; ++i)
-               xe_lrc_put(q->lrc[i]);
-}
-
 struct xe_exec_queue *xe_exec_queue_create(struct xe_device *xe, struct xe_vm *vm,
                                           u32 logical_mask, u16 width,
                                           struct xe_hw_engine *hwe, u32 flags,
index c307a3fd9ea287d54f2d211cdb688e1143a43d03..c1c615447c8574939a8384497cbfc2c3a2dce953 100644 (file)
@@ -75,7 +75,8 @@ static inline struct xe_lrc *xe_lrc_get(struct xe_lrc *lrc)
  */
 static inline void xe_lrc_put(struct xe_lrc *lrc)
 {
-       kref_put(&lrc->refcount, xe_lrc_destroy);
+       if (lrc)
+               kref_put(&lrc->refcount, xe_lrc_destroy);
 }
 
 /**