]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/xe: Release runtime pm for error path of xe_devcoredump_read()
authorShuicheng Lin <shuicheng.lin@intel.com>
Mon, 7 Jul 2025 00:49:14 +0000 (00:49 +0000)
committerLucas De Marchi <lucas.demarchi@intel.com>
Fri, 11 Jul 2025 03:59:38 +0000 (20:59 -0700)
xe_pm_runtime_put() is missed to be called for the error path in
xe_devcoredump_read().
Add function description comments for xe_devcoredump_read() to help
understand it.

v2: more detail function comments and refine goto logic (Matt)

Fixes: c4a2e5f865b7 ("drm/xe: Add devcoredump chunking")
Cc: stable@vger.kernel.org
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
Signed-off-by: Shuicheng Lin <shuicheng.lin@intel.com>
Signed-off-by: Matthew Brost <matthew.brost@intel.com>
Link: https://lore.kernel.org/r/20250707004911.3502904-6-shuicheng.lin@intel.com
(cherry picked from commit 017ef1228d735965419ff118fe1b89089e772c42)
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
drivers/gpu/drm/xe/xe_devcoredump.c

index 7a8af231131808235d9f7bbc8632169e1f194411..11e60d687572f8b392f060067ed90b73e3e0a308 100644 (file)
@@ -171,14 +171,32 @@ static void xe_devcoredump_snapshot_free(struct xe_devcoredump_snapshot *ss)
 
 #define XE_DEVCOREDUMP_CHUNK_MAX       (SZ_512M + SZ_1G)
 
+/**
+ * xe_devcoredump_read() - Read data from the Xe device coredump snapshot
+ * @buffer: Destination buffer to copy the coredump data into
+ * @offset: Offset in the coredump data to start reading from
+ * @count: Number of bytes to read
+ * @data: Pointer to the xe_devcoredump structure
+ * @datalen: Length of the data (unused)
+ *
+ * Reads a chunk of the coredump snapshot data into the provided buffer.
+ * If the devcoredump is smaller than 1.5 GB (XE_DEVCOREDUMP_CHUNK_MAX),
+ * it is read directly from a pre-written buffer. For larger devcoredumps,
+ * the pre-written buffer must be periodically repopulated from the snapshot
+ * state due to kmalloc size limitations.
+ *
+ * Return: Number of bytes copied on success, or a negative error code on failure.
+ */
 static ssize_t xe_devcoredump_read(char *buffer, loff_t offset,
                                   size_t count, void *data, size_t datalen)
 {
        struct xe_devcoredump *coredump = data;
        struct xe_devcoredump_snapshot *ss;
-       ssize_t byte_copied;
+       ssize_t byte_copied = 0;
        u32 chunk_offset;
        ssize_t new_chunk_position;
+       bool pm_needed = false;
+       int ret = 0;
 
        if (!coredump)
                return -ENODEV;
@@ -188,20 +206,19 @@ static ssize_t xe_devcoredump_read(char *buffer, loff_t offset,
        /* Ensure delayed work is captured before continuing */
        flush_work(&ss->work);
 
-       if (ss->read.size > XE_DEVCOREDUMP_CHUNK_MAX)
+       pm_needed = ss->read.size > XE_DEVCOREDUMP_CHUNK_MAX;
+       if (pm_needed)
                xe_pm_runtime_get(gt_to_xe(ss->gt));
 
        mutex_lock(&coredump->lock);
 
        if (!ss->read.buffer) {
-               mutex_unlock(&coredump->lock);
-               return -ENODEV;
+               ret = -ENODEV;
+               goto unlock;
        }
 
-       if (offset >= ss->read.size) {
-               mutex_unlock(&coredump->lock);
-               return 0;
-       }
+       if (offset >= ss->read.size)
+               goto unlock;
 
        new_chunk_position = div_u64_rem(offset,
                                         XE_DEVCOREDUMP_CHUNK_MAX,
@@ -221,12 +238,13 @@ static ssize_t xe_devcoredump_read(char *buffer, loff_t offset,
                ss->read.size - offset;
        memcpy(buffer, ss->read.buffer + chunk_offset, byte_copied);
 
+unlock:
        mutex_unlock(&coredump->lock);
 
-       if (ss->read.size > XE_DEVCOREDUMP_CHUNK_MAX)
+       if (pm_needed)
                xe_pm_runtime_put(gt_to_xe(ss->gt));
 
-       return byte_copied;
+       return byte_copied ? byte_copied : ret;
 }
 
 static void xe_devcoredump_free(void *data)