diff options
-rw-r--r-- | drivers/gpu/drm/msm/msm_drv.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/msm_gpu.c | 17 | ||||
-rw-r--r-- | include/uapi/drm/msm_drm.h | 8 |
3 files changed, 30 insertions, 2 deletions
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index cc3e56733fb9..a441f3d15542 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -1707,6 +1707,13 @@ static int msm_ioctl_submitqueue_new(struct drm_device *dev, void *data, return -EPERM; } + if (args->flags & MSM_SUBMITQUEUE_BYPASS_QOS_TIMEOUT && + !capable(CAP_SYS_ADMIN)) { + DRM_ERROR( + "Only CAP_SYS_ADMIN processes can bypass the timer\n"); + return -EPERM; + } + return msm_submitqueue_create(file->driver_priv, args->prio, args->flags, &args->id); } diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index cb90d23e8b07..c6e8660e3cbe 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -353,8 +353,22 @@ static void hangcheck_handler(unsigned long data) /* some progress has been made.. ya! */ gpu->hangcheck_fence[ring->id] = fence; } else if (fence < submitted) { - /* no progress and not done.. hung! */ + struct msm_gem_submit *submit; + gpu->hangcheck_fence[ring->id] = fence; + + /* + * No progress done, but see if the current submit is + * intentionally skipping the hangcheck + */ + submit = list_first_entry_or_null(&ring->submits, + struct msm_gem_submit, node); + + if (!submit || (submit->queue->flags & + MSM_SUBMITQUEUE_BYPASS_QOS_TIMEOUT)) + goto out; + + /* no progress and not done and not special .. hung! */ dev_err(dev->dev, "%s: hangcheck detected gpu lockup rb %d!\n", gpu->name, ring->id); dev_err(dev->dev, "%s: completed fence: %u\n", @@ -365,6 +379,7 @@ static void hangcheck_handler(unsigned long data) queue_work(priv->wq, &gpu->recover_work); } +out: /* if still more pending work, reset the hangcheck timer: */ if (submitted > gpu->hangcheck_fence[ring->id]) hangcheck_timer_reset(gpu); diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h index ce05a3974572..d8b8ef16b14a 100644 --- a/include/uapi/drm/msm_drm.h +++ b/include/uapi/drm/msm_drm.h @@ -362,7 +362,13 @@ struct drm_msm_gem_sync { * use and query 0 but cannot destroy it. */ -#define MSM_SUBMITQUEUE_FLAGS (0) +/* + * Allows a process to bypass the 2 second quality of service timeout. + * Only CAP_SYS_ADMIN capable processes can set this flag. + */ +#define MSM_SUBMITQUEUE_BYPASS_QOS_TIMEOUT 0x00000001 + +#define MSM_SUBMITQUEUE_FLAGS (MSM_SUBMITQUEUE_BYPASS_QOS_TIMEOUT) struct drm_msm_submitqueue { __u32 flags; /* in, MSM_SUBMITQUEUE_x */ |