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

Signed-off-by: Rob Clark <[email protected]>
---
 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

Reply via email to