Merge branch 'drm-next-4.5' of git://people.freedesktop.org/~agd5f/linux into drm...
[linux-drm-fsl-dcu.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_cs.c
index 3afcf0237c25474c662f499d4583c7743f6067f9..fa0e3276e8dae9ccfaf84204b4cfe143fd9464b6 100644 (file)
@@ -222,6 +222,8 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
                                }
 
                                p->uf.bo = gem_to_amdgpu_bo(gobj);
+                               amdgpu_bo_ref(p->uf.bo);
+                               drm_gem_object_unreference_unlocked(gobj);
                                p->uf.offset = fence_data->offset;
                        } else {
                                ret = -EINVAL;
@@ -386,17 +388,18 @@ static int amdgpu_cs_parser_relocs(struct amdgpu_cs_parser *p)
                amdgpu_cs_buckets_get_list(&buckets, &p->validated);
        }
 
-       p->vm_bos = amdgpu_vm_get_bos(p->adev, &fpriv->vm,
-                                     &p->validated);
+       INIT_LIST_HEAD(&duplicates);
+       amdgpu_vm_get_pd_bo(&fpriv->vm, &p->validated, &p->vm_pd);
 
        if (need_mmap_lock)
                down_read(&current->mm->mmap_sem);
 
-       INIT_LIST_HEAD(&duplicates);
        r = ttm_eu_reserve_buffers(&p->ticket, &p->validated, true, &duplicates);
        if (unlikely(r != 0))
                goto error_reserve;
 
+       amdgpu_vm_get_pt_bos(&fpriv->vm, &duplicates);
+
        r = amdgpu_cs_list_validate(p->adev, &fpriv->vm, &p->validated);
        if (r)
                goto error_validate;
@@ -478,7 +481,6 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo
        if (parser->bo_list)
                amdgpu_bo_list_put(parser->bo_list);
 
-       drm_free_large(parser->vm_bos);
        for (i = 0; i < parser->nchunks; i++)
                drm_free_large(parser->chunks[i].kdata);
        kfree(parser->chunks);
@@ -487,7 +489,7 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo
                        amdgpu_ib_free(parser->adev, &parser->ibs[i]);
        kfree(parser->ibs);
        if (parser->uf.bo)
-               drm_gem_object_unreference_unlocked(&parser->uf.bo->gem_base);
+               amdgpu_bo_unref(&parser->uf.bo);
 }
 
 static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p,
@@ -776,7 +778,7 @@ static int amdgpu_cs_free_job(struct amdgpu_job *job)
                        amdgpu_ib_free(job->adev, &job->ibs[i]);
        kfree(job->ibs);
        if (job->uf.bo)
-               drm_gem_object_unreference_unlocked(&job->uf.bo->gem_base);
+               amdgpu_bo_unref(&job->uf.bo);
        return 0;
 }
 
@@ -784,8 +786,6 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
 {
        struct amdgpu_device *adev = dev->dev_private;
        union drm_amdgpu_cs *cs = data;
-       struct amdgpu_fpriv *fpriv = filp->driver_priv;
-       struct amdgpu_vm *vm = &fpriv->vm;
        struct amdgpu_cs_parser parser = {};
        bool reserved_buffers = false;
        int i, r;
@@ -803,7 +803,6 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
                r = amdgpu_cs_handle_lockup(adev, r);
                return r;
        }
-       mutex_lock(&vm->mutex);
        r = amdgpu_cs_parser_relocs(&parser);
        if (r == -ENOMEM)
                DRM_ERROR("Not enough memory for command submission!\n");
@@ -888,7 +887,6 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
 
 out:
        amdgpu_cs_parser_fini(&parser, r, reserved_buffers);
-       mutex_unlock(&vm->mutex);
        r = amdgpu_cs_handle_lockup(adev, r);
        return r;
 }