]> www.infradead.org Git - linux.git/commitdiff
drm/xe: forcewake debugfs open fails on xe_forcewake_get failure
authorHimal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
Mon, 14 Oct 2024 07:55:59 +0000 (13:25 +0530)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Thu, 17 Oct 2024 14:17:09 +0000 (10:17 -0400)
A failure in xe_force_wake_get() no longer increments the domain's
refcount. Therefore, if xe_force_wake_get() fails during forcewake
debugfs open, return an error. This ensures there are no valid file
descriptors to close via forcewake debugfs, preventing refcount
mismanagement.

v3
- return xe_wakeref_t instead of int in xe_force_wake_get()

v5
- return unsigned int from xe_force_wake_get()

v6
- Use helper xe_force_wake_ref_has_domain()
to determine the status of the call.

Cc: Badal Nilawar <badal.nilawar@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
Reviewed-by: Badal Nilawar <badal.nilawar@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20241014075601.2324382-25-himal.prasad.ghimiray@intel.com
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
drivers/gpu/drm/xe/xe_debugfs.c

index fe4319eb13fdfb3cf6a10d5029fcbe0a8971006b..492b4877433f1678eef10440ef9d6259561eddf5 100644 (file)
@@ -90,13 +90,32 @@ static int forcewake_open(struct inode *inode, struct file *file)
 {
        struct xe_device *xe = inode->i_private;
        struct xe_gt *gt;
-       u8 id;
+       u8 id, last_gt;
+       unsigned int fw_ref;
 
        xe_pm_runtime_get(xe);
-       for_each_gt(gt, xe, id)
-               XE_WARN_ON(xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL));
+       for_each_gt(gt, xe, id) {
+               last_gt = id;
+
+               fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
+               if (!xe_force_wake_ref_has_domain(fw_ref, XE_FORCEWAKE_ALL))
+                       goto err_fw_get;
+       }
 
        return 0;
+
+err_fw_get:
+       for_each_gt(gt, xe, id) {
+               if (id < last_gt)
+                       xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL);
+               else if (id == last_gt)
+                       xe_force_wake_put(gt_to_fw(gt), fw_ref);
+               else
+                       break;
+       }
+
+       xe_pm_runtime_put(xe);
+       return -ETIMEDOUT;
 }
 
 static int forcewake_release(struct inode *inode, struct file *file)
@@ -106,7 +125,7 @@ static int forcewake_release(struct inode *inode, struct file *file)
        u8 id;
 
        for_each_gt(gt, xe, id)
-               XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
+               xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL);
        xe_pm_runtime_put(xe);
 
        return 0;