* [PATCH 0/3] drm/panic: Add kunit tests for drm_panic
@ 2025-08-21 9:49 Jocelyn Falempe
2025-08-21 9:49 ` [PATCH 1/3] drm/panic: Rename draw_panic_static_* to draw_panic_screen_* Jocelyn Falempe
` (2 more replies)
0 siblings, 3 replies; 13+ messages in thread
From: Jocelyn Falempe @ 2025-08-21 9:49 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Jocelyn Falempe, Javier Martinez Canillas,
linux-kernel, dri-devel
This series adds some kunit tests to drm_panic.
This tests draws the panic screens to different framebuffer size and
format, and ensure it doesn't crash or draw outside of the buffer.
However it doesn't check the resulting image, because it depends on
other Kconfig options, like logo, fonts, or panic colors.
The last patch is optional and a bit hacky.
It allows to dump the generated images to the logs, and then a python
script can convert it to .png files. It makes it handy to check how
the panic screen will look on different resolutions, without having
to crash a VM.
To not pollute the logs, it uses a monochrome framebuffer, compress
it with zlib, and base64 encode it.
Jocelyn Falempe (3):
drm/panic: Rename draw_panic_static_* to draw_panic_screen_*
drm/panic: Add kunit tests for drm_panic
drm/panic: Add a kconfig option to dump kunits results to png
MAINTAINERS | 1 +
drivers/gpu/drm/Kconfig.debug | 14 ++
drivers/gpu/drm/drm_panic.c | 33 +--
drivers/gpu/drm/tests/drm_panic_test.c | 275 +++++++++++++++++++++++++
scripts/kunitpanic2png.py | 53 +++++
5 files changed, 361 insertions(+), 15 deletions(-)
create mode 100644 drivers/gpu/drm/tests/drm_panic_test.c
create mode 100755 scripts/kunitpanic2png.py
base-commit: 043d9c6928b010be7902a01b5cdfa7d754535b1a
--
2.50.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 1/3] drm/panic: Rename draw_panic_static_* to draw_panic_screen_*
2025-08-21 9:49 [PATCH 0/3] drm/panic: Add kunit tests for drm_panic Jocelyn Falempe
@ 2025-08-21 9:49 ` Jocelyn Falempe
2025-08-21 9:49 ` [PATCH 2/3] drm/panic: Add kunit tests for drm_panic Jocelyn Falempe
2025-08-21 9:49 ` [PATCH 3/3] drm/panic: Add a kconfig option to dump kunits results to png Jocelyn Falempe
2 siblings, 0 replies; 13+ messages in thread
From: Jocelyn Falempe @ 2025-08-21 9:49 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Jocelyn Falempe, Javier Martinez Canillas,
linux-kernel, dri-devel
I called them "static" because the panic screen is drawn only once,
but this can be confused with the static meaning in C.
Also remove some unnecessary braces in draw_panic_dispatch().
No functionnal change.
Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
---
drivers/gpu/drm/drm_panic.c | 29 ++++++++++++++---------------
1 file changed, 14 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index 1d6312fa1429..1e06e3a18d09 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -437,7 +437,7 @@ static void drm_panic_logo_draw(struct drm_scanout_buffer *sb, struct drm_rect *
fg_color);
}
-static void draw_panic_static_user(struct drm_scanout_buffer *sb)
+static void draw_panic_screen_user(struct drm_scanout_buffer *sb)
{
u32 fg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR,
sb->format->format);
@@ -506,7 +506,7 @@ static int draw_line_with_wrap(struct drm_scanout_buffer *sb, const struct font_
* Draw the kmsg buffer to the screen, starting from the youngest message at the bottom,
* and going up until reaching the top of the screen.
*/
-static void draw_panic_static_kmsg(struct drm_scanout_buffer *sb)
+static void draw_panic_screen_kmsg(struct drm_scanout_buffer *sb)
{
u32 fg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR,
sb->format->format);
@@ -694,7 +694,7 @@ static int drm_panic_get_qr_code(u8 **qr_image)
/*
* Draw the panic message at the center of the screen, with a QR Code
*/
-static int _draw_panic_static_qr_code(struct drm_scanout_buffer *sb)
+static int _draw_panic_screen_qr_code(struct drm_scanout_buffer *sb)
{
u32 fg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR,
sb->format->format);
@@ -759,15 +759,15 @@ static int _draw_panic_static_qr_code(struct drm_scanout_buffer *sb)
return 0;
}
-static void draw_panic_static_qr_code(struct drm_scanout_buffer *sb)
+static void draw_panic_screen_qr_code(struct drm_scanout_buffer *sb)
{
- if (_draw_panic_static_qr_code(sb))
- draw_panic_static_user(sb);
+ if (_draw_panic_screen_qr_code(sb))
+ draw_panic_screen_user(sb);
}
#else
-static void draw_panic_static_qr_code(struct drm_scanout_buffer *sb)
+static void draw_panic_screen_qr_code(struct drm_scanout_buffer *sb)
{
- draw_panic_static_user(sb);
+ draw_panic_screen_user(sb);
}
static void drm_panic_qr_init(void) {};
@@ -790,13 +790,12 @@ static bool drm_panic_is_format_supported(const struct drm_format_info *format)
static void draw_panic_dispatch(struct drm_scanout_buffer *sb)
{
- if (!strcmp(drm_panic_screen, "kmsg")) {
- draw_panic_static_kmsg(sb);
- } else if (!strcmp(drm_panic_screen, "qr_code")) {
- draw_panic_static_qr_code(sb);
- } else {
- draw_panic_static_user(sb);
- }
+ if (!strcmp(drm_panic_screen, "kmsg"))
+ draw_panic_screen_kmsg(sb);
+ else if (!strcmp(drm_panic_screen, "qr_code"))
+ draw_panic_screen_qr_code(sb);
+ else
+ draw_panic_screen_user(sb);
}
static void drm_panic_set_description(const char *description)
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 2/3] drm/panic: Add kunit tests for drm_panic
2025-08-21 9:49 [PATCH 0/3] drm/panic: Add kunit tests for drm_panic Jocelyn Falempe
2025-08-21 9:49 ` [PATCH 1/3] drm/panic: Rename draw_panic_static_* to draw_panic_screen_* Jocelyn Falempe
@ 2025-08-21 9:49 ` Jocelyn Falempe
2025-08-27 9:44 ` Maxime Ripard
2025-08-21 9:49 ` [PATCH 3/3] drm/panic: Add a kconfig option to dump kunits results to png Jocelyn Falempe
2 siblings, 1 reply; 13+ messages in thread
From: Jocelyn Falempe @ 2025-08-21 9:49 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Jocelyn Falempe, Javier Martinez Canillas,
linux-kernel, dri-devel
Add kunit tests for drm_panic.
They check that drawing the panic screen doesn't crash, but they
don't check the correctness of the resulting image.
Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
---
MAINTAINERS | 1 +
drivers/gpu/drm/drm_panic.c | 4 +
drivers/gpu/drm/tests/drm_panic_test.c | 164 +++++++++++++++++++++++++
3 files changed, 169 insertions(+)
create mode 100644 drivers/gpu/drm/tests/drm_panic_test.c
diff --git a/MAINTAINERS b/MAINTAINERS
index cfa28b3470ab..285d1e27734f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8465,6 +8465,7 @@ T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: drivers/gpu/drm/drm_draw.c
F: drivers/gpu/drm/drm_draw_internal.h
F: drivers/gpu/drm/drm_panic*.c
+F: drivers/gpu/drm/tests/drm_panic_test.c
F: include/drm/drm_panic*
DRM PANIC QR CODE
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index 1e06e3a18d09..d89812ff1935 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -986,3 +986,7 @@ void drm_panic_exit(void)
{
drm_panic_qr_exit();
}
+
+#ifdef CONFIG_DRM_KUNIT_TEST
+#include "tests/drm_panic_test.c"
+#endif
diff --git a/drivers/gpu/drm/tests/drm_panic_test.c b/drivers/gpu/drm/tests/drm_panic_test.c
new file mode 100644
index 000000000000..46ff3e5e0e5d
--- /dev/null
+++ b/drivers/gpu/drm/tests/drm_panic_test.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0 or MIT
+/*
+ * Copyright (c) 2025 Red Hat.
+ * Author: Jocelyn Falempe <jfalempe@redhat.com>
+ *
+ * KUNIT tests for drm panic
+ */
+
+#include <drm/drm_fourcc.h>
+#include <drm/drm_panic.h>
+
+#include <kunit/test.h>
+
+#include <linux/units.h>
+#include <linux/vmalloc.h>
+
+struct drm_test_mode {
+ const int width;
+ const int height;
+ const u32 format;
+ void (*draw_screen)(struct drm_scanout_buffer *sb);
+ const char *fname;
+};
+
+/*
+ * Run all tests for the 3 panic screens: user, kmsg and qr_code
+ */
+#define DRM_TEST_MODE_LIST(func) \
+ DRM_PANIC_TEST_MODE(1024, 768, DRM_FORMAT_XRGB8888, func) \
+ DRM_PANIC_TEST_MODE(300, 200, DRM_FORMAT_XRGB8888, func) \
+ DRM_PANIC_TEST_MODE(1920, 1080, DRM_FORMAT_XRGB8888, func) \
+ DRM_PANIC_TEST_MODE(1024, 768, DRM_FORMAT_RGB565, func) \
+ DRM_PANIC_TEST_MODE(1024, 768, DRM_FORMAT_RGB888, func) \
+
+#define DRM_PANIC_TEST_MODE(w, h, f, name) { \
+ .width = w, \
+ .height = h, \
+ .format = f, \
+ .draw_screen = draw_panic_screen_##name, \
+ .fname = #name, \
+ }, \
+
+static const struct drm_test_mode drm_test_modes_cases[] = {
+ DRM_TEST_MODE_LIST(user)
+ DRM_TEST_MODE_LIST(kmsg)
+ DRM_TEST_MODE_LIST(qr_code)
+};
+#undef DRM_PANIC_TEST_MODE
+
+static int drm_test_panic_init(struct kunit *test)
+{
+ struct drm_scanout_buffer *priv;
+
+ priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, priv);
+
+ test->priv = priv;
+
+ drm_panic_set_description("Kunit testing");
+
+ return 0;
+}
+
+static void drm_test_panic_screen_user_map(struct kunit *test)
+{
+ struct drm_scanout_buffer *sb = test->priv;
+ const struct drm_test_mode *params = test->param_value;
+ void *fb;
+ int fb_size;
+
+ sb->format = drm_format_info(params->format);
+ fb_size = params->width * params->height * sb->format->cpp[0];
+
+ fb = vmalloc(fb_size);
+ KUNIT_ASSERT_NOT_NULL(test, fb);
+
+ iosys_map_set_vaddr(&sb->map[0], fb);
+ sb->width = params->width;
+ sb->height = params->height;
+ sb->pitch[0] = params->width * sb->format->cpp[0];
+
+ params->draw_screen(sb);
+ vfree(fb);
+}
+
+static void drm_test_panic_screen_user_page(struct kunit *test)
+{
+ struct drm_scanout_buffer *sb = test->priv;
+ const struct drm_test_mode *params = test->param_value;
+ int fb_size;
+ struct page **pages;
+ int i;
+ int npages;
+
+ sb->format = drm_format_info(params->format);
+ fb_size = params->width * params->height * sb->format->cpp[0];
+ npages = DIV_ROUND_UP(fb_size, PAGE_SIZE);
+
+ pages = kmalloc_array(npages, sizeof(struct page *), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, pages);
+
+ for (i = 0; i < npages; i++) {
+ pages[i] = alloc_page(GFP_KERNEL);
+ KUNIT_ASSERT_NOT_NULL(test, pages[i]);
+ }
+ sb->pages = pages;
+ sb->width = params->width;
+ sb->height = params->height;
+ sb->pitch[0] = params->width * sb->format->cpp[0];
+
+ params->draw_screen(sb);
+
+ for (i = 0; i < npages; i++)
+ __free_page(pages[i]);
+ kfree(pages);
+}
+
+static void drm_test_panic_set_pixel(struct drm_scanout_buffer *sb,
+ unsigned int x,
+ unsigned int y,
+ u32 color)
+{
+}
+
+static void drm_test_panic_screen_user_set_pixel(struct kunit *test)
+{
+ struct drm_scanout_buffer *sb = test->priv;
+ const struct drm_test_mode *params = test->param_value;
+
+ sb->format = drm_format_info(params->format);
+ sb->set_pixel = drm_test_panic_set_pixel;
+ sb->width = params->width;
+ sb->height = params->height;
+
+ params->draw_screen(sb);
+}
+
+static void drm_test_panic_desc(const struct drm_test_mode *t, char *desc)
+{
+ sprintf(desc, "Panic screen %s, mode: %d x %d \t%p4cc",
+ t->fname, t->width, t->height, &t->format);
+}
+
+KUNIT_ARRAY_PARAM(drm_test_panic_screen_user_map, drm_test_modes_cases, drm_test_panic_desc);
+KUNIT_ARRAY_PARAM(drm_test_panic_screen_user_page, drm_test_modes_cases, drm_test_panic_desc);
+KUNIT_ARRAY_PARAM(drm_test_panic_screen_user_set_pixel, drm_test_modes_cases, drm_test_panic_desc);
+
+static struct kunit_case drm_panic_screen_user_test[] = {
+ KUNIT_CASE_PARAM(drm_test_panic_screen_user_map,
+ drm_test_panic_screen_user_map_gen_params),
+ KUNIT_CASE_PARAM(drm_test_panic_screen_user_page,
+ drm_test_panic_screen_user_page_gen_params),
+ KUNIT_CASE_PARAM(drm_test_panic_screen_user_set_pixel,
+ drm_test_panic_screen_user_set_pixel_gen_params),
+ { }
+};
+
+static struct kunit_suite drm_panic_suite = {
+ .name = "drm_panic",
+ .init = drm_test_panic_init,
+ .test_cases = drm_panic_screen_user_test,
+};
+
+kunit_test_suite(drm_panic_suite);
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 3/3] drm/panic: Add a kconfig option to dump kunits results to png
2025-08-21 9:49 [PATCH 0/3] drm/panic: Add kunit tests for drm_panic Jocelyn Falempe
2025-08-21 9:49 ` [PATCH 1/3] drm/panic: Rename draw_panic_static_* to draw_panic_screen_* Jocelyn Falempe
2025-08-21 9:49 ` [PATCH 2/3] drm/panic: Add kunit tests for drm_panic Jocelyn Falempe
@ 2025-08-21 9:49 ` Jocelyn Falempe
2025-08-27 9:52 ` Maxime Ripard
2025-08-27 10:45 ` Thomas Zimmermann
2 siblings, 2 replies; 13+ messages in thread
From: Jocelyn Falempe @ 2025-08-21 9:49 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Jocelyn Falempe, Javier Martinez Canillas,
linux-kernel, dri-devel
This is a bit hacky, but very handy if you want to customize the
panic screen.
It allows to dump the generated images to the logs, and then a python
script can convert it to .png files. It makes it easy to check how
the panic screen will look on different resolutions, without having
to crash a VM.
To not pollute the logs, it uses a monochrome framebuffer, compress
it with zlib, and base64 encode it.
Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
---
drivers/gpu/drm/Kconfig.debug | 14 ++++
drivers/gpu/drm/tests/drm_panic_test.c | 111 +++++++++++++++++++++++++
scripts/kunitpanic2png.py | 53 ++++++++++++
3 files changed, 178 insertions(+)
create mode 100755 scripts/kunitpanic2png.py
diff --git a/drivers/gpu/drm/Kconfig.debug b/drivers/gpu/drm/Kconfig.debug
index 05dc43c0b8c5..d8ae85132d32 100644
--- a/drivers/gpu/drm/Kconfig.debug
+++ b/drivers/gpu/drm/Kconfig.debug
@@ -84,6 +84,20 @@ config DRM_KUNIT_TEST
If in doubt, say "N".
+config DRM_PANIC_KUNIT_TEST_DUMP
+ bool "Enable screen dump to logs in KUnit tests for drm_panic"
+ default n
+ depends on DRM && DRM_PANIC && DRM_KUNIT_TEST
+ select ZLIB_DEFLATE
+ help
+ This allows to dump the panic screen to the KUnit tests logs.
+ It's possible with a small python script to write pngs from the logs.
+
+ This is only to help developers customizing the drm_panic screen,
+ checking the result for different resolutions.
+
+ If in doubt, say "N"
+
config DRM_TTM_KUNIT_TEST
tristate "KUnit tests for TTM" if !KUNIT_ALL_TESTS
default n
diff --git a/drivers/gpu/drm/tests/drm_panic_test.c b/drivers/gpu/drm/tests/drm_panic_test.c
index 46ff3e5e0e5d..8cddb845aea9 100644
--- a/drivers/gpu/drm/tests/drm_panic_test.c
+++ b/drivers/gpu/drm/tests/drm_panic_test.c
@@ -115,24 +115,135 @@ static void drm_test_panic_screen_user_page(struct kunit *test)
kfree(pages);
}
+#ifdef CONFIG_DRM_PANIC_KUNIT_TEST_DUMP
+#include <linux/base64.h>
+#include <linux/delay.h>
+#include <linux/zlib.h>
+
+#define LINE_LEN 128
+
+#define COMPR_LEVEL 6
+#define WINDOW_BITS 12
+#define MEM_LEVEL 4
+
+static int compress_image(u8 *src, int size, u8 *dst)
+{
+ struct z_stream_s stream;
+
+ stream.workspace = kmalloc(zlib_deflate_workspacesize(WINDOW_BITS, MEM_LEVEL),
+ GFP_KERNEL);
+
+ if (zlib_deflateInit2(&stream, COMPR_LEVEL, Z_DEFLATED, WINDOW_BITS,
+ MEM_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK)
+ return -EINVAL;
+
+ stream.next_in = src;
+ stream.avail_in = size;
+ stream.total_in = 0;
+ stream.next_out = dst;
+ stream.avail_out = size;
+ stream.total_out = 0;
+
+ if (zlib_deflate(&stream, Z_FINISH) != Z_STREAM_END)
+ return -EINVAL;
+
+ if (zlib_deflateEnd(&stream) != Z_OK)
+ return -EINVAL;
+
+ kfree(stream.workspace);
+
+ return stream.total_out;
+}
+
+static void dump_image(u8 *fb, unsigned int width, unsigned int height)
+{
+ int len = 0;
+ char *dst;
+ char *compressed;
+ int sent = 0;
+ int stride = DIV_ROUND_UP(width, 8);
+ int size = stride * height;
+
+ compressed = vzalloc(size);
+ if (!compressed)
+ return;
+ len = compress_image(fb, size, compressed);
+ if (len < 0) {
+ pr_err("Compression failed %d", len);
+ return;
+ }
+
+ dst = vzalloc(4 * DIV_ROUND_UP(len, 3) + 1);
+ if (!dst)
+ return;
+
+ len = base64_encode(compressed, len, dst);
+
+ pr_info("KUNIT PANIC IMAGE DUMP START %dx%d", width, height);
+ while (len > 0) {
+ char save = dst[sent + LINE_LEN];
+
+ dst[sent + LINE_LEN] = 0;
+ pr_info("%s", dst + sent);
+ dst[sent + LINE_LEN] = save;
+ sent += LINE_LEN;
+ len -= LINE_LEN;
+ }
+ pr_info("KUNIT PANIC IMAGE DUMP END");
+ vfree(compressed);
+ vfree(dst);
+
+}
+
+// Ignore pixel format, use 1bit per pixel in monochrome.
static void drm_test_panic_set_pixel(struct drm_scanout_buffer *sb,
unsigned int x,
unsigned int y,
u32 color)
{
+ int stride = DIV_ROUND_UP(sb->width, 8);
+ size_t off = x / 8 + y * stride;
+ u8 shift = 7 - (x % 8);
+ u8 *fb = (u8 *) sb->private;
+
+ if (color)
+ fb[off] |= 1 << shift;
+ else
+ fb[off] &= ~(1 << shift);
}
+#else
+static void dump_image(u8 *fb, unsigned int width, unsigned int height) {}
+static void drm_test_panic_set_pixel(struct drm_scanout_buffer *sb,
+ unsigned int x,
+ unsigned int y,
+ u32 color)
+{
+}
+#endif
+
static void drm_test_panic_screen_user_set_pixel(struct kunit *test)
{
struct drm_scanout_buffer *sb = test->priv;
const struct drm_test_mode *params = test->param_value;
+ int fb_size;
+ u8 *fb;
sb->format = drm_format_info(params->format);
+ fb_size = DIV_ROUND_UP(params->width, 8) * params->height;
+
+ fb = vzalloc(fb_size);
+ KUNIT_ASSERT_NOT_NULL(test, fb);
+ sb->private = fb;
sb->set_pixel = drm_test_panic_set_pixel;
sb->width = params->width;
sb->height = params->height;
params->draw_screen(sb);
+ if (params->format == DRM_FORMAT_XRGB8888)
+ dump_image(fb, sb->width, sb->height);
+
+ vfree(fb);
}
static void drm_test_panic_desc(const struct drm_test_mode *t, char *desc)
diff --git a/scripts/kunitpanic2png.py b/scripts/kunitpanic2png.py
new file mode 100755
index 000000000000..e292afd7422c
--- /dev/null
+++ b/scripts/kunitpanic2png.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: MIT
+#
+# Copyright (c) 2025 Red Hat.
+# Author: Jocelyn Falempe <jfalempe@redhat.com>
+
+from argparse import ArgumentParser
+from PIL import Image
+import base64
+import zlib
+
+def get_dim(s):
+ (w, h) = s.split('x')
+ return (int(w), int(h))
+
+def draw_image(img_data, width, height, n_img):
+
+ decoded = base64.b64decode(img_data)
+ unzipped = zlib.decompress(decoded)
+
+ img = Image.frombytes("1", (width, height), unzipped)
+ fname = f"panic_screen_{n_img}.png"
+ img.save(fname)
+ print(f"Image {width}x{height} saved to {fname}")
+
+def main():
+ parser = ArgumentParser(
+ prog="kunitpanic2png",
+ description="Read drm_panic kunit logs and translate that to png files")
+
+ parser.add_argument("filename", help="log file from kunit, usually test.log")
+
+ parsing_img = False
+ img_data = ""
+ n_img = 0
+
+ args = parser.parse_args()
+ with open(args.filename, "r") as f:
+ for line in f.readlines():
+ if line.startswith("KUNIT PANIC IMAGE DUMP START"):
+ parsing_img = True
+ width, height = get_dim(line.split()[-1])
+ continue
+ if line.startswith("KUNIT PANIC IMAGE DUMP END"):
+ draw_image(img_data, width, height, n_img)
+ parsing_img = False
+ img_data = ""
+ n_img += 1
+ continue
+ if parsing_img:
+ img_data += line.strip()
+
+main()
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 2/3] drm/panic: Add kunit tests for drm_panic
2025-08-21 9:49 ` [PATCH 2/3] drm/panic: Add kunit tests for drm_panic Jocelyn Falempe
@ 2025-08-27 9:44 ` Maxime Ripard
2025-09-01 12:59 ` Jocelyn Falempe
0 siblings, 1 reply; 13+ messages in thread
From: Maxime Ripard @ 2025-08-27 9:44 UTC (permalink / raw)
To: Jocelyn Falempe
Cc: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Javier Martinez Canillas, linux-kernel, dri-devel
[-- Attachment #1: Type: text/plain, Size: 4052 bytes --]
Hi,
On Thu, Aug 21, 2025 at 11:49:06AM +0200, Jocelyn Falempe wrote:
> Add kunit tests for drm_panic.
> They check that drawing the panic screen doesn't crash, but they
> don't check the correctness of the resulting image.
>
> Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
> ---
> MAINTAINERS | 1 +
> drivers/gpu/drm/drm_panic.c | 4 +
> drivers/gpu/drm/tests/drm_panic_test.c | 164 +++++++++++++++++++++++++
> 3 files changed, 169 insertions(+)
> create mode 100644 drivers/gpu/drm/tests/drm_panic_test.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index cfa28b3470ab..285d1e27734f 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -8465,6 +8465,7 @@ T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
> F: drivers/gpu/drm/drm_draw.c
> F: drivers/gpu/drm/drm_draw_internal.h
> F: drivers/gpu/drm/drm_panic*.c
> +F: drivers/gpu/drm/tests/drm_panic_test.c
> F: include/drm/drm_panic*
>
> DRM PANIC QR CODE
> diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
> index 1e06e3a18d09..d89812ff1935 100644
> --- a/drivers/gpu/drm/drm_panic.c
> +++ b/drivers/gpu/drm/drm_panic.c
> @@ -986,3 +986,7 @@ void drm_panic_exit(void)
> {
> drm_panic_qr_exit();
> }
> +
> +#ifdef CONFIG_DRM_KUNIT_TEST
> +#include "tests/drm_panic_test.c"
> +#endif
> diff --git a/drivers/gpu/drm/tests/drm_panic_test.c b/drivers/gpu/drm/tests/drm_panic_test.c
> new file mode 100644
> index 000000000000..46ff3e5e0e5d
> --- /dev/null
> +++ b/drivers/gpu/drm/tests/drm_panic_test.c
> @@ -0,0 +1,164 @@
> +// SPDX-License-Identifier: GPL-2.0 or MIT
> +/*
> + * Copyright (c) 2025 Red Hat.
> + * Author: Jocelyn Falempe <jfalempe@redhat.com>
> + *
> + * KUNIT tests for drm panic
> + */
> +
> +#include <drm/drm_fourcc.h>
> +#include <drm/drm_panic.h>
> +
> +#include <kunit/test.h>
> +
> +#include <linux/units.h>
> +#include <linux/vmalloc.h>
> +
> +struct drm_test_mode {
> + const int width;
> + const int height;
> + const u32 format;
> + void (*draw_screen)(struct drm_scanout_buffer *sb);
> + const char *fname;
> +};
> +
> +/*
> + * Run all tests for the 3 panic screens: user, kmsg and qr_code
> + */
> +#define DRM_TEST_MODE_LIST(func) \
> + DRM_PANIC_TEST_MODE(1024, 768, DRM_FORMAT_XRGB8888, func) \
> + DRM_PANIC_TEST_MODE(300, 200, DRM_FORMAT_XRGB8888, func) \
> + DRM_PANIC_TEST_MODE(1920, 1080, DRM_FORMAT_XRGB8888, func) \
> + DRM_PANIC_TEST_MODE(1024, 768, DRM_FORMAT_RGB565, func) \
> + DRM_PANIC_TEST_MODE(1024, 768, DRM_FORMAT_RGB888, func) \
> +
> +#define DRM_PANIC_TEST_MODE(w, h, f, name) { \
> + .width = w, \
> + .height = h, \
> + .format = f, \
> + .draw_screen = draw_panic_screen_##name, \
> + .fname = #name, \
> + }, \
> +
> +static const struct drm_test_mode drm_test_modes_cases[] = {
> + DRM_TEST_MODE_LIST(user)
> + DRM_TEST_MODE_LIST(kmsg)
> + DRM_TEST_MODE_LIST(qr_code)
> +};
> +#undef DRM_PANIC_TEST_MODE
> +
> +static int drm_test_panic_init(struct kunit *test)
> +{
> + struct drm_scanout_buffer *priv;
> +
> + priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
> + KUNIT_ASSERT_NOT_NULL(test, priv);
> +
> + test->priv = priv;
> +
> + drm_panic_set_description("Kunit testing");
> +
> + return 0;
> +}
> +
> +static void drm_test_panic_screen_user_map(struct kunit *test)
> +{
> + struct drm_scanout_buffer *sb = test->priv;
> + const struct drm_test_mode *params = test->param_value;
> + void *fb;
> + int fb_size;
> +
> + sb->format = drm_format_info(params->format);
> + fb_size = params->width * params->height * sb->format->cpp[0];
> +
> + fb = vmalloc(fb_size);
> + KUNIT_ASSERT_NOT_NULL(test, fb);
> +
> + iosys_map_set_vaddr(&sb->map[0], fb);
> + sb->width = params->width;
> + sb->height = params->height;
> + sb->pitch[0] = params->width * sb->format->cpp[0];
> +
> + params->draw_screen(sb);
> + vfree(fb);
> +}
You need to document what you're testing, and what the expected result
is.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/3] drm/panic: Add a kconfig option to dump kunits results to png
2025-08-21 9:49 ` [PATCH 3/3] drm/panic: Add a kconfig option to dump kunits results to png Jocelyn Falempe
@ 2025-08-27 9:52 ` Maxime Ripard
2025-09-01 13:16 ` Jocelyn Falempe
2025-08-27 10:45 ` Thomas Zimmermann
1 sibling, 1 reply; 13+ messages in thread
From: Maxime Ripard @ 2025-08-27 9:52 UTC (permalink / raw)
To: Jocelyn Falempe
Cc: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Javier Martinez Canillas, linux-kernel, dri-devel
[-- Attachment #1: Type: text/plain, Size: 4279 bytes --]
Hi,
On Thu, Aug 21, 2025 at 11:49:07AM +0200, Jocelyn Falempe wrote:
> This is a bit hacky, but very handy if you want to customize the
> panic screen.
> It allows to dump the generated images to the logs, and then a python
> script can convert it to .png files. It makes it easy to check how
> the panic screen will look on different resolutions, without having
> to crash a VM.
> To not pollute the logs, it uses a monochrome framebuffer, compress
> it with zlib, and base64 encode it.
>
> Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
> ---
> drivers/gpu/drm/Kconfig.debug | 14 ++++
> drivers/gpu/drm/tests/drm_panic_test.c | 111 +++++++++++++++++++++++++
> scripts/kunitpanic2png.py | 53 ++++++++++++
> 3 files changed, 178 insertions(+)
> create mode 100755 scripts/kunitpanic2png.py
>
> diff --git a/drivers/gpu/drm/Kconfig.debug b/drivers/gpu/drm/Kconfig.debug
> index 05dc43c0b8c5..d8ae85132d32 100644
> --- a/drivers/gpu/drm/Kconfig.debug
> +++ b/drivers/gpu/drm/Kconfig.debug
> @@ -84,6 +84,20 @@ config DRM_KUNIT_TEST
>
> If in doubt, say "N".
>
> +config DRM_PANIC_KUNIT_TEST_DUMP
> + bool "Enable screen dump to logs in KUnit tests for drm_panic"
> + default n
> + depends on DRM && DRM_PANIC && DRM_KUNIT_TEST
> + select ZLIB_DEFLATE
> + help
> + This allows to dump the panic screen to the KUnit tests logs.
> + It's possible with a small python script to write pngs from the logs.
> +
> + This is only to help developers customizing the drm_panic screen,
> + checking the result for different resolutions.
> +
> + If in doubt, say "N"
> +
> config DRM_TTM_KUNIT_TEST
> tristate "KUnit tests for TTM" if !KUNIT_ALL_TESTS
> default n
> diff --git a/drivers/gpu/drm/tests/drm_panic_test.c b/drivers/gpu/drm/tests/drm_panic_test.c
> index 46ff3e5e0e5d..8cddb845aea9 100644
> --- a/drivers/gpu/drm/tests/drm_panic_test.c
> +++ b/drivers/gpu/drm/tests/drm_panic_test.c
> @@ -115,24 +115,135 @@ static void drm_test_panic_screen_user_page(struct kunit *test)
> kfree(pages);
> }
>
> +#ifdef CONFIG_DRM_PANIC_KUNIT_TEST_DUMP
> +#include <linux/base64.h>
> +#include <linux/delay.h>
> +#include <linux/zlib.h>
> +
> +#define LINE_LEN 128
> +
> +#define COMPR_LEVEL 6
> +#define WINDOW_BITS 12
> +#define MEM_LEVEL 4
> +
> +static int compress_image(u8 *src, int size, u8 *dst)
> +{
> + struct z_stream_s stream;
> +
> + stream.workspace = kmalloc(zlib_deflate_workspacesize(WINDOW_BITS, MEM_LEVEL),
> + GFP_KERNEL);
> +
> + if (zlib_deflateInit2(&stream, COMPR_LEVEL, Z_DEFLATED, WINDOW_BITS,
> + MEM_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK)
> + return -EINVAL;
> +
> + stream.next_in = src;
> + stream.avail_in = size;
> + stream.total_in = 0;
> + stream.next_out = dst;
> + stream.avail_out = size;
> + stream.total_out = 0;
> +
> + if (zlib_deflate(&stream, Z_FINISH) != Z_STREAM_END)
> + return -EINVAL;
> +
> + if (zlib_deflateEnd(&stream) != Z_OK)
> + return -EINVAL;
> +
> + kfree(stream.workspace);
> +
> + return stream.total_out;
> +}
> +
> +static void dump_image(u8 *fb, unsigned int width, unsigned int height)
> +{
> + int len = 0;
> + char *dst;
> + char *compressed;
> + int sent = 0;
> + int stride = DIV_ROUND_UP(width, 8);
> + int size = stride * height;
> +
> + compressed = vzalloc(size);
> + if (!compressed)
> + return;
> + len = compress_image(fb, size, compressed);
> + if (len < 0) {
> + pr_err("Compression failed %d", len);
> + return;
> + }
> +
> + dst = vzalloc(4 * DIV_ROUND_UP(len, 3) + 1);
> + if (!dst)
> + return;
> +
> + len = base64_encode(compressed, len, dst);
> +
> + pr_info("KUNIT PANIC IMAGE DUMP START %dx%d", width, height);
> + while (len > 0) {
> + char save = dst[sent + LINE_LEN];
> +
> + dst[sent + LINE_LEN] = 0;
> + pr_info("%s", dst + sent);
> + dst[sent + LINE_LEN] = save;
> + sent += LINE_LEN;
> + len -= LINE_LEN;
> + }
> + pr_info("KUNIT PANIC IMAGE DUMP END");
The kunit test output format is defined, and we should probably use a
diagnostic line for this:
https://docs.kernel.org/dev-tools/ktap.html#diagnostic-lines
We should probably cc the kunit maintainers about this too.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/3] drm/panic: Add a kconfig option to dump kunits results to png
2025-08-21 9:49 ` [PATCH 3/3] drm/panic: Add a kconfig option to dump kunits results to png Jocelyn Falempe
2025-08-27 9:52 ` Maxime Ripard
@ 2025-08-27 10:45 ` Thomas Zimmermann
2025-09-01 13:04 ` Jocelyn Falempe
1 sibling, 1 reply; 13+ messages in thread
From: Thomas Zimmermann @ 2025-08-27 10:45 UTC (permalink / raw)
To: Jocelyn Falempe, Maarten Lankhorst, Maxime Ripard, David Airlie,
Simona Vetter, Javier Martinez Canillas, linux-kernel, dri-devel
Hi
Am 21.08.25 um 11:49 schrieb Jocelyn Falempe:
> This is a bit hacky, but very handy if you want to customize the
> panic screen.
> It allows to dump the generated images to the logs, and then a python
> script can convert it to .png files. It makes it easy to check how
> the panic screen will look on different resolutions, without having
> to crash a VM.
> To not pollute the logs, it uses a monochrome framebuffer, compress
> it with zlib, and base64 encode it.
May I suggest to export the raw image via debugfs? Debugfs can also
export additional information in additional files, such as
width/height/stride/format. This could provide the real/last image on
the fly, simply by reading the files. No workarounds or encodings needed.
Best regards
Thomas
>
> Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
> ---
> drivers/gpu/drm/Kconfig.debug | 14 ++++
> drivers/gpu/drm/tests/drm_panic_test.c | 111 +++++++++++++++++++++++++
> scripts/kunitpanic2png.py | 53 ++++++++++++
> 3 files changed, 178 insertions(+)
> create mode 100755 scripts/kunitpanic2png.py
>
> diff --git a/drivers/gpu/drm/Kconfig.debug b/drivers/gpu/drm/Kconfig.debug
> index 05dc43c0b8c5..d8ae85132d32 100644
> --- a/drivers/gpu/drm/Kconfig.debug
> +++ b/drivers/gpu/drm/Kconfig.debug
> @@ -84,6 +84,20 @@ config DRM_KUNIT_TEST
>
> If in doubt, say "N".
>
> +config DRM_PANIC_KUNIT_TEST_DUMP
> + bool "Enable screen dump to logs in KUnit tests for drm_panic"
> + default n
> + depends on DRM && DRM_PANIC && DRM_KUNIT_TEST
> + select ZLIB_DEFLATE
> + help
> + This allows to dump the panic screen to the KUnit tests logs.
> + It's possible with a small python script to write pngs from the logs.
> +
> + This is only to help developers customizing the drm_panic screen,
> + checking the result for different resolutions.
> +
> + If in doubt, say "N"
> +
> config DRM_TTM_KUNIT_TEST
> tristate "KUnit tests for TTM" if !KUNIT_ALL_TESTS
> default n
> diff --git a/drivers/gpu/drm/tests/drm_panic_test.c b/drivers/gpu/drm/tests/drm_panic_test.c
> index 46ff3e5e0e5d..8cddb845aea9 100644
> --- a/drivers/gpu/drm/tests/drm_panic_test.c
> +++ b/drivers/gpu/drm/tests/drm_panic_test.c
> @@ -115,24 +115,135 @@ static void drm_test_panic_screen_user_page(struct kunit *test)
> kfree(pages);
> }
>
> +#ifdef CONFIG_DRM_PANIC_KUNIT_TEST_DUMP
> +#include <linux/base64.h>
> +#include <linux/delay.h>
> +#include <linux/zlib.h>
> +
> +#define LINE_LEN 128
> +
> +#define COMPR_LEVEL 6
> +#define WINDOW_BITS 12
> +#define MEM_LEVEL 4
> +
> +static int compress_image(u8 *src, int size, u8 *dst)
> +{
> + struct z_stream_s stream;
> +
> + stream.workspace = kmalloc(zlib_deflate_workspacesize(WINDOW_BITS, MEM_LEVEL),
> + GFP_KERNEL);
> +
> + if (zlib_deflateInit2(&stream, COMPR_LEVEL, Z_DEFLATED, WINDOW_BITS,
> + MEM_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK)
> + return -EINVAL;
> +
> + stream.next_in = src;
> + stream.avail_in = size;
> + stream.total_in = 0;
> + stream.next_out = dst;
> + stream.avail_out = size;
> + stream.total_out = 0;
> +
> + if (zlib_deflate(&stream, Z_FINISH) != Z_STREAM_END)
> + return -EINVAL;
> +
> + if (zlib_deflateEnd(&stream) != Z_OK)
> + return -EINVAL;
> +
> + kfree(stream.workspace);
> +
> + return stream.total_out;
> +}
> +
> +static void dump_image(u8 *fb, unsigned int width, unsigned int height)
> +{
> + int len = 0;
> + char *dst;
> + char *compressed;
> + int sent = 0;
> + int stride = DIV_ROUND_UP(width, 8);
> + int size = stride * height;
> +
> + compressed = vzalloc(size);
> + if (!compressed)
> + return;
> + len = compress_image(fb, size, compressed);
> + if (len < 0) {
> + pr_err("Compression failed %d", len);
> + return;
> + }
> +
> + dst = vzalloc(4 * DIV_ROUND_UP(len, 3) + 1);
> + if (!dst)
> + return;
> +
> + len = base64_encode(compressed, len, dst);
> +
> + pr_info("KUNIT PANIC IMAGE DUMP START %dx%d", width, height);
> + while (len > 0) {
> + char save = dst[sent + LINE_LEN];
> +
> + dst[sent + LINE_LEN] = 0;
> + pr_info("%s", dst + sent);
> + dst[sent + LINE_LEN] = save;
> + sent += LINE_LEN;
> + len -= LINE_LEN;
> + }
> + pr_info("KUNIT PANIC IMAGE DUMP END");
> + vfree(compressed);
> + vfree(dst);
> +
> +}
> +
> +// Ignore pixel format, use 1bit per pixel in monochrome.
> static void drm_test_panic_set_pixel(struct drm_scanout_buffer *sb,
> unsigned int x,
> unsigned int y,
> u32 color)
> {
> + int stride = DIV_ROUND_UP(sb->width, 8);
> + size_t off = x / 8 + y * stride;
> + u8 shift = 7 - (x % 8);
> + u8 *fb = (u8 *) sb->private;
> +
> + if (color)
> + fb[off] |= 1 << shift;
> + else
> + fb[off] &= ~(1 << shift);
> }
>
> +#else
> +static void dump_image(u8 *fb, unsigned int width, unsigned int height) {}
> +static void drm_test_panic_set_pixel(struct drm_scanout_buffer *sb,
> + unsigned int x,
> + unsigned int y,
> + u32 color)
> +{
> +}
> +#endif
> +
> static void drm_test_panic_screen_user_set_pixel(struct kunit *test)
> {
> struct drm_scanout_buffer *sb = test->priv;
> const struct drm_test_mode *params = test->param_value;
> + int fb_size;
> + u8 *fb;
>
> sb->format = drm_format_info(params->format);
> + fb_size = DIV_ROUND_UP(params->width, 8) * params->height;
> +
> + fb = vzalloc(fb_size);
> + KUNIT_ASSERT_NOT_NULL(test, fb);
> + sb->private = fb;
> sb->set_pixel = drm_test_panic_set_pixel;
> sb->width = params->width;
> sb->height = params->height;
>
> params->draw_screen(sb);
> + if (params->format == DRM_FORMAT_XRGB8888)
> + dump_image(fb, sb->width, sb->height);
> +
> + vfree(fb);
> }
>
> static void drm_test_panic_desc(const struct drm_test_mode *t, char *desc)
> diff --git a/scripts/kunitpanic2png.py b/scripts/kunitpanic2png.py
> new file mode 100755
> index 000000000000..e292afd7422c
> --- /dev/null
> +++ b/scripts/kunitpanic2png.py
> @@ -0,0 +1,53 @@
> +#!/usr/bin/env python3
> +# SPDX-License-Identifier: MIT
> +#
> +# Copyright (c) 2025 Red Hat.
> +# Author: Jocelyn Falempe <jfalempe@redhat.com>
> +
> +from argparse import ArgumentParser
> +from PIL import Image
> +import base64
> +import zlib
> +
> +def get_dim(s):
> + (w, h) = s.split('x')
> + return (int(w), int(h))
> +
> +def draw_image(img_data, width, height, n_img):
> +
> + decoded = base64.b64decode(img_data)
> + unzipped = zlib.decompress(decoded)
> +
> + img = Image.frombytes("1", (width, height), unzipped)
> + fname = f"panic_screen_{n_img}.png"
> + img.save(fname)
> + print(f"Image {width}x{height} saved to {fname}")
> +
> +def main():
> + parser = ArgumentParser(
> + prog="kunitpanic2png",
> + description="Read drm_panic kunit logs and translate that to png files")
> +
> + parser.add_argument("filename", help="log file from kunit, usually test.log")
> +
> + parsing_img = False
> + img_data = ""
> + n_img = 0
> +
> + args = parser.parse_args()
> + with open(args.filename, "r") as f:
> + for line in f.readlines():
> + if line.startswith("KUNIT PANIC IMAGE DUMP START"):
> + parsing_img = True
> + width, height = get_dim(line.split()[-1])
> + continue
> + if line.startswith("KUNIT PANIC IMAGE DUMP END"):
> + draw_image(img_data, width, height, n_img)
> + parsing_img = False
> + img_data = ""
> + n_img += 1
> + continue
> + if parsing_img:
> + img_data += line.strip()
> +
> +main()
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/3] drm/panic: Add kunit tests for drm_panic
2025-08-27 9:44 ` Maxime Ripard
@ 2025-09-01 12:59 ` Jocelyn Falempe
0 siblings, 0 replies; 13+ messages in thread
From: Jocelyn Falempe @ 2025-09-01 12:59 UTC (permalink / raw)
To: Maxime Ripard
Cc: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Javier Martinez Canillas, linux-kernel, dri-devel
On 27/08/2025 11:44, Maxime Ripard wrote:
> Hi,
>
> On Thu, Aug 21, 2025 at 11:49:06AM +0200, Jocelyn Falempe wrote:
>> Add kunit tests for drm_panic.
>> They check that drawing the panic screen doesn't crash, but they
>> don't check the correctness of the resulting image.
>>
>> Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
>> ---
>> MAINTAINERS | 1 +
>> drivers/gpu/drm/drm_panic.c | 4 +
>> drivers/gpu/drm/tests/drm_panic_test.c | 164 +++++++++++++++++++++++++
>> 3 files changed, 169 insertions(+)
>> create mode 100644 drivers/gpu/drm/tests/drm_panic_test.c
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index cfa28b3470ab..285d1e27734f 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -8465,6 +8465,7 @@ T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
>> F: drivers/gpu/drm/drm_draw.c
>> F: drivers/gpu/drm/drm_draw_internal.h
>> F: drivers/gpu/drm/drm_panic*.c
>> +F: drivers/gpu/drm/tests/drm_panic_test.c
>> F: include/drm/drm_panic*
>>
>> DRM PANIC QR CODE
>> diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
>> index 1e06e3a18d09..d89812ff1935 100644
>> --- a/drivers/gpu/drm/drm_panic.c
>> +++ b/drivers/gpu/drm/drm_panic.c
>> @@ -986,3 +986,7 @@ void drm_panic_exit(void)
>> {
>> drm_panic_qr_exit();
>> }
>> +
>> +#ifdef CONFIG_DRM_KUNIT_TEST
>> +#include "tests/drm_panic_test.c"
>> +#endif
>> diff --git a/drivers/gpu/drm/tests/drm_panic_test.c b/drivers/gpu/drm/tests/drm_panic_test.c
>> new file mode 100644
>> index 000000000000..46ff3e5e0e5d
>> --- /dev/null
>> +++ b/drivers/gpu/drm/tests/drm_panic_test.c
>> @@ -0,0 +1,164 @@
>> +// SPDX-License-Identifier: GPL-2.0 or MIT
>> +/*
>> + * Copyright (c) 2025 Red Hat.
>> + * Author: Jocelyn Falempe <jfalempe@redhat.com>
>> + *
>> + * KUNIT tests for drm panic
>> + */
>> +
>> +#include <drm/drm_fourcc.h>
>> +#include <drm/drm_panic.h>
>> +
>> +#include <kunit/test.h>
>> +
>> +#include <linux/units.h>
>> +#include <linux/vmalloc.h>
>> +
>> +struct drm_test_mode {
>> + const int width;
>> + const int height;
>> + const u32 format;
>> + void (*draw_screen)(struct drm_scanout_buffer *sb);
>> + const char *fname;
>> +};
>> +
>> +/*
>> + * Run all tests for the 3 panic screens: user, kmsg and qr_code
>> + */
>> +#define DRM_TEST_MODE_LIST(func) \
>> + DRM_PANIC_TEST_MODE(1024, 768, DRM_FORMAT_XRGB8888, func) \
>> + DRM_PANIC_TEST_MODE(300, 200, DRM_FORMAT_XRGB8888, func) \
>> + DRM_PANIC_TEST_MODE(1920, 1080, DRM_FORMAT_XRGB8888, func) \
>> + DRM_PANIC_TEST_MODE(1024, 768, DRM_FORMAT_RGB565, func) \
>> + DRM_PANIC_TEST_MODE(1024, 768, DRM_FORMAT_RGB888, func) \
>> +
>> +#define DRM_PANIC_TEST_MODE(w, h, f, name) { \
>> + .width = w, \
>> + .height = h, \
>> + .format = f, \
>> + .draw_screen = draw_panic_screen_##name, \
>> + .fname = #name, \
>> + }, \
>> +
>> +static const struct drm_test_mode drm_test_modes_cases[] = {
>> + DRM_TEST_MODE_LIST(user)
>> + DRM_TEST_MODE_LIST(kmsg)
>> + DRM_TEST_MODE_LIST(qr_code)
>> +};
>> +#undef DRM_PANIC_TEST_MODE
>> +
>> +static int drm_test_panic_init(struct kunit *test)
>> +{
>> + struct drm_scanout_buffer *priv;
>> +
>> + priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
>> + KUNIT_ASSERT_NOT_NULL(test, priv);
>> +
>> + test->priv = priv;
>> +
>> + drm_panic_set_description("Kunit testing");
>> +
>> + return 0;
>> +}
>> +
>> +static void drm_test_panic_screen_user_map(struct kunit *test)
>> +{
>> + struct drm_scanout_buffer *sb = test->priv;
>> + const struct drm_test_mode *params = test->param_value;
>> + void *fb;
>> + int fb_size;
>> +
>> + sb->format = drm_format_info(params->format);
>> + fb_size = params->width * params->height * sb->format->cpp[0];
>> +
>> + fb = vmalloc(fb_size);
>> + KUNIT_ASSERT_NOT_NULL(test, fb);
>> +
>> + iosys_map_set_vaddr(&sb->map[0], fb);
>> + sb->width = params->width;
>> + sb->height = params->height;
>> + sb->pitch[0] = params->width * sb->format->cpp[0];
>> +
>> + params->draw_screen(sb);
>> + vfree(fb);
>> +}
>
> You need to document what you're testing, and what the expected result
> is.
Sure, I will add some comments.
I think I can also add a few checks, as this doesn't check the result at
all.
>
> Maxime
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/3] drm/panic: Add a kconfig option to dump kunits results to png
2025-08-27 10:45 ` Thomas Zimmermann
@ 2025-09-01 13:04 ` Jocelyn Falempe
2025-09-02 16:58 ` Maxime Ripard
0 siblings, 1 reply; 13+ messages in thread
From: Jocelyn Falempe @ 2025-09-01 13:04 UTC (permalink / raw)
To: Thomas Zimmermann, Maarten Lankhorst, Maxime Ripard, David Airlie,
Simona Vetter, Javier Martinez Canillas, linux-kernel, dri-devel
On 27/08/2025 12:45, Thomas Zimmermann wrote:
> Hi
>
> Am 21.08.25 um 11:49 schrieb Jocelyn Falempe:
>> This is a bit hacky, but very handy if you want to customize the
>> panic screen.
>> It allows to dump the generated images to the logs, and then a python
>> script can convert it to .png files. It makes it easy to check how
>> the panic screen will look on different resolutions, without having
>> to crash a VM.
>> To not pollute the logs, it uses a monochrome framebuffer, compress
>> it with zlib, and base64 encode it.
>
> May I suggest to export the raw image via debugfs? Debugfs can also
> export additional information in additional files, such as width/height/
> stride/format. This could provide the real/last image on the fly, simply
> by reading the files. No workarounds or encodings needed.
I'm looking into that. The difficulty is to get the debugfs content
outside of the test kernel. As I'm using a uml kernel for testing, I
will need a special initrd, and a way to share files with the host.
Best regards,
--
Jocelyn
>
> Best regards
> Thomas
>
>>
>> Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
>> ---
>> drivers/gpu/drm/Kconfig.debug | 14 ++++
>> drivers/gpu/drm/tests/drm_panic_test.c | 111 +++++++++++++++++++++++++
>> scripts/kunitpanic2png.py | 53 ++++++++++++
>> 3 files changed, 178 insertions(+)
>> create mode 100755 scripts/kunitpanic2png.py
>>
>> diff --git a/drivers/gpu/drm/Kconfig.debug b/drivers/gpu/drm/
>> Kconfig.debug
>> index 05dc43c0b8c5..d8ae85132d32 100644
>> --- a/drivers/gpu/drm/Kconfig.debug
>> +++ b/drivers/gpu/drm/Kconfig.debug
>> @@ -84,6 +84,20 @@ config DRM_KUNIT_TEST
>> If in doubt, say "N".
>> +config DRM_PANIC_KUNIT_TEST_DUMP
>> + bool "Enable screen dump to logs in KUnit tests for drm_panic"
>> + default n
>> + depends on DRM && DRM_PANIC && DRM_KUNIT_TEST
>> + select ZLIB_DEFLATE
>> + help
>> + This allows to dump the panic screen to the KUnit tests logs.
>> + It's possible with a small python script to write pngs from the
>> logs.
>> +
>> + This is only to help developers customizing the drm_panic screen,
>> + checking the result for different resolutions.
>> +
>> + If in doubt, say "N"
>> +
>> config DRM_TTM_KUNIT_TEST
>> tristate "KUnit tests for TTM" if !KUNIT_ALL_TESTS
>> default n
>> diff --git a/drivers/gpu/drm/tests/drm_panic_test.c b/drivers/gpu/drm/
>> tests/drm_panic_test.c
>> index 46ff3e5e0e5d..8cddb845aea9 100644
>> --- a/drivers/gpu/drm/tests/drm_panic_test.c
>> +++ b/drivers/gpu/drm/tests/drm_panic_test.c
>> @@ -115,24 +115,135 @@ static void
>> drm_test_panic_screen_user_page(struct kunit *test)
>> kfree(pages);
>> }
>> +#ifdef CONFIG_DRM_PANIC_KUNIT_TEST_DUMP
>> +#include <linux/base64.h>
>> +#include <linux/delay.h>
>> +#include <linux/zlib.h>
>> +
>> +#define LINE_LEN 128
>> +
>> +#define COMPR_LEVEL 6
>> +#define WINDOW_BITS 12
>> +#define MEM_LEVEL 4
>> +
>> +static int compress_image(u8 *src, int size, u8 *dst)
>> +{
>> + struct z_stream_s stream;
>> +
>> + stream.workspace =
>> kmalloc(zlib_deflate_workspacesize(WINDOW_BITS, MEM_LEVEL),
>> + GFP_KERNEL);
>> +
>> + if (zlib_deflateInit2(&stream, COMPR_LEVEL, Z_DEFLATED, WINDOW_BITS,
>> + MEM_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK)
>> + return -EINVAL;
>> +
>> + stream.next_in = src;
>> + stream.avail_in = size;
>> + stream.total_in = 0;
>> + stream.next_out = dst;
>> + stream.avail_out = size;
>> + stream.total_out = 0;
>> +
>> + if (zlib_deflate(&stream, Z_FINISH) != Z_STREAM_END)
>> + return -EINVAL;
>> +
>> + if (zlib_deflateEnd(&stream) != Z_OK)
>> + return -EINVAL;
>> +
>> + kfree(stream.workspace);
>> +
>> + return stream.total_out;
>> +}
>> +
>> +static void dump_image(u8 *fb, unsigned int width, unsigned int height)
>> +{
>> + int len = 0;
>> + char *dst;
>> + char *compressed;
>> + int sent = 0;
>> + int stride = DIV_ROUND_UP(width, 8);
>> + int size = stride * height;
>> +
>> + compressed = vzalloc(size);
>> + if (!compressed)
>> + return;
>> + len = compress_image(fb, size, compressed);
>> + if (len < 0) {
>> + pr_err("Compression failed %d", len);
>> + return;
>> + }
>> +
>> + dst = vzalloc(4 * DIV_ROUND_UP(len, 3) + 1);
>> + if (!dst)
>> + return;
>> +
>> + len = base64_encode(compressed, len, dst);
>> +
>> + pr_info("KUNIT PANIC IMAGE DUMP START %dx%d", width, height);
>> + while (len > 0) {
>> + char save = dst[sent + LINE_LEN];
>> +
>> + dst[sent + LINE_LEN] = 0;
>> + pr_info("%s", dst + sent);
>> + dst[sent + LINE_LEN] = save;
>> + sent += LINE_LEN;
>> + len -= LINE_LEN;
>> + }
>> + pr_info("KUNIT PANIC IMAGE DUMP END");
>> + vfree(compressed);
>> + vfree(dst);
>> +
>> +}
>> +
>> +// Ignore pixel format, use 1bit per pixel in monochrome.
>> static void drm_test_panic_set_pixel(struct drm_scanout_buffer *sb,
>> unsigned int x,
>> unsigned int y,
>> u32 color)
>> {
>> + int stride = DIV_ROUND_UP(sb->width, 8);
>> + size_t off = x / 8 + y * stride;
>> + u8 shift = 7 - (x % 8);
>> + u8 *fb = (u8 *) sb->private;
>> +
>> + if (color)
>> + fb[off] |= 1 << shift;
>> + else
>> + fb[off] &= ~(1 << shift);
>> }
>> +#else
>> +static void dump_image(u8 *fb, unsigned int width, unsigned int
>> height) {}
>> +static void drm_test_panic_set_pixel(struct drm_scanout_buffer *sb,
>> + unsigned int x,
>> + unsigned int y,
>> + u32 color)
>> +{
>> +}
>> +#endif
>> +
>> static void drm_test_panic_screen_user_set_pixel(struct kunit *test)
>> {
>> struct drm_scanout_buffer *sb = test->priv;
>> const struct drm_test_mode *params = test->param_value;
>> + int fb_size;
>> + u8 *fb;
>> sb->format = drm_format_info(params->format);
>> + fb_size = DIV_ROUND_UP(params->width, 8) * params->height;
>> +
>> + fb = vzalloc(fb_size);
>> + KUNIT_ASSERT_NOT_NULL(test, fb);
>> + sb->private = fb;
>> sb->set_pixel = drm_test_panic_set_pixel;
>> sb->width = params->width;
>> sb->height = params->height;
>> params->draw_screen(sb);
>> + if (params->format == DRM_FORMAT_XRGB8888)
>> + dump_image(fb, sb->width, sb->height);
>> +
>> + vfree(fb);
>> }
>> static void drm_test_panic_desc(const struct drm_test_mode *t, char
>> *desc)
>> diff --git a/scripts/kunitpanic2png.py b/scripts/kunitpanic2png.py
>> new file mode 100755
>> index 000000000000..e292afd7422c
>> --- /dev/null
>> +++ b/scripts/kunitpanic2png.py
>> @@ -0,0 +1,53 @@
>> +#!/usr/bin/env python3
>> +# SPDX-License-Identifier: MIT
>> +#
>> +# Copyright (c) 2025 Red Hat.
>> +# Author: Jocelyn Falempe <jfalempe@redhat.com>
>> +
>> +from argparse import ArgumentParser
>> +from PIL import Image
>> +import base64
>> +import zlib
>> +
>> +def get_dim(s):
>> + (w, h) = s.split('x')
>> + return (int(w), int(h))
>> +
>> +def draw_image(img_data, width, height, n_img):
>> +
>> + decoded = base64.b64decode(img_data)
>> + unzipped = zlib.decompress(decoded)
>> +
>> + img = Image.frombytes("1", (width, height), unzipped)
>> + fname = f"panic_screen_{n_img}.png"
>> + img.save(fname)
>> + print(f"Image {width}x{height} saved to {fname}")
>> +
>> +def main():
>> + parser = ArgumentParser(
>> + prog="kunitpanic2png",
>> + description="Read drm_panic kunit logs and translate that to
>> png files")
>> +
>> + parser.add_argument("filename", help="log file from kunit,
>> usually test.log")
>> +
>> + parsing_img = False
>> + img_data = ""
>> + n_img = 0
>> +
>> + args = parser.parse_args()
>> + with open(args.filename, "r") as f:
>> + for line in f.readlines():
>> + if line.startswith("KUNIT PANIC IMAGE DUMP START"):
>> + parsing_img = True
>> + width, height = get_dim(line.split()[-1])
>> + continue
>> + if line.startswith("KUNIT PANIC IMAGE DUMP END"):
>> + draw_image(img_data, width, height, n_img)
>> + parsing_img = False
>> + img_data = ""
>> + n_img += 1
>> + continue
>> + if parsing_img:
>> + img_data += line.strip()
>> +
>> +main()
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/3] drm/panic: Add a kconfig option to dump kunits results to png
2025-08-27 9:52 ` Maxime Ripard
@ 2025-09-01 13:16 ` Jocelyn Falempe
0 siblings, 0 replies; 13+ messages in thread
From: Jocelyn Falempe @ 2025-09-01 13:16 UTC (permalink / raw)
To: Maxime Ripard
Cc: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
Javier Martinez Canillas, linux-kernel, dri-devel
On 27/08/2025 11:52, Maxime Ripard wrote:
> Hi,
>
> On Thu, Aug 21, 2025 at 11:49:07AM +0200, Jocelyn Falempe wrote:
>> This is a bit hacky, but very handy if you want to customize the
>> panic screen.
>> It allows to dump the generated images to the logs, and then a python
>> script can convert it to .png files. It makes it easy to check how
>> the panic screen will look on different resolutions, without having
>> to crash a VM.
>> To not pollute the logs, it uses a monochrome framebuffer, compress
>> it with zlib, and base64 encode it.
>>
>> Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
>> ---
>> drivers/gpu/drm/Kconfig.debug | 14 ++++
>> drivers/gpu/drm/tests/drm_panic_test.c | 111 +++++++++++++++++++++++++
>> scripts/kunitpanic2png.py | 53 ++++++++++++
>> 3 files changed, 178 insertions(+)
>> create mode 100755 scripts/kunitpanic2png.py
>>
>> diff --git a/drivers/gpu/drm/Kconfig.debug b/drivers/gpu/drm/Kconfig.debug
>> index 05dc43c0b8c5..d8ae85132d32 100644
>> --- a/drivers/gpu/drm/Kconfig.debug
>> +++ b/drivers/gpu/drm/Kconfig.debug
>> @@ -84,6 +84,20 @@ config DRM_KUNIT_TEST
>>
>> If in doubt, say "N".
>>
>> +config DRM_PANIC_KUNIT_TEST_DUMP
>> + bool "Enable screen dump to logs in KUnit tests for drm_panic"
>> + default n
>> + depends on DRM && DRM_PANIC && DRM_KUNIT_TEST
>> + select ZLIB_DEFLATE
>> + help
>> + This allows to dump the panic screen to the KUnit tests logs.
>> + It's possible with a small python script to write pngs from the logs.
>> +
>> + This is only to help developers customizing the drm_panic screen,
>> + checking the result for different resolutions.
>> +
>> + If in doubt, say "N"
>> +
>> config DRM_TTM_KUNIT_TEST
>> tristate "KUnit tests for TTM" if !KUNIT_ALL_TESTS
>> default n
>> diff --git a/drivers/gpu/drm/tests/drm_panic_test.c b/drivers/gpu/drm/tests/drm_panic_test.c
>> index 46ff3e5e0e5d..8cddb845aea9 100644
>> --- a/drivers/gpu/drm/tests/drm_panic_test.c
>> +++ b/drivers/gpu/drm/tests/drm_panic_test.c
>> @@ -115,24 +115,135 @@ static void drm_test_panic_screen_user_page(struct kunit *test)
>> kfree(pages);
>> }
>>
>> +#ifdef CONFIG_DRM_PANIC_KUNIT_TEST_DUMP
>> +#include <linux/base64.h>
>> +#include <linux/delay.h>
>> +#include <linux/zlib.h>
>> +
>> +#define LINE_LEN 128
>> +
>> +#define COMPR_LEVEL 6
>> +#define WINDOW_BITS 12
>> +#define MEM_LEVEL 4
>> +
>> +static int compress_image(u8 *src, int size, u8 *dst)
>> +{
>> + struct z_stream_s stream;
>> +
>> + stream.workspace = kmalloc(zlib_deflate_workspacesize(WINDOW_BITS, MEM_LEVEL),
>> + GFP_KERNEL);
>> +
>> + if (zlib_deflateInit2(&stream, COMPR_LEVEL, Z_DEFLATED, WINDOW_BITS,
>> + MEM_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK)
>> + return -EINVAL;
>> +
>> + stream.next_in = src;
>> + stream.avail_in = size;
>> + stream.total_in = 0;
>> + stream.next_out = dst;
>> + stream.avail_out = size;
>> + stream.total_out = 0;
>> +
>> + if (zlib_deflate(&stream, Z_FINISH) != Z_STREAM_END)
>> + return -EINVAL;
>> +
>> + if (zlib_deflateEnd(&stream) != Z_OK)
>> + return -EINVAL;
>> +
>> + kfree(stream.workspace);
>> +
>> + return stream.total_out;
>> +}
>> +
>> +static void dump_image(u8 *fb, unsigned int width, unsigned int height)
>> +{
>> + int len = 0;
>> + char *dst;
>> + char *compressed;
>> + int sent = 0;
>> + int stride = DIV_ROUND_UP(width, 8);
>> + int size = stride * height;
>> +
>> + compressed = vzalloc(size);
>> + if (!compressed)
>> + return;
>> + len = compress_image(fb, size, compressed);
>> + if (len < 0) {
>> + pr_err("Compression failed %d", len);
>> + return;
>> + }
>> +
>> + dst = vzalloc(4 * DIV_ROUND_UP(len, 3) + 1);
>> + if (!dst)
>> + return;
>> +
>> + len = base64_encode(compressed, len, dst);
>> +
>> + pr_info("KUNIT PANIC IMAGE DUMP START %dx%d", width, height);
>> + while (len > 0) {
>> + char save = dst[sent + LINE_LEN];
>> +
>> + dst[sent + LINE_LEN] = 0;
>> + pr_info("%s", dst + sent);
>> + dst[sent + LINE_LEN] = save;
>> + sent += LINE_LEN;
>> + len -= LINE_LEN;
>> + }
>> + pr_info("KUNIT PANIC IMAGE DUMP END");
>
> The kunit test output format is defined, and we should probably use a
> diagnostic line for this:
> https://docs.kernel.org/dev-tools/ktap.html#diagnostic-lines
>
> We should probably cc the kunit maintainers about this too.
Thanks for the pointer, I will also experiment with debugfs, as
suggested by Thomas.
Best regards,
--
Jocelyn
>
> Maxime
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/3] drm/panic: Add a kconfig option to dump kunits results to png
2025-09-01 13:04 ` Jocelyn Falempe
@ 2025-09-02 16:58 ` Maxime Ripard
2025-09-03 7:30 ` Jocelyn Falempe
0 siblings, 1 reply; 13+ messages in thread
From: Maxime Ripard @ 2025-09-02 16:58 UTC (permalink / raw)
To: Jocelyn Falempe
Cc: Thomas Zimmermann, Maarten Lankhorst, David Airlie, Simona Vetter,
Javier Martinez Canillas, linux-kernel, dri-devel
[-- Attachment #1: Type: text/plain, Size: 1393 bytes --]
On Mon, Sep 01, 2025 at 03:04:26PM +0200, Jocelyn Falempe wrote:
> On 27/08/2025 12:45, Thomas Zimmermann wrote:
> > Hi
> >
> > Am 21.08.25 um 11:49 schrieb Jocelyn Falempe:
> > > This is a bit hacky, but very handy if you want to customize the
> > > panic screen.
> > > It allows to dump the generated images to the logs, and then a python
> > > script can convert it to .png files. It makes it easy to check how
> > > the panic screen will look on different resolutions, without having
> > > to crash a VM.
> > > To not pollute the logs, it uses a monochrome framebuffer, compress
> > > it with zlib, and base64 encode it.
> >
> > May I suggest to export the raw image via debugfs? Debugfs can also
> > export additional information in additional files, such as width/height/
> > stride/format. This could provide the real/last image on the fly, simply
> > by reading the files. No workarounds or encodings needed.
>
> I'm looking into that. The difficulty is to get the debugfs content outside
> of the test kernel. As I'm using a uml kernel for testing, I will need a
> special initrd, and a way to share files with the host.
Yeah, I agree that it's not very practical. If only because the test
context doesn't stick around once it's been executed, so you would
effectively leak an arbritrarily long buffer with no hope of getting
back its memory.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/3] drm/panic: Add a kconfig option to dump kunits results to png
2025-09-02 16:58 ` Maxime Ripard
@ 2025-09-03 7:30 ` Jocelyn Falempe
2025-09-03 8:19 ` Maxime Ripard
0 siblings, 1 reply; 13+ messages in thread
From: Jocelyn Falempe @ 2025-09-03 7:30 UTC (permalink / raw)
To: Maxime Ripard
Cc: Thomas Zimmermann, Maarten Lankhorst, David Airlie, Simona Vetter,
Javier Martinez Canillas, linux-kernel, dri-devel
On 02/09/2025 18:58, Maxime Ripard wrote:
> On Mon, Sep 01, 2025 at 03:04:26PM +0200, Jocelyn Falempe wrote:
>> On 27/08/2025 12:45, Thomas Zimmermann wrote:
>>> Hi
>>>
>>> Am 21.08.25 um 11:49 schrieb Jocelyn Falempe:
>>>> This is a bit hacky, but very handy if you want to customize the
>>>> panic screen.
>>>> It allows to dump the generated images to the logs, and then a python
>>>> script can convert it to .png files. It makes it easy to check how
>>>> the panic screen will look on different resolutions, without having
>>>> to crash a VM.
>>>> To not pollute the logs, it uses a monochrome framebuffer, compress
>>>> it with zlib, and base64 encode it.
>>>
>>> May I suggest to export the raw image via debugfs? Debugfs can also
>>> export additional information in additional files, such as width/height/
>>> stride/format. This could provide the real/last image on the fly, simply
>>> by reading the files. No workarounds or encodings needed.
>>
>> I'm looking into that. The difficulty is to get the debugfs content outside
>> of the test kernel. As I'm using a uml kernel for testing, I will need a
>> special initrd, and a way to share files with the host.
>
> Yeah, I agree that it's not very practical. If only because the test
> context doesn't stick around once it's been executed, so you would
> effectively leak an arbritrarily long buffer with no hope of getting
> back its memory.
I've made a prototype with debugfs, a small ramdisk with busybox, and
using hostfs to mount the host filesystem in the uml kernel, and it
allows to dump the raw panic buffer easily.
Even if it's a bit more complex to setup, I think this use case is not
really a kunit test, so it's probably better that way.
Let me a few days to clean that up, and I will send a v2 of the kunit
tests, and a new series to add a debugfs interface.
Thanks for your reviews,
--
Jocelyn
>
> Maxime
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/3] drm/panic: Add a kconfig option to dump kunits results to png
2025-09-03 7:30 ` Jocelyn Falempe
@ 2025-09-03 8:19 ` Maxime Ripard
0 siblings, 0 replies; 13+ messages in thread
From: Maxime Ripard @ 2025-09-03 8:19 UTC (permalink / raw)
To: Jocelyn Falempe
Cc: Thomas Zimmermann, Maarten Lankhorst, David Airlie, Simona Vetter,
Javier Martinez Canillas, linux-kernel, dri-devel
[-- Attachment #1: Type: text/plain, Size: 2590 bytes --]
On Wed, Sep 03, 2025 at 09:30:23AM +0200, Jocelyn Falempe wrote:
> On 02/09/2025 18:58, Maxime Ripard wrote:
> > On Mon, Sep 01, 2025 at 03:04:26PM +0200, Jocelyn Falempe wrote:
> > > On 27/08/2025 12:45, Thomas Zimmermann wrote:
> > > > Hi
> > > >
> > > > Am 21.08.25 um 11:49 schrieb Jocelyn Falempe:
> > > > > This is a bit hacky, but very handy if you want to customize the
> > > > > panic screen.
> > > > > It allows to dump the generated images to the logs, and then a python
> > > > > script can convert it to .png files. It makes it easy to check how
> > > > > the panic screen will look on different resolutions, without having
> > > > > to crash a VM.
> > > > > To not pollute the logs, it uses a monochrome framebuffer, compress
> > > > > it with zlib, and base64 encode it.
> > > >
> > > > May I suggest to export the raw image via debugfs? Debugfs can also
> > > > export additional information in additional files, such as width/height/
> > > > stride/format. This could provide the real/last image on the fly, simply
> > > > by reading the files. No workarounds or encodings needed.
> > >
> > > I'm looking into that. The difficulty is to get the debugfs content outside
> > > of the test kernel. As I'm using a uml kernel for testing, I will need a
> > > special initrd, and a way to share files with the host.
> >
> > Yeah, I agree that it's not very practical. If only because the test
> > context doesn't stick around once it's been executed, so you would
> > effectively leak an arbritrarily long buffer with no hope of getting
> > back its memory.
>
> I've made a prototype with debugfs, a small ramdisk with busybox, and using
> hostfs to mount the host filesystem in the uml kernel, and it allows to dump
> the raw panic buffer easily.
> Even if it's a bit more complex to setup, I think this use case is not
> really a kunit test, so it's probably better that way.
>
> Let me a few days to clean that up, and I will send a v2 of the kunit tests,
> and a new series to add a debugfs interface.
>
> Thanks for your reviews,
We also have to think about how it's going to be shipped and used. If
your debugfs integration has to be disabled everytime we're running
kunit through uml, qemu, and in CI (because we can't retrieve the
result), on a live system (because it would leak memory indefinitely),
how is it useful?
The diagnostic lines are part of the test result, are in the logs, and
can be distributed. You're having all those problems solved already,
without having any additional work to do.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2025-09-03 8:19 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-21 9:49 [PATCH 0/3] drm/panic: Add kunit tests for drm_panic Jocelyn Falempe
2025-08-21 9:49 ` [PATCH 1/3] drm/panic: Rename draw_panic_static_* to draw_panic_screen_* Jocelyn Falempe
2025-08-21 9:49 ` [PATCH 2/3] drm/panic: Add kunit tests for drm_panic Jocelyn Falempe
2025-08-27 9:44 ` Maxime Ripard
2025-09-01 12:59 ` Jocelyn Falempe
2025-08-21 9:49 ` [PATCH 3/3] drm/panic: Add a kconfig option to dump kunits results to png Jocelyn Falempe
2025-08-27 9:52 ` Maxime Ripard
2025-09-01 13:16 ` Jocelyn Falempe
2025-08-27 10:45 ` Thomas Zimmermann
2025-09-01 13:04 ` Jocelyn Falempe
2025-09-02 16:58 ` Maxime Ripard
2025-09-03 7:30 ` Jocelyn Falempe
2025-09-03 8:19 ` Maxime Ripard
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).