Skip to content

Commit 253a174

Browse files
ShuichengLinlucasdemarchi
authored andcommitted
drm/xe: Release runtime pm for error path of xe_devcoredump_read()
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: c4a2e5f ("drm/xe: Add devcoredump chunking") Cc: [email protected] Reviewed-by: Matthew Brost <[email protected]> Signed-off-by: Shuicheng Lin <[email protected]> Signed-off-by: Matthew Brost <[email protected]> Link: https://lore.kernel.org/r/[email protected] (cherry picked from commit 017ef12) Signed-off-by: Lucas De Marchi <[email protected]>
1 parent 6d33df6 commit 253a174

File tree

1 file changed

+28
-10
lines changed

1 file changed

+28
-10
lines changed

drivers/gpu/drm/xe/xe_devcoredump.c

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -171,14 +171,32 @@ static void xe_devcoredump_snapshot_free(struct xe_devcoredump_snapshot *ss)
171171

172172
#define XE_DEVCOREDUMP_CHUNK_MAX (SZ_512M + SZ_1G)
173173

174+
/**
175+
* xe_devcoredump_read() - Read data from the Xe device coredump snapshot
176+
* @buffer: Destination buffer to copy the coredump data into
177+
* @offset: Offset in the coredump data to start reading from
178+
* @count: Number of bytes to read
179+
* @data: Pointer to the xe_devcoredump structure
180+
* @datalen: Length of the data (unused)
181+
*
182+
* Reads a chunk of the coredump snapshot data into the provided buffer.
183+
* If the devcoredump is smaller than 1.5 GB (XE_DEVCOREDUMP_CHUNK_MAX),
184+
* it is read directly from a pre-written buffer. For larger devcoredumps,
185+
* the pre-written buffer must be periodically repopulated from the snapshot
186+
* state due to kmalloc size limitations.
187+
*
188+
* Return: Number of bytes copied on success, or a negative error code on failure.
189+
*/
174190
static ssize_t xe_devcoredump_read(char *buffer, loff_t offset,
175191
size_t count, void *data, size_t datalen)
176192
{
177193
struct xe_devcoredump *coredump = data;
178194
struct xe_devcoredump_snapshot *ss;
179-
ssize_t byte_copied;
195+
ssize_t byte_copied = 0;
180196
u32 chunk_offset;
181197
ssize_t new_chunk_position;
198+
bool pm_needed = false;
199+
int ret = 0;
182200

183201
if (!coredump)
184202
return -ENODEV;
@@ -188,20 +206,19 @@ static ssize_t xe_devcoredump_read(char *buffer, loff_t offset,
188206
/* Ensure delayed work is captured before continuing */
189207
flush_work(&ss->work);
190208

191-
if (ss->read.size > XE_DEVCOREDUMP_CHUNK_MAX)
209+
pm_needed = ss->read.size > XE_DEVCOREDUMP_CHUNK_MAX;
210+
if (pm_needed)
192211
xe_pm_runtime_get(gt_to_xe(ss->gt));
193212

194213
mutex_lock(&coredump->lock);
195214

196215
if (!ss->read.buffer) {
197-
mutex_unlock(&coredump->lock);
198-
return -ENODEV;
216+
ret = -ENODEV;
217+
goto unlock;
199218
}
200219

201-
if (offset >= ss->read.size) {
202-
mutex_unlock(&coredump->lock);
203-
return 0;
204-
}
220+
if (offset >= ss->read.size)
221+
goto unlock;
205222

206223
new_chunk_position = div_u64_rem(offset,
207224
XE_DEVCOREDUMP_CHUNK_MAX,
@@ -221,12 +238,13 @@ static ssize_t xe_devcoredump_read(char *buffer, loff_t offset,
221238
ss->read.size - offset;
222239
memcpy(buffer, ss->read.buffer + chunk_offset, byte_copied);
223240

241+
unlock:
224242
mutex_unlock(&coredump->lock);
225243

226-
if (ss->read.size > XE_DEVCOREDUMP_CHUNK_MAX)
244+
if (pm_needed)
227245
xe_pm_runtime_put(gt_to_xe(ss->gt));
228246

229-
return byte_copied;
247+
return byte_copied ? byte_copied : ret;
230248
}
231249

232250
static void xe_devcoredump_free(void *data)

0 commit comments

Comments
 (0)