mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-04 21:42:31 -04:00
drm/xe/queue: Call fini on exec queue creation fail
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: 3c1fa4aa60 ("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>
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user