Merge branch 'linus-4.14-rc4-acp-prereq' of git://people.freedesktop.org/~agd5f/linux...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / msm / msm_gem_submit.c
index 93535cac0676355d935e1cf032d4601ba5000ac3..b8dc8f96caf221413ebfe65ff1eaf5b6a2b97b8b 100644 (file)
@@ -31,7 +31,8 @@
 #define BO_PINNED   0x2000
 
 static struct msm_gem_submit *submit_create(struct drm_device *dev,
-               struct msm_gpu *gpu, uint32_t nr_bos, uint32_t nr_cmds)
+               struct msm_gpu *gpu, struct msm_gpu_submitqueue *queue,
+               uint32_t nr_bos, uint32_t nr_cmds)
 {
        struct msm_gem_submit *submit;
        uint64_t sz = sizeof(*submit) + ((u64)nr_bos * sizeof(submit->bos[0])) +
@@ -49,6 +50,8 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev,
        submit->fence = NULL;
        submit->pid = get_pid(task_pid(current));
        submit->cmd = (void *)&submit->bos[nr_bos];
+       submit->queue = queue;
+       submit->ring = gpu->rb[queue->prio];
 
        /* initially, until copy_from_user() and bo lookup succeeds: */
        submit->nr_bos = 0;
@@ -66,6 +69,8 @@ void msm_gem_submit_free(struct msm_gem_submit *submit)
        dma_fence_put(submit->fence);
        list_del(&submit->node);
        put_pid(submit->pid);
+       msm_submitqueue_put(submit->queue);
+
        kfree(submit);
 }
 
@@ -156,7 +161,8 @@ out:
        return ret;
 }
 
-static void submit_unlock_unpin_bo(struct msm_gem_submit *submit, int i)
+static void submit_unlock_unpin_bo(struct msm_gem_submit *submit,
+               int i, bool backoff)
 {
        struct msm_gem_object *msm_obj = submit->bos[i].obj;
 
@@ -166,7 +172,7 @@ static void submit_unlock_unpin_bo(struct msm_gem_submit *submit, int i)
        if (submit->bos[i].flags & BO_LOCKED)
                ww_mutex_unlock(&msm_obj->resv->lock);
 
-       if (!(submit->bos[i].flags & BO_VALID))
+       if (backoff && !(submit->bos[i].flags & BO_VALID))
                submit->bos[i].iova = 0;
 
        submit->bos[i].flags &= ~(BO_LOCKED | BO_PINNED);
@@ -201,10 +207,10 @@ retry:
 
 fail:
        for (; i >= 0; i--)
-               submit_unlock_unpin_bo(submit, i);
+               submit_unlock_unpin_bo(submit, i, true);
 
        if (slow_locked > 0)
-               submit_unlock_unpin_bo(submit, slow_locked);
+               submit_unlock_unpin_bo(submit, slow_locked, true);
 
        if (ret == -EDEADLK) {
                struct msm_gem_object *msm_obj = submit->bos[contended].obj;
@@ -243,7 +249,8 @@ static int submit_fence_sync(struct msm_gem_submit *submit, bool no_implicit)
                if (no_implicit)
                        continue;
 
-               ret = msm_gem_sync_object(&msm_obj->base, submit->gpu->fctx, write);
+               ret = msm_gem_sync_object(&msm_obj->base, submit->ring->fctx,
+                       write);
                if (ret)
                        break;
        }
@@ -387,7 +394,7 @@ static void submit_cleanup(struct msm_gem_submit *submit)
 
        for (i = 0; i < submit->nr_bos; i++) {
                struct msm_gem_object *msm_obj = submit->bos[i].obj;
-               submit_unlock_unpin_bo(submit, i);
+               submit_unlock_unpin_bo(submit, i, false);
                list_del_init(&msm_obj->submit_entry);
                drm_gem_object_unreference(&msm_obj->base);
        }
@@ -405,6 +412,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
        struct msm_gpu *gpu = priv->gpu;
        struct dma_fence *in_fence = NULL;
        struct sync_file *sync_file = NULL;
+       struct msm_gpu_submitqueue *queue;
+       struct msm_ringbuffer *ring;
        int out_fence_fd = -1;
        unsigned i;
        int ret;
@@ -421,6 +430,12 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
        if (MSM_PIPE_FLAGS(args->flags) & ~MSM_SUBMIT_FLAGS)
                return -EINVAL;
 
+       queue = msm_submitqueue_get(ctx, args->queueid);
+       if (!queue)
+               return -ENOENT;
+
+       ring = gpu->rb[queue->prio];
+
        if (args->flags & MSM_SUBMIT_FENCE_FD_IN) {
                in_fence = sync_file_get_fence(args->fence_fd);
 
@@ -431,7 +446,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
                 * Wait if the fence is from a foreign context, or if the fence
                 * array contains any fence from a foreign context.
                 */
-               if (!dma_fence_match_context(in_fence, gpu->fctx->context)) {
+               if (!dma_fence_match_context(in_fence, ring->fctx->context)) {
                        ret = dma_fence_wait(in_fence, true);
                        if (ret)
                                return ret;
@@ -449,9 +464,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
                        goto out_unlock;
                }
        }
-       priv->struct_mutex_task = current;
 
-       submit = submit_create(dev, gpu, args->nr_bos, args->nr_cmds);
+       submit = submit_create(dev, gpu, queue, args->nr_bos, args->nr_cmds);
        if (!submit) {
                ret = -ENOMEM;
                goto out_unlock;
@@ -534,7 +548,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
 
        submit->nr_cmds = i;
 
-       submit->fence = msm_fence_alloc(gpu->fctx);
+       submit->fence = msm_fence_alloc(ring->fctx);
        if (IS_ERR(submit->fence)) {
                ret = PTR_ERR(submit->fence);
                submit->fence = NULL;
@@ -567,7 +581,6 @@ out:
 out_unlock:
        if (ret && (out_fence_fd >= 0))
                put_unused_fd(out_fence_fd);
-       priv->struct_mutex_task = NULL;
        mutex_unlock(&dev->struct_mutex);
        return ret;
 }