drm/amdgpu: only support IBs in the buffer list (v2)
authorMarek Olšák <marek.olsak@amd.com>
Tue, 2 Jun 2015 15:44:49 +0000 (17:44 +0200)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 4 Jun 2015 01:04:05 +0000 (21:04 -0400)
amdgpu_cs_find_mapping doesn't work without all buffers being validated,
so the TTM validation must be done first.

v2: only use amdgpu_cs_find_mapping for UVD/VCE VM emulation

Signed-off-by: Marek Olšák <marek.olsak@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
include/uapi/drm/amdgpu_drm.h

index 149b769130910dcde19d3d90b29bb7a2c6aef9dc..c33c1af36fa2cffaff4ac7dc953280ae68823633 100644 (file)
@@ -1191,7 +1191,6 @@ struct amdgpu_cs_parser {
        struct amdgpu_cs_chunk  *chunks;
        /* relocations */
        struct amdgpu_bo_list_entry     *vm_bos;
-       struct amdgpu_bo_list_entry     *ib_bos;
        struct list_head        validated;
 
        struct amdgpu_ib        *ibs;
index fefa48a59a7dd188a9cae5fc562d245e97d30cd5..f6b224a69b3ab45329f699aed08d92b40d9987c6 100644 (file)
@@ -230,11 +230,6 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
                goto out;
        }
 
-       p->ib_bos = kcalloc(p->num_ibs, sizeof(struct amdgpu_bo_list_entry),
-                           GFP_KERNEL);
-       if (!p->ib_bos)
-               r = -ENOMEM;
-
 out:
        kfree(chunk_array);
        return r;
@@ -373,13 +368,6 @@ static int amdgpu_cs_parser_relocs(struct amdgpu_cs_parser *p)
        p->vm_bos = amdgpu_vm_get_bos(p->adev, &fpriv->vm,
                                      &p->validated);
 
-       for (i = 0; i < p->num_ibs; i++) {
-               if (!p->ib_bos[i].robj)
-                       continue;
-
-               list_add(&p->ib_bos[i].tv.head, &p->validated);
-       }
-
        if (need_mmap_lock)
                down_read(&current->mm->mmap_sem);
 
@@ -457,15 +445,9 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo
        for (i = 0; i < parser->nchunks; i++)
                drm_free_large(parser->chunks[i].kdata);
        kfree(parser->chunks);
-       for (i = 0; i < parser->num_ibs; i++) {
-               struct amdgpu_bo *bo = parser->ib_bos[i].robj;
+       for (i = 0; i < parser->num_ibs; i++)
                amdgpu_ib_free(parser->adev, &parser->ibs[i]);
-
-               if (bo)
-                       drm_gem_object_unreference_unlocked(&bo->gem_base);
-       }
        kfree(parser->ibs);
-       kfree(parser->ib_bos);
        if (parser->uf.bo)
                drm_gem_object_unreference_unlocked(&parser->uf.bo->gem_base);
 }
@@ -505,21 +487,6 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p,
                }
        }
 
-       for (i = 0; i < p->num_ibs; i++) {
-               bo = p->ib_bos[i].robj;
-               if (!bo)
-                       continue;
-
-               bo_va = p->ib_bos[i].bo_va;
-               if (!bo_va)
-                       continue;
-
-               r = amdgpu_vm_bo_update(adev, bo_va, &bo->tbo.mem);
-               if (r)
-                       return r;
-
-               amdgpu_sync_fence(&p->ibs[0].sync, bo_va->last_pt_update);
-       }
        return amdgpu_vm_clear_invalids(adev, vm, &p->ibs[0].sync);
 }
 
@@ -581,11 +548,7 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev,
                struct amdgpu_cs_chunk *chunk;
                struct amdgpu_ib *ib;
                struct drm_amdgpu_cs_chunk_ib *chunk_ib;
-               struct amdgpu_bo_list_entry *ib_bo;
                struct amdgpu_ring *ring;
-               struct drm_gem_object *gobj;
-               struct amdgpu_bo *aobj;
-               void *kptr;
 
                chunk = &parser->chunks[i];
                ib = &parser->ibs[j];
@@ -594,66 +557,49 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev,
                if (chunk->chunk_id != AMDGPU_CHUNK_ID_IB)
                        continue;
 
-               gobj = drm_gem_object_lookup(adev->ddev, parser->filp, chunk_ib->handle);
-               if (gobj == NULL)
-                       return -ENOENT;
-               aobj = gem_to_amdgpu_bo(gobj);
-
                r = amdgpu_cs_get_ring(adev, chunk_ib->ip_type,
                                       chunk_ib->ip_instance, chunk_ib->ring,
                                       &ring);
-               if (r) {
-                       drm_gem_object_unreference_unlocked(gobj);
+               if (r)
                        return r;
-               }
 
                if (ring->funcs->parse_cs) {
-                       r = amdgpu_bo_reserve(aobj, false);
-                       if (r) {
-                               drm_gem_object_unreference_unlocked(gobj);
-                               return r;
+                       struct amdgpu_bo *aobj = NULL;
+                       void *kptr;
+
+                       amdgpu_cs_find_mapping(parser, chunk_ib->va_start, &aobj);
+                       if (!aobj) {
+                               DRM_ERROR("IB va_start is invalid\n");
+                               return -EINVAL;
                        }
 
+                       /* the IB should be reserved at this point */
                        r = amdgpu_bo_kmap(aobj, &kptr);
                        if (r) {
-                               amdgpu_bo_unreserve(aobj);
-                               drm_gem_object_unreference_unlocked(gobj);
                                return r;
                        }
 
                        r =  amdgpu_ib_get(ring, NULL, chunk_ib->ib_bytes, ib);
                        if (r) {
                                DRM_ERROR("Failed to get ib !\n");
-                               amdgpu_bo_unreserve(aobj);
-                               drm_gem_object_unreference_unlocked(gobj);
                                return r;
                        }
 
                        memcpy(ib->ptr, kptr, chunk_ib->ib_bytes);
                        amdgpu_bo_kunmap(aobj);
-                       amdgpu_bo_unreserve(aobj);
                } else {
                        r =  amdgpu_ib_get(ring, vm, 0, ib);
                        if (r) {
                                DRM_ERROR("Failed to get ib !\n");
-                               drm_gem_object_unreference_unlocked(gobj);
                                return r;
                        }
 
                        ib->gpu_addr = chunk_ib->va_start;
                }
-               ib->length_dw = chunk_ib->ib_bytes / 4;
 
+               ib->length_dw = chunk_ib->ib_bytes / 4;
                ib->flags = chunk_ib->flags;
                ib->ctx = parser->ctx;
-
-               ib_bo = &parser->ib_bos[j];
-               ib_bo->robj = aobj;
-               ib_bo->prefered_domains = aobj->initial_domain;
-               ib_bo->allowed_domains = aobj->initial_domain;
-               ib_bo->priority = 0;
-               ib_bo->tv.bo = &aobj->tbo;
-               ib_bo->tv.shared = true;
                j++;
        }
 
@@ -702,6 +648,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
        union drm_amdgpu_cs *cs = data;
        struct amdgpu_cs_parser parser;
        int r, i;
+       bool reserved_buffers = false;
 
        down_read(&adev->exclusive_lock);
        if (!adev->accel_working) {
@@ -721,15 +668,21 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
                return r;
        }
 
-       r = amdgpu_cs_ib_fill(adev, &parser);
-       if (!r) {
-               r = amdgpu_cs_parser_relocs(&parser);
-               if (r && r != -ERESTARTSYS)
-                       DRM_ERROR("Failed to parse relocation %d!\n", r);
+       r = amdgpu_cs_parser_relocs(&parser);
+       if (r) {
+               if (r != -ERESTARTSYS) {
+                       if (r == -ENOMEM)
+                               DRM_ERROR("Not enough memory for command submission!\n");
+                       else
+                               DRM_ERROR("Failed to process the buffer list %d!\n", r);
+               }
+       } else {
+               reserved_buffers = true;
+               r = amdgpu_cs_ib_fill(adev, &parser);
        }
 
        if (r) {
-               amdgpu_cs_parser_fini(&parser, r, false);
+               amdgpu_cs_parser_fini(&parser, r, reserved_buffers);
                up_read(&adev->exclusive_lock);
                r = amdgpu_cs_handle_lockup(adev, r);
                return r;
index c90f4f0d059ed718a2b707b239cb7f2c2e2be7dd..780a5815fb1249326bb4c7637e579db41cea8f9e 100644 (file)
@@ -378,11 +378,7 @@ union drm_amdgpu_cs {
 #define AMDGPU_IB_FLAG_PREAMBLE (1<<2)
 
 struct drm_amdgpu_cs_chunk_ib {
-       /**
-        * Handle of GEM object to be used as IB or 0 if it is already in
-        * residency list.
-        */
-       uint32_t handle;
+       uint32_t _pad;
        uint32_t flags;         /* IB Flags */
        uint64_t va_start;      /* Virtual address to begin IB execution */
        uint32_t ib_bytes;      /* Size of submission */