]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
drm/amdgpu: fix VM clearing in amdgpu_gem_object_close
authorChristian König <christian.koenig@amd.com>
Fri, 21 Apr 2017 08:05:56 +0000 (10:05 +0200)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 28 Apr 2017 21:32:53 +0000 (17:32 -0400)
We need to check if the VM is swapped out before trying to update it.

Fixes: 23e0563e48f7 ("drm/amdgpu: clear freed mappings immediately when BO may be freed")
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c

index 03a9c5cad222ab97748196ce699136ccbaceb129..94cb91cf93eb8b0b6652b6a271ca56063e0ab912 100644 (file)
@@ -139,6 +139,35 @@ int amdgpu_gem_object_open(struct drm_gem_object *obj,
        return 0;
 }
 
+static int amdgpu_gem_vm_check(void *param, struct amdgpu_bo *bo)
+{
+       /* if anything is swapped out don't swap it in here,
+          just abort and wait for the next CS */
+       if (!amdgpu_bo_gpu_accessible(bo))
+               return -ERESTARTSYS;
+
+       if (bo->shadow && !amdgpu_bo_gpu_accessible(bo->shadow))
+               return -ERESTARTSYS;
+
+       return 0;
+}
+
+static bool amdgpu_gem_vm_ready(struct amdgpu_device *adev,
+                               struct amdgpu_vm *vm,
+                               struct list_head *list)
+{
+       struct ttm_validate_buffer *entry;
+
+       list_for_each_entry(entry, list, head) {
+               struct amdgpu_bo *bo =
+                       container_of(entry->bo, struct amdgpu_bo, tbo);
+               if (amdgpu_gem_vm_check(NULL, bo))
+                       return false;
+       }
+
+       return !amdgpu_vm_validate_pt_bos(adev, vm, amdgpu_gem_vm_check, NULL);
+}
+
 void amdgpu_gem_object_close(struct drm_gem_object *obj,
                             struct drm_file *file_priv)
 {
@@ -148,15 +177,13 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj,
        struct amdgpu_vm *vm = &fpriv->vm;
 
        struct amdgpu_bo_list_entry vm_pd;
-       struct list_head list, duplicates;
+       struct list_head list;
        struct ttm_validate_buffer tv;
        struct ww_acquire_ctx ticket;
        struct amdgpu_bo_va *bo_va;
-       struct dma_fence *fence = NULL;
        int r;
 
        INIT_LIST_HEAD(&list);
-       INIT_LIST_HEAD(&duplicates);
 
        tv.bo = &bo->tbo;
        tv.shared = true;
@@ -164,16 +191,18 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj,
 
        amdgpu_vm_get_pd_bo(vm, &list, &vm_pd);
 
-       r = ttm_eu_reserve_buffers(&ticket, &list, false, &duplicates);
+       r = ttm_eu_reserve_buffers(&ticket, &list, false, NULL);
        if (r) {
                dev_err(adev->dev, "leaking bo va because "
                        "we fail to reserve bo (%d)\n", r);
                return;
        }
        bo_va = amdgpu_vm_bo_find(vm, bo);
-       if (bo_va) {
-               if (--bo_va->ref_count == 0) {
-                       amdgpu_vm_bo_rmv(adev, bo_va);
+       if (bo_va && --bo_va->ref_count == 0) {
+               amdgpu_vm_bo_rmv(adev, bo_va);
+
+               if (amdgpu_gem_vm_ready(adev, vm, &list)) {
+                       struct dma_fence *fence = NULL;
 
                        r = amdgpu_vm_clear_freed(adev, vm, &fence);
                        if (unlikely(r)) {
@@ -502,19 +531,6 @@ out:
        return r;
 }
 
-static int amdgpu_gem_va_check(void *param, struct amdgpu_bo *bo)
-{
-       /* if anything is swapped out don't swap it in here,
-          just abort and wait for the next CS */
-       if (!amdgpu_bo_gpu_accessible(bo))
-               return -ERESTARTSYS;
-
-       if (bo->shadow && !amdgpu_bo_gpu_accessible(bo->shadow))
-               return -ERESTARTSYS;
-
-       return 0;
-}
-
 /**
  * amdgpu_gem_va_update_vm -update the bo_va in its VM
  *
@@ -533,19 +549,9 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
                                    struct list_head *list,
                                    uint32_t operation)
 {
-       struct ttm_validate_buffer *entry;
        int r = -ERESTARTSYS;
 
-       list_for_each_entry(entry, list, head) {
-               struct amdgpu_bo *bo =
-                       container_of(entry->bo, struct amdgpu_bo, tbo);
-               if (amdgpu_gem_va_check(NULL, bo))
-                       goto error;
-       }
-
-       r = amdgpu_vm_validate_pt_bos(adev, vm, amdgpu_gem_va_check,
-                                     NULL);
-       if (r)
+       if (!amdgpu_gem_vm_ready(adev, vm, list))
                goto error;
 
        r = amdgpu_vm_update_directories(adev, vm);