[RFC 2/2] drm/msm: Add sysrq_kill handler

From: Rob Clark

Date: Mon Mar 16 2026 - 18:40:38 EST


This does the same thing as an immediately expiring hangcheck timer.

Signed-off-by: Rob Clark <robin.clark@xxxxxxxxxxxxxxxx>
---
drivers/gpu/drm/msm/msm_drv.c | 12 ++++++++++++
drivers/gpu/drm/msm/msm_gpu.c | 18 ++++++++++++++++++
drivers/gpu/drm/msm/msm_gpu.h | 1 +
3 files changed, 31 insertions(+)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index ed2a61c66ac9..ac04d83724b9 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -812,6 +812,16 @@ static void msm_show_fdinfo(struct drm_printer *p, struct drm_file *file)
drm_show_memory_stats(p, file);
}

+static void msm_sysrq_kill(struct drm_device *dev)
+{
+ struct msm_drm_private *priv = dev->dev_private;
+
+ if (!priv->gpu)
+ return;
+
+ msm_gpu_sysrq_kill(priv->gpu);
+}
+
static const struct file_operations fops = {
.owner = THIS_MODULE,
DRM_GEM_FOPS,
@@ -846,6 +856,7 @@ static const struct drm_driver msm_driver = {
#endif
MSM_FBDEV_DRIVER_OPS,
.show_fdinfo = msm_show_fdinfo,
+ .sysrq_kill = msm_sysrq_kill,
.ioctls = msm_ioctls,
.num_ioctls = ARRAY_SIZE(msm_ioctls),
.fops = &fops,
@@ -885,6 +896,7 @@ static const struct drm_driver msm_gpu_driver = {
.debugfs_init = msm_debugfs_init,
#endif
.show_fdinfo = msm_show_fdinfo,
+ .sysrq_kill = msm_sysrq_kill,
.ioctls = msm_ioctls,
.num_ioctls = ARRAY_SIZE(msm_ioctls),
.fops = &fops,
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 995549d0bbbc..6b1c284ad631 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -673,6 +673,24 @@ static void hangcheck_handler(struct timer_list *t)
msm_gpu_retire(gpu);
}

+void msm_gpu_sysrq_kill(struct msm_gpu *gpu)
+{
+ struct msm_ringbuffer *ring = gpu->funcs->active_ring(gpu);
+ uint32_t fence = ring->memptrs->fence;
+ struct drm_device *dev = gpu->dev;
+
+ if (fence_before(fence, ring->fctx->last_fence)) {
+ DRM_DEV_ERROR(dev->dev, "%s: sysrq kill job, rb %d!\n",
+ gpu->name, ring->id);
+ DRM_DEV_ERROR(dev->dev, "%s: completed fence: %u\n",
+ gpu->name, fence);
+ DRM_DEV_ERROR(dev->dev, "%s: submitted fence: %u\n",
+ gpu->name, ring->fctx->last_fence);
+
+ kthread_queue_work(gpu->worker, &gpu->recover_work);
+ }
+}
+
/*
* Performance Counters:
*/
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index 666cf499b7ec..07abbe33d992 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -696,6 +696,7 @@ int msm_gpu_perfcntr_sample(struct msm_gpu *gpu, uint32_t *activetime,

void msm_gpu_retire(struct msm_gpu *gpu);
void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit);
+void msm_gpu_sysrq_kill(struct msm_gpu *gpu);

int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
struct msm_gpu *gpu, const struct msm_gpu_funcs *funcs,
--
2.53.0