drm/amdgpu: rework amdgpu_cs_find_mapping
authorChristian König <christian.koenig@amd.com>
Wed, 6 Sep 2017 14:55:16 +0000 (16:55 +0200)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 12 Sep 2017 18:27:48 +0000 (14:27 -0400)
Use the VM instead of the BO list to find the BO for a virtual address.

This fixes UVD/VCE in physical mode with VM local BOs.

Signed-off-by: Christian König <christian.koenig@amd.com>
Acked-by: Leo Liu <leo.liu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h

index c30110a..5f19227 100644 (file)
@@ -1479,46 +1479,24 @@ int amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
                           uint64_t addr, struct amdgpu_bo **bo,
                           struct amdgpu_bo_va_mapping **map)
 {
+       struct amdgpu_fpriv *fpriv = parser->filp->driver_priv;
+       struct amdgpu_vm *vm = &fpriv->vm;
        struct amdgpu_bo_va_mapping *mapping;
-       unsigned i;
        int r;
 
-       if (!parser->bo_list)
-               return 0;
-
        addr /= AMDGPU_GPU_PAGE_SIZE;
 
-       for (i = 0; i < parser->bo_list->num_entries; i++) {
-               struct amdgpu_bo_list_entry *lobj;
-
-               lobj = &parser->bo_list->array[i];
-               if (!lobj->bo_va)
-                       continue;
-
-               list_for_each_entry(mapping, &lobj->bo_va->valids, list) {
-                       if (mapping->start > addr ||
-                           addr > mapping->last)
-                               continue;
-
-                       *bo = lobj->bo_va->base.bo;
-                       *map = mapping;
-                       goto found;
-               }
-
-               list_for_each_entry(mapping, &lobj->bo_va->invalids, list) {
-                       if (mapping->start > addr ||
-                           addr > mapping->last)
-                               continue;
+       mapping = amdgpu_vm_bo_lookup_mapping(vm, addr);
+       if (!mapping || !mapping->bo_va || !mapping->bo_va->base.bo)
+               return -EINVAL;
 
-                       *bo = lobj->bo_va->base.bo;
-                       *map = mapping;
-                       goto found;
-               }
-       }
+       *bo = mapping->bo_va->base.bo;
+       *map = mapping;
 
-       return -EINVAL;
+       /* Double check that the BO is reserved by this CS */
+       if (READ_ONCE((*bo)->tbo.resv->lock.ctx) != &parser->ticket)
+               return -EINVAL;
 
-found:
        r = amdgpu_ttm_bind(&(*bo)->tbo, &(*bo)->tbo.mem);
        if (unlikely(r))
                return r;
index 42492e6..a4891be 100644 (file)
@@ -35,6 +35,7 @@
 
 /* bo virtual addresses in a vm */
 struct amdgpu_bo_va_mapping {
+       struct amdgpu_bo_va             *bo_va;
        struct list_head                list;
        struct rb_node                  rb;
        uint64_t                        start;
index 545531d..758bbb9 100644 (file)
@@ -2086,6 +2086,7 @@ static void amdgpu_vm_bo_insert_map(struct amdgpu_device *adev,
        struct amdgpu_vm *vm = bo_va->base.vm;
        struct amdgpu_bo *bo = bo_va->base.bo;
 
+       mapping->bo_va = bo_va;
        list_add(&mapping->list, &bo_va->invalids);
        amdgpu_vm_it_insert(mapping, &vm->va);
 
@@ -2263,6 +2264,7 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
 
        list_del(&mapping->list);
        amdgpu_vm_it_remove(mapping, &vm->va);
+       mapping->bo_va = NULL;
        trace_amdgpu_vm_bo_unmap(bo_va, mapping);
 
        if (valid)
@@ -2348,6 +2350,7 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
                if (tmp->last > eaddr)
                    tmp->last = eaddr;
 
+               tmp->bo_va = NULL;
                list_add(&tmp->list, &vm->freed);
                trace_amdgpu_vm_bo_unmap(NULL, tmp);
        }
@@ -2374,6 +2377,19 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
 }
 
 /**
+ * amdgpu_vm_bo_lookup_mapping - find mapping by address
+ *
+ * @vm: the requested VM
+ *
+ * Find a mapping by it's address.
+ */
+struct amdgpu_bo_va_mapping *amdgpu_vm_bo_lookup_mapping(struct amdgpu_vm *vm,
+                                                        uint64_t addr)
+{
+       return amdgpu_vm_it_iter_first(&vm->va, addr, addr);
+}
+
+/**
  * amdgpu_vm_bo_rmv - remove a bo to a specific vm
  *
  * @adev: amdgpu_device pointer
@@ -2398,6 +2414,7 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
        list_for_each_entry_safe(mapping, next, &bo_va->valids, list) {
                list_del(&mapping->list);
                amdgpu_vm_it_remove(mapping, &vm->va);
+               mapping->bo_va = NULL;
                trace_amdgpu_vm_bo_unmap(bo_va, mapping);
                list_add(&mapping->list, &vm->freed);
        }
index 90b7741..c1accd1 100644 (file)
@@ -276,6 +276,8 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
 int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
                                struct amdgpu_vm *vm,
                                uint64_t saddr, uint64_t size);
+struct amdgpu_bo_va_mapping *amdgpu_vm_bo_lookup_mapping(struct amdgpu_vm *vm,
+                                                        uint64_t addr);
 void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
                      struct amdgpu_bo_va *bo_va);
 void amdgpu_vm_set_fragment_size(struct amdgpu_device *adev,