summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorJordan Crouse <jcrouse@codeaurora.org>2017-06-12 09:16:46 -0600
committerJordan Crouse <jcrouse@codeaurora.org>2017-06-19 15:50:26 -0600
commitb674857b834e03f0b789e7def6948a34c246ae60 (patch)
tree1fd98dfa8713ea3a9a508a22bd35353d360c3c45 /drivers/gpu
parentd4041b86d5e341c82a4e5b0cd09f4edc7ecb068a (diff)
drm/msm: Add submit queue queries
Add the capability to query information from a submit queue. The first available parameter is to query the number of GPU faults that have been caused by the queue. The driver can periodically query this value to see if it has caused a fault and take action accordingly. Change-Id: Ic0dedbadc68d5782c0b8b71d89722742aa6aaf1a Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/msm/msm_drv.c12
-rw-r--r--drivers/gpu/drm/msm/msm_drv.h3
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.c25
-rw-r--r--drivers/gpu/drm/msm/msm_submitqueue.c26
4 files changed, 60 insertions, 6 deletions
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index a12da5b745f4..cc3e56733fb9 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -1711,6 +1711,16 @@ static int msm_ioctl_submitqueue_new(struct drm_device *dev, void *data,
args->flags, &args->id);
}
+static int msm_ioctl_submitqueue_query(struct drm_device *dev, void *data,
+ struct drm_file *file)
+{
+ struct drm_msm_submitqueue_query *args = data;
+ void __user *ptr = (void __user *)(uintptr_t) args->data;
+
+ return msm_submitqueue_query(file->driver_priv, args->id,
+ args->param, ptr, args->len);
+}
+
static int msm_ioctl_submitqueue_close(struct drm_device *dev, void *data,
struct drm_file *file)
{
@@ -1768,6 +1778,8 @@ static const struct drm_ioctl_desc msm_ioctls[] = {
DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_CLOSE, msm_ioctl_submitqueue_close,
DRM_AUTH|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_QUERY, msm_ioctl_submitqueue_query,
+ DRM_AUTH|DRM_RENDER_ALLOW),
};
static const struct vm_operations_struct vm_ops = {
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 660c608b64f0..adc1e021b6f7 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -516,8 +516,11 @@ struct msm_gpu_submitqueue *msm_submitqueue_get(struct msm_file_private *ctx,
u32 id);
int msm_submitqueue_create(struct msm_file_private *ctx, u32 prio,
u32 flags, u32 *id);
+int msm_submitqueue_query(struct msm_file_private *ctx, u32 id, u32 param,
+ void __user *data, u32 len);
int msm_submitqueue_remove(struct msm_file_private *ctx, u32 id);
void msm_submitqueue_close(struct msm_file_private *ctx);
+
void msm_submitqueue_destroy(struct kref *kref);
struct hdmi;
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 45d7a658f022..cb90d23e8b07 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -274,6 +274,20 @@ static void inactive_start(struct msm_gpu *gpu)
round_jiffies_up(jiffies + DRM_MSM_INACTIVE_JIFFIES));
}
+static void retire_guilty_submit(struct msm_gpu *gpu,
+ struct msm_ringbuffer *ring)
+{
+ struct msm_gem_submit *submit = list_first_entry_or_null(&ring->submits,
+ struct msm_gem_submit, node);
+
+ if (!submit)
+ return;
+
+ submit->queue->faults++;
+
+ msm_gem_submit_free(submit);
+}
+
/*
* Hangcheck detection for locked gpu:
*/
@@ -296,13 +310,12 @@ static void recover_worker(struct work_struct *work)
inactive_cancel(gpu);
- FOR_EACH_RING(gpu, ring, i) {
- uint32_t fence = gpu->funcs->last_fence(gpu, ring);
-
+ /* Retire all events that have already passed */
+ FOR_EACH_RING(gpu, ring, i)
retire_submits(gpu, ring,
- gpu->funcs->active_ring(gpu) == ring ?
- fence + 1 : fence);
- }
+ gpu->funcs->last_fence(gpu, ring));
+
+ retire_guilty_submit(gpu, gpu->funcs->active_ring(gpu));
/* Recover the GPU */
gpu->funcs->recover(gpu);
diff --git a/drivers/gpu/drm/msm/msm_submitqueue.c b/drivers/gpu/drm/msm/msm_submitqueue.c
index 8e29021bb0d8..4f2af876db49 100644
--- a/drivers/gpu/drm/msm/msm_submitqueue.c
+++ b/drivers/gpu/drm/msm/msm_submitqueue.c
@@ -27,6 +27,9 @@ struct msm_gpu_submitqueue *msm_submitqueue_get(struct msm_file_private *ctx,
{
struct msm_gpu_submitqueue *entry;
+ if (!ctx)
+ return NULL;
+
read_lock(&ctx->queuelock);
list_for_each_entry(entry, &ctx->submitqueues, node) {
@@ -95,6 +98,29 @@ int msm_submitqueue_init(struct msm_file_private *ctx)
return msm_submitqueue_create(ctx, 3, 0, NULL);
}
+int msm_submitqueue_query(struct msm_file_private *ctx, u32 id, u32 param,
+ void __user *data, u32 len)
+{
+ struct msm_gpu_submitqueue *queue = msm_submitqueue_get(ctx, id);
+ int ret = 0;
+
+ if (!queue)
+ return -ENOENT;
+
+ if (param == MSM_SUBMITQUEUE_PARAM_FAULTS) {
+ u32 size = min_t(u32, len, sizeof(queue->faults));
+
+ if (copy_to_user(data, &queue->faults, size))
+ ret = -EFAULT;
+ } else {
+ ret = -EINVAL;
+ }
+
+ msm_submitqueue_put(queue);
+
+ return ret;
+}
+
int msm_submitqueue_remove(struct msm_file_private *ctx, u32 id)
{
struct msm_gpu_submitqueue *entry;