* [PATCH v4 0/2] drm/panic: Add kunit tests for drm_panic
@ 2025-12-16 8:20 Jocelyn Falempe
2025-12-16 8:20 ` [PATCH v4 1/2] drm/panic: Rename draw_panic_static_* to draw_panic_screen_* Jocelyn Falempe
2025-12-16 8:20 ` [PATCH v4 2/2] drm/panic: Add kunit tests for drm_panic Jocelyn Falempe
0 siblings, 2 replies; 5+ messages in thread
From: Jocelyn Falempe @ 2025-12-16 8:20 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, and a debugfs interface to easily test the panic screen rendering at different resolutions/pixel format.
The kunit 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.
v2:
* Use debugfs instead of sending the framebuffer through the kunit logs. (Thomas Zimmermann).
* Add a few checks, and more comments in the kunit tests. (Maxime Ripard).
v3:
* Check the framebuffer content in drm_test_panic_screen_user_page().
* Fix memory leaks, when the test fails (Maxime Ripard).
v4:
* Run QR code test only if QR code panic screen is built.
* Drop the last patch to add a draw_test debugfs.
Jocelyn Falempe (2):
drm/panic: Rename draw_panic_static_* to draw_panic_screen_*
drm/panic: Add kunit tests for drm_panic
MAINTAINERS | 1 +
drivers/gpu/drm/drm_panic.c | 22 ++-
drivers/gpu/drm/tests/drm_panic_test.c | 220 +++++++++++++++++++++++++
3 files changed, 234 insertions(+), 9 deletions(-)
create mode 100644 drivers/gpu/drm/tests/drm_panic_test.c
base-commit: 20de1b0080b9889094d703927871da8f21fb624e
--
2.52.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v4 1/2] drm/panic: Rename draw_panic_static_* to draw_panic_screen_*
2025-12-16 8:20 [PATCH v4 0/2] drm/panic: Add kunit tests for drm_panic Jocelyn Falempe
@ 2025-12-16 8:20 ` Jocelyn Falempe
2025-12-16 8:35 ` Javier Martinez Canillas
2025-12-16 8:20 ` [PATCH v4 2/2] drm/panic: Add kunit tests for drm_panic Jocelyn Falempe
1 sibling, 1 reply; 5+ messages in thread
From: Jocelyn Falempe @ 2025-12-16 8:20 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 | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index f42be7f1d8c2..30c615768efe 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -476,7 +476,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);
@@ -545,7 +545,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);
@@ -733,7 +733,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);
@@ -801,10 +801,10 @@ 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 drm_panic_qr_init(void) {};
@@ -879,18 +879,18 @@ static void draw_panic_dispatch(struct drm_scanout_buffer *sb)
{
switch (drm_panic_type) {
case DRM_PANIC_TYPE_KMSG:
- draw_panic_static_kmsg(sb);
+ draw_panic_screen_kmsg(sb);
break;
#if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
case DRM_PANIC_TYPE_QR:
- draw_panic_static_qr_code(sb);
+ draw_panic_screen_qr_code(sb);
break;
#endif
case DRM_PANIC_TYPE_USER:
default:
- draw_panic_static_user(sb);
+ draw_panic_screen_user(sb);
}
}
--
2.52.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v4 2/2] drm/panic: Add kunit tests for drm_panic
2025-12-16 8:20 [PATCH v4 0/2] drm/panic: Add kunit tests for drm_panic Jocelyn Falempe
2025-12-16 8:20 ` [PATCH v4 1/2] drm/panic: Rename draw_panic_static_* to draw_panic_screen_* Jocelyn Falempe
@ 2025-12-16 8:20 ` Jocelyn Falempe
2025-12-19 9:29 ` Maxime Ripard
1 sibling, 1 reply; 5+ messages in thread
From: Jocelyn Falempe @ 2025-12-16 8:20 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>
---
v3:
* Check the framebuffer content in drm_test_panic_screen_user_page().
* Fix memory leaks, when the test fails (Maxime Ripard).
v4:
* Run QR code test only if QR code panic screen is built.
MAINTAINERS | 1 +
drivers/gpu/drm/drm_panic.c | 4 +
drivers/gpu/drm/tests/drm_panic_test.c | 220 +++++++++++++++++++++++++
3 files changed, 225 insertions(+)
create mode 100644 drivers/gpu/drm/tests/drm_panic_test.c
diff --git a/MAINTAINERS b/MAINTAINERS
index f980623f1479..74eb8c7da2ab 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8749,6 +8749,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 30c615768efe..a9f54c51a522 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -1084,3 +1084,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..dfd79b12ae9b
--- /dev/null
+++ b/drivers/gpu/drm/tests/drm_panic_test.c
@@ -0,0 +1,220 @@
+// 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>
+
+/* Check the framebuffer color only if the panic colors are the default */
+#if (CONFIG_DRM_PANIC_BACKGROUND_COLOR == 0 && \
+ CONFIG_DRM_PANIC_FOREGROUND_COLOR == 0xffffff)
+
+static void drm_panic_check_color_byte(struct kunit *test, u8 b)
+{
+ KUNIT_EXPECT_TRUE(test, (b == 0 || b == 0xff));
+}
+#else
+static void drm_panic_check_color_byte(struct kunit *test, u8 b) {}
+#endif
+
+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)
+#if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
+ DRM_TEST_MODE_LIST(qr_code)
+#endif
+};
+#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;
+}
+
+/*
+ * Test drawing the panic screen, using a memory mapped framebuffer
+ * Set the whole buffer to 0xa5, and then check that all pixels have been
+ * written.
+ */
+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;
+ char *fb;
+ int fb_size;
+ int i;
+
+ 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);
+
+ memset(fb, 0xa5, fb_size);
+
+ 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);
+
+ for (i = 0; i < fb_size; i++)
+ drm_panic_check_color_byte(test, fb[i]);
+
+ vfree(fb);
+}
+
+/*
+ * Test drawing the panic screen, using a list of pages framebuffer
+ * Set the whole buffer to 0xa5, and then check that all pixels have been
+ * written.
+ */
+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, p, i, npages;
+ struct page **pages;
+ u8 *vaddr;
+
+ 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 (p = 0; p < npages; p++) {
+ pages[p] = alloc_page(GFP_KERNEL);
+ if (!pages[p]) {
+ npages = p - 1;
+ KUNIT_FAIL(test, "Can't allocate page\n");
+ goto free_pages;
+ }
+ vaddr = kmap_local_page(pages[p]);
+ memset(vaddr, 0xa5, PAGE_SIZE);
+ kunmap_local(vaddr);
+ }
+ 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 (p = 0; p < npages; p++) {
+ int bytes_in_page = (p == npages - 1) ? fb_size - p * PAGE_SIZE : PAGE_SIZE;
+
+ vaddr = kmap_local_page(pages[p]);
+ for (i = 0; i < bytes_in_page; i++)
+ drm_panic_check_color_byte(test, vaddr[i]);
+
+ kunmap_local(vaddr);
+ }
+
+free_pages:
+ for (p = 0; p < npages; p++)
+ __free_page(pages[p]);
+ kfree(pages);
+}
+
+static void drm_test_panic_set_pixel(struct drm_scanout_buffer *sb,
+ unsigned int x,
+ unsigned int y,
+ u32 color)
+{
+ struct kunit *test = (struct kunit *) sb->private;
+
+ KUNIT_ASSERT_TRUE(test, x < sb->width && y < sb->height);
+}
+
+/*
+ * Test drawing the panic screen, using the set_pixel callback
+ * Check that all calls to set_pixel() are within the framebuffer
+ */
+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;
+ sb->private = test;
+
+ 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.52.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v4 1/2] drm/panic: Rename draw_panic_static_* to draw_panic_screen_*
2025-12-16 8:20 ` [PATCH v4 1/2] drm/panic: Rename draw_panic_static_* to draw_panic_screen_* Jocelyn Falempe
@ 2025-12-16 8:35 ` Javier Martinez Canillas
0 siblings, 0 replies; 5+ messages in thread
From: Javier Martinez Canillas @ 2025-12-16 8:35 UTC (permalink / raw)
To: Jocelyn Falempe, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Jocelyn Falempe,
linux-kernel, dri-devel
Jocelyn Falempe <jfalempe@redhat.com> writes:
Hello Jocelyn,
> 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>
> ---
Makes sense.
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
--
Best regards,
Javier Martinez Canillas
Core Platforms
Red Hat
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v4 2/2] drm/panic: Add kunit tests for drm_panic
2025-12-16 8:20 ` [PATCH v4 2/2] drm/panic: Add kunit tests for drm_panic Jocelyn Falempe
@ 2025-12-19 9:29 ` Maxime Ripard
0 siblings, 0 replies; 5+ messages in thread
From: Maxime Ripard @ 2025-12-19 9:29 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: 344 bytes --]
On Tue, Dec 16, 2025 at 09:20:39AM +0100, 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>
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-12-19 9:29 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-12-16 8:20 [PATCH v4 0/2] drm/panic: Add kunit tests for drm_panic Jocelyn Falempe
2025-12-16 8:20 ` [PATCH v4 1/2] drm/panic: Rename draw_panic_static_* to draw_panic_screen_* Jocelyn Falempe
2025-12-16 8:35 ` Javier Martinez Canillas
2025-12-16 8:20 ` [PATCH v4 2/2] drm/panic: Add kunit tests for drm_panic Jocelyn Falempe
2025-12-19 9:29 ` Maxime Ripard
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®