Re: [PATCH 04/12] drm/panic: Return errno codes if panic output fails
Jocelyn Falempe <[email protected]>
| Newsgroups | org.freedesktop.lists.amd-gfx,dev.linux.lists.imx,dev.linux.lists.sashiko-reviews,dev.linux.lists.virtualization,org.freedesktop.lists.dri-devel,org.freedesktop.lists.intel-gfx,org.freedesktop.lists.intel-xe,org.freedesktop.lists.nouveau,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-doc,org.kernel.vger.linux-hyperv,org.kernel.vger.linux-renesas-soc,org.kernel.vger.rust-for-linux |
|---|---|
| Message-ID | <[email protected]> |
On 18/08/2026 14:28, Thomas Zimmermann wrote: > Return errno codes from the panic output helpers to detect invalid > panic handling. Avoid flushing the display if an error ocured. The > unflushed display output might be helpful in debugging. > > For now, test the result values in the panic test cases. A later patch > will add support for retrying failed panic output. Thanks, it looks good to me. Reviewed-by: Jocelyn Falempe <[email protected]> > > Signed-off-by: Thomas Zimmermann <[email protected]> > --- > drivers/gpu/drm/drm_panic.c | 41 +++++++++++++++++--------- > drivers/gpu/drm/tests/drm_panic_test.c | 16 ++++++---- > 2 files changed, 37 insertions(+), 20 deletions(-) > > diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c > index 96d238bfceee..594235661710 100644 > --- a/drivers/gpu/drm/drm_panic.c > +++ b/drivers/gpu/drm/drm_panic.c > @@ -478,7 +478,7 @@ static void drm_panic_logo_draw(struct drm_scanout_buffer *sb, struct drm_rect * > fg_color); > } > > -static void draw_panic_screen_user(struct drm_scanout_buffer *sb) > +static int 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); > @@ -489,7 +489,7 @@ static void draw_panic_screen_user(struct drm_scanout_buffer *sb) > unsigned int msg_width, msg_height; > > if (!font) > - return; > + return -EINVAL; > > r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height); > drm_panic_logo_rect(&r_logo, font); > @@ -508,6 +508,8 @@ static void draw_panic_screen_user(struct drm_scanout_buffer *sb) > drm_panic_logo_draw(sb, &r_logo, font, fg_color); > > draw_txt_rectangle(sb, font, panic_msg, panic_msg_lines, true, &r_msg, fg_color); > + > + return 0; > } > > /* > @@ -547,7 +549,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_screen_kmsg(struct drm_scanout_buffer *sb) > +static int 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); > @@ -562,7 +564,7 @@ static void draw_panic_screen_kmsg(struct drm_scanout_buffer *sb) > int yoffset; > > if (!font || font->width > sb->width) > - return; > + return -EINVAL; > > yoffset = sb->height - font->height - (sb->height % font->height) / 2; > > @@ -589,6 +591,8 @@ static void draw_panic_screen_kmsg(struct drm_scanout_buffer *sb) > start--; > } > } > + > + return 0; > } > > #if defined(CONFIG_DRM_PANIC_SCREEN_QR_CODE) > @@ -814,10 +818,11 @@ static int _draw_panic_screen_qr_code(struct drm_scanout_buffer *sb) > return 0; > } > > -static void draw_panic_screen_qr_code(struct drm_scanout_buffer *sb) > +static int draw_panic_screen_qr_code(struct drm_scanout_buffer *sb) > { > if (_draw_panic_screen_qr_code(sb)) > draw_panic_screen_user(sb); > + return 0; > } > #else > static void drm_panic_qr_init(void) {}; > @@ -888,23 +893,25 @@ static bool drm_panic_is_format_supported(const struct drm_format_info *format) > return drm_draw_can_convert_from_xrgb8888(format->format); > } > > -static void draw_panic_dispatch(struct drm_scanout_buffer *sb) > +static int draw_panic_dispatch(struct drm_scanout_buffer *sb) > { > + int ret; > + > switch (drm_panic_type) { > case DRM_PANIC_TYPE_KMSG: > - draw_panic_screen_kmsg(sb); > + ret = draw_panic_screen_kmsg(sb); > break; > - > #if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE) > case DRM_PANIC_TYPE_QR: > - draw_panic_screen_qr_code(sb); > + ret = draw_panic_screen_qr_code(sb); > break; > #endif > - > case DRM_PANIC_TYPE_USER: > default: > - draw_panic_screen_user(sb); > + ret = draw_panic_screen_user(sb); > } > + > + return ret; > } > > static void drm_panic_set_description(const char *description) > @@ -951,9 +958,15 @@ static void draw_panic_plane(struct drm_plane *plane, const char *description) > > drm_panic_set_description(description); > > - draw_panic_dispatch(&sb); > - if (plane->helper_private->panic_flush) > - plane->helper_private->panic_flush(plane); > + ret = draw_panic_dispatch(&sb); > + if (!ret) { > + /* > + * Only flush if we have a panic screen to display. Otherwise > + * it's probably better to leave the display output as-is. > + */ > + if (plane->helper_private->panic_flush) > + plane->helper_private->panic_flush(plane); > + } > > drm_panic_clear_description(); > > diff --git a/drivers/gpu/drm/tests/drm_panic_test.c b/drivers/gpu/drm/tests/drm_panic_test.c > index ad2f3a2f93b6..fdd77b0cc54c 100644 > --- a/drivers/gpu/drm/tests/drm_panic_test.c > +++ b/drivers/gpu/drm/tests/drm_panic_test.c > @@ -30,7 +30,7 @@ struct drm_test_mode { > const int width; > const int height; > const u32 format; > - void (*draw_screen)(struct drm_scanout_buffer *sb); > + int (*draw_screen)(struct drm_scanout_buffer *sb); > const char *fname; > }; > > @@ -87,7 +87,7 @@ static void drm_test_panic_screen_user_map(struct kunit *test) > const struct drm_test_mode *params = test->param_value; > char *fb; > int fb_size; > - int i; > + int i, ret; > > sb->format = drm_format_info(params->format); > fb_size = params->width * params->height * sb->format->cpp[0]; > @@ -102,7 +102,8 @@ static void drm_test_panic_screen_user_map(struct kunit *test) > sb->height = params->height; > sb->pitch[0] = params->width * sb->format->cpp[0]; > > - params->draw_screen(sb); > + ret = params->draw_screen(sb); > + KUNIT_ASSERT_EQ(test, ret, 0); > > for (i = 0; i < fb_size; i++) > drm_panic_check_color_byte(test, fb[i]); > @@ -119,7 +120,7 @@ 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; > + int fb_size, p, i, npages, ret; > struct page **pages; > u8 *vaddr; > > @@ -146,7 +147,8 @@ static void drm_test_panic_screen_user_page(struct kunit *test) > sb->height = params->height; > sb->pitch[0] = params->width * sb->format->cpp[0]; > > - params->draw_screen(sb); > + ret = params->draw_screen(sb); > + KUNIT_ASSERT_EQ(test, ret, 0); > > for (p = 0; p < npages; p++) { > int bytes_in_page = (p == npages - 1) ? fb_size - p * PAGE_SIZE : PAGE_SIZE; > @@ -182,6 +184,7 @@ 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 ret; > > sb->format = drm_format_info(params->format); > sb->set_pixel = drm_test_panic_set_pixel; > @@ -189,7 +192,8 @@ static void drm_test_panic_screen_user_set_pixel(struct kunit *test) > sb->height = params->height; > sb->private = test; > > - params->draw_screen(sb); > + ret = params->draw_screen(sb); > + KUNIT_ASSERT_EQ(test, ret, 0); > } > > static void drm_test_panic_desc(const struct drm_test_mode *t, char *desc)