Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/panic: Add debugfs entry to test without triggering panic.

Add a debugfs file, so you can test drm_panic without freezing
your machine. This is unsafe, and should be enabled only for
developer or tester.

To display the drm_panic screen on the device 0:
echo 1 > /sys/kernel/debug/dri/0/drm_panic_plane_0

v9:
* Create a debugfs file for each plane in the device's debugfs
directory. This allows to test for each plane of each GPU
independently.

Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240409163432.352518-5-jfalempe@redhat.com
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>

+52 -1
+9
drivers/gpu/drm/Kconfig
··· 127 127 depends on DRM_PANIC 128 128 default 0x000000 129 129 130 + config DRM_PANIC_DEBUG 131 + bool "Add a debug fs entry to trigger drm_panic" 132 + depends on DRM_PANIC && DEBUG_FS 133 + help 134 + Add dri/[device]/drm_panic_plane_x in the kernel debugfs, to force the 135 + panic handler to write the panic message to this plane scanout buffer. 136 + This is unsafe and should not be enabled on a production build. 137 + If in doubt, say "N". 138 + 130 139 config DRM_DEBUG_DP_MST_TOPOLOGY_REFS 131 140 bool "Enable refcount backtrace history in the DP MST helpers" 132 141 depends on STACKTRACE_SUPPORT
+43 -1
drivers/gpu/drm/drm_panic.c
··· 496 496 draw_panic_plane(plane); 497 497 } 498 498 499 + 500 + /* 501 + * DEBUG FS, This is currently unsafe. 502 + * Create one file per plane, so it's possible to debug one plane at a time. 503 + * TODO: It would be better to emulate an NMI context. 504 + */ 505 + #ifdef CONFIG_DRM_PANIC_DEBUG 506 + #include <linux/debugfs.h> 507 + 508 + static ssize_t debugfs_trigger_write(struct file *file, const char __user *user_buf, 509 + size_t count, loff_t *ppos) 510 + { 511 + bool run; 512 + 513 + if (kstrtobool_from_user(user_buf, count, &run) == 0 && run) { 514 + struct drm_plane *plane = file->private_data; 515 + 516 + draw_panic_plane(plane); 517 + } 518 + return count; 519 + } 520 + 521 + static const struct file_operations dbg_drm_panic_ops = { 522 + .owner = THIS_MODULE, 523 + .write = debugfs_trigger_write, 524 + .open = simple_open, 525 + }; 526 + 527 + static void debugfs_register_plane(struct drm_plane *plane, int index) 528 + { 529 + char fname[32]; 530 + 531 + snprintf(fname, 32, "drm_panic_plane_%d", index); 532 + debugfs_create_file(fname, 0200, plane->dev->debugfs_root, 533 + plane, &dbg_drm_panic_ops); 534 + } 535 + #else 536 + static void debugfs_register_plane(struct drm_plane *plane, int index) {} 537 + #endif /* CONFIG_DRM_PANIC_DEBUG */ 538 + 499 539 /** 500 540 * drm_panic_register() - Initialize DRM panic for a device 501 541 * @dev: the drm device on which the panic screen will be displayed. ··· 555 515 plane->kmsg_panic.max_reason = KMSG_DUMP_PANIC; 556 516 if (kmsg_dump_register(&plane->kmsg_panic)) 557 517 drm_warn(dev, "Failed to register panic handler\n"); 558 - else 518 + else { 519 + debugfs_register_plane(plane, registered_plane); 559 520 registered_plane++; 521 + } 560 522 } 561 523 if (registered_plane) 562 524 drm_info(dev, "Registered %d planes with drm panic\n", registered_plane);