]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/xe/hw_engine_group: Fix potential leak
authorMichal Wajdeczko <michal.wajdeczko@intel.com>
Fri, 27 Jun 2025 18:41:43 +0000 (20:41 +0200)
committerMichal Wajdeczko <michal.wajdeczko@intel.com>
Wed, 2 Jul 2025 11:31:30 +0000 (13:31 +0200)
If we fail to allocate a workqueue we will leak kzalloc'ed group
object since it was designed to be kfree'ed in the drmm cleanup
action, but we didn't have a chance to register this action yet.

To avoid this leak allocate a group object using drmm_kzalloc()
and start using predefined drmm action to release the workqueue.

Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
Cc: Francois Dugast <francois.dugast@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
Link: https://lore.kernel.org/r/20250627184143.1480-1-michal.wajdeczko@intel.com
drivers/gpu/drm/xe/xe_hw_engine_group.c

index 2d68c5b5262abf5bb085b5b87912b5fe23e2a214..87a6dcb1b4b51ba482f907099029ddc274d7fe4d 100644 (file)
 #include "xe_hw_engine_group.h"
 #include "xe_vm.h"
 
-static void
-hw_engine_group_free(struct drm_device *drm, void *arg)
-{
-       struct xe_hw_engine_group *group = arg;
-
-       destroy_workqueue(group->resume_wq);
-       kfree(group);
-}
-
 static void
 hw_engine_group_resume_lr_jobs_func(struct work_struct *w)
 {
@@ -53,7 +44,7 @@ hw_engine_group_alloc(struct xe_device *xe)
        struct xe_hw_engine_group *group;
        int err;
 
-       group = kzalloc(sizeof(*group), GFP_KERNEL);
+       group = drmm_kzalloc(&xe->drm, sizeof(*group), GFP_KERNEL);
        if (!group)
                return ERR_PTR(-ENOMEM);
 
@@ -61,14 +52,14 @@ hw_engine_group_alloc(struct xe_device *xe)
        if (!group->resume_wq)
                return ERR_PTR(-ENOMEM);
 
+       err = drmm_add_action_or_reset(&xe->drm, __drmm_workqueue_release, group->resume_wq);
+       if (err)
+               return ERR_PTR(err);
+
        init_rwsem(&group->mode_sem);
        INIT_WORK(&group->resume_work, hw_engine_group_resume_lr_jobs_func);
        INIT_LIST_HEAD(&group->exec_queue_list);
 
-       err = drmm_add_action_or_reset(&xe->drm, hw_engine_group_free, group);
-       if (err)
-               return ERR_PTR(err);
-
        return group;
 }