summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@quicinc.com>2017-06-20 03:20:27 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2017-06-20 03:20:26 -0700
commit73a0e7ea498e45c9bf25612658311c63c89fc4d8 (patch)
treef3c76113860ad938e6a71f4166da21697c602a5e /drivers
parent0045ec6f11d0f5b6f515bf4ef8af9552580370df (diff)
parentb674857b834e03f0b789e7def6948a34c246ae60 (diff)
Merge "drm/msm: Add submit queue queries"
Diffstat (limited to 'drivers')
-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;