drm/xe: Fix and re-enable xe_print_blob_ascii85()
commit a9ab6591b45258b79af1cb66112fd9f83c8855da upstream.
Commit 70fb86a85dc9 ("drm/xe: Revert some changes that break a mesa
debug tool") partially reverted some changes to workaround breakage
caused to mesa tools. However, in doing so it also broke fetching the
GuC log via debugfs since xe_print_blob_ascii85() simply bails out.
The fix is to avoid the extra newlines: the devcoredump interface is
line-oriented and adding random newlines in the middle breaks it. If a
tool is able to parse it by looking at the data and checking for chars
that are out of the ascii85 space, it can still do so. A format change
that breaks the line-oriented output on devcoredump however needs better
coordination with existing tools.
v2: Add suffix description comment
v3: Reword explanation of xe_print_blob_ascii85() calling drm_puts()
in a loop
Reviewed-by: José Roberto de Souza <jose.souza@intel.com>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Julia Filipchuk <julia.filipchuk@intel.com>
Cc: José Roberto de Souza <jose.souza@intel.com>
Cc: stable@vger.kernel.org
Fixes: 70fb86a85dc9 ("drm/xe: Revert some changes that break a mesa debug tool")
Fixes: ec1455ce7e35 ("drm/xe/devcoredump: Add ASCII85 dump helper function")
Link: https://patchwork.freedesktop.org/patch/msgid/20250123202307.95103-2-jose.souza@intel.com
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
(cherry picked from commit 2c95bbf5002776117a69caed3b31c10bf7341bec)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
c963ef1840
commit
bdea9e692d
@@ -333,42 +333,34 @@ int xe_devcoredump_init(struct xe_device *xe)
|
||||
/**
|
||||
* xe_print_blob_ascii85 - print a BLOB to some useful location in ASCII85
|
||||
*
|
||||
* The output is split to multiple lines because some print targets, e.g. dmesg
|
||||
* cannot handle arbitrarily long lines. Note also that printing to dmesg in
|
||||
* piece-meal fashion is not possible, each separate call to drm_puts() has a
|
||||
* line-feed automatically added! Therefore, the entire output line must be
|
||||
* constructed in a local buffer first, then printed in one atomic output call.
|
||||
* The output is split into multiple calls to drm_puts() because some print
|
||||
* targets, e.g. dmesg, cannot handle arbitrarily long lines. These targets may
|
||||
* add newlines, as is the case with dmesg: each drm_puts() call creates a
|
||||
* separate line.
|
||||
*
|
||||
* There is also a scheduler yield call to prevent the 'task has been stuck for
|
||||
* 120s' kernel hang check feature from firing when printing to a slow target
|
||||
* such as dmesg over a serial port.
|
||||
*
|
||||
* TODO: Add compression prior to the ASCII85 encoding to shrink huge buffers down.
|
||||
*
|
||||
* @p: the printer object to output to
|
||||
* @prefix: optional prefix to add to output string
|
||||
* @suffix: optional suffix to add at the end. 0 disables it and is
|
||||
* not added to the output, which is useful when using multiple calls
|
||||
* to dump data to @p
|
||||
* @blob: the Binary Large OBject to dump out
|
||||
* @offset: offset in bytes to skip from the front of the BLOB, must be a multiple of sizeof(u32)
|
||||
* @size: the size in bytes of the BLOB, must be a multiple of sizeof(u32)
|
||||
*/
|
||||
void xe_print_blob_ascii85(struct drm_printer *p, const char *prefix,
|
||||
void xe_print_blob_ascii85(struct drm_printer *p, const char *prefix, char suffix,
|
||||
const void *blob, size_t offset, size_t size)
|
||||
{
|
||||
const u32 *blob32 = (const u32 *)blob;
|
||||
char buff[ASCII85_BUFSZ], *line_buff;
|
||||
size_t line_pos = 0;
|
||||
|
||||
/*
|
||||
* Splitting blobs across multiple lines is not compatible with the mesa
|
||||
* debug decoder tool. Note that even dropping the explicit '\n' below
|
||||
* doesn't help because the GuC log is so big some underlying implementation
|
||||
* still splits the lines at 512K characters. So just bail completely for
|
||||
* the moment.
|
||||
*/
|
||||
return;
|
||||
|
||||
#define DMESG_MAX_LINE_LEN 800
|
||||
#define MIN_SPACE (ASCII85_BUFSZ + 2) /* 85 + "\n\0" */
|
||||
/* Always leave space for the suffix char and the \0 */
|
||||
#define MIN_SPACE (ASCII85_BUFSZ + 2) /* 85 + "<suffix>\0" */
|
||||
|
||||
if (size & 3)
|
||||
drm_printf(p, "Size not word aligned: %zu", size);
|
||||
@@ -400,7 +392,6 @@ void xe_print_blob_ascii85(struct drm_printer *p, const char *prefix,
|
||||
line_pos += strlen(line_buff + line_pos);
|
||||
|
||||
if ((line_pos + MIN_SPACE) >= DMESG_MAX_LINE_LEN) {
|
||||
line_buff[line_pos++] = '\n';
|
||||
line_buff[line_pos++] = 0;
|
||||
|
||||
drm_puts(p, line_buff);
|
||||
@@ -412,10 +403,11 @@ void xe_print_blob_ascii85(struct drm_printer *p, const char *prefix,
|
||||
}
|
||||
}
|
||||
|
||||
if (line_pos) {
|
||||
line_buff[line_pos++] = '\n';
|
||||
line_buff[line_pos++] = 0;
|
||||
if (suffix)
|
||||
line_buff[line_pos++] = suffix;
|
||||
|
||||
if (line_pos) {
|
||||
line_buff[line_pos++] = 0;
|
||||
drm_puts(p, line_buff);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ static inline int xe_devcoredump_init(struct xe_device *xe)
|
||||
}
|
||||
#endif
|
||||
|
||||
void xe_print_blob_ascii85(struct drm_printer *p, const char *prefix,
|
||||
void xe_print_blob_ascii85(struct drm_printer *p, const char *prefix, char suffix,
|
||||
const void *blob, size_t offset, size_t size);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -78,7 +78,7 @@ void xe_guc_log_print(struct xe_guc_log *log, struct drm_printer *p)
|
||||
|
||||
xe_map_memcpy_from(xe, copy, &log->bo->vmap, 0, size);
|
||||
|
||||
xe_print_blob_ascii85(p, "Log data", copy, 0, size);
|
||||
xe_print_blob_ascii85(p, "Log data", '\n', copy, 0, size);
|
||||
|
||||
vfree(copy);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user