diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 38 | 
1 files changed, 23 insertions, 15 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 087332858853..fc32fc01a64b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -115,12 +115,9 @@ int amdgpu_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_pri  	struct amdgpu_vm *vm = &fpriv->vm;  	struct amdgpu_bo_va *bo_va;  	int r; -	mutex_lock(&vm->mutex);  	r = amdgpu_bo_reserve(rbo, false); -	if (r) { -		mutex_unlock(&vm->mutex); +	if (r)  		return r; -	}  	bo_va = amdgpu_vm_bo_find(vm, rbo);  	if (!bo_va) { @@ -129,7 +126,6 @@ int amdgpu_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_pri  		++bo_va->ref_count;  	}  	amdgpu_bo_unreserve(rbo); -	mutex_unlock(&vm->mutex);  	return 0;  } @@ -142,10 +138,8 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj,  	struct amdgpu_vm *vm = &fpriv->vm;  	struct amdgpu_bo_va *bo_va;  	int r; -	mutex_lock(&vm->mutex);  	r = amdgpu_bo_reserve(rbo, true);  	if (r) { -		mutex_unlock(&vm->mutex);  		dev_err(adev->dev, "leaking bo va because "  			"we fail to reserve bo (%d)\n", r);  		return; @@ -157,7 +151,6 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj,  		}  	}  	amdgpu_bo_unreserve(rbo); -	mutex_unlock(&vm->mutex);  }  static int amdgpu_gem_handle_lockup(struct amdgpu_device *adev, int r) @@ -483,6 +476,9 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,  		if (domain == AMDGPU_GEM_DOMAIN_CPU)  			goto error_unreserve;  	} +	r = amdgpu_vm_update_page_directory(adev, bo_va->vm); +	if (r) +		goto error_unreserve;  	r = amdgpu_vm_clear_freed(adev, bo_va->vm);  	if (r) @@ -512,6 +508,9 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,  	struct amdgpu_fpriv *fpriv = filp->driver_priv;  	struct amdgpu_bo *rbo;  	struct amdgpu_bo_va *bo_va; +	struct ttm_validate_buffer tv, tv_pd; +	struct ww_acquire_ctx ticket; +	struct list_head list, duplicates;  	uint32_t invalid_flags, va_flags = 0;  	int r = 0; @@ -547,19 +546,28 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,  	gobj = drm_gem_object_lookup(dev, filp, args->handle);  	if (gobj == NULL)  		return -ENOENT; -	mutex_lock(&fpriv->vm.mutex);  	rbo = gem_to_amdgpu_bo(gobj); -	r = amdgpu_bo_reserve(rbo, false); +	INIT_LIST_HEAD(&list); +	INIT_LIST_HEAD(&duplicates); +	tv.bo = &rbo->tbo; +	tv.shared = true; +	list_add(&tv.head, &list); + +	if (args->operation == AMDGPU_VA_OP_MAP) { +		tv_pd.bo = &fpriv->vm.page_directory->tbo; +		tv_pd.shared = true; +		list_add(&tv_pd.head, &list); +	} +	r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates);  	if (r) { -		mutex_unlock(&fpriv->vm.mutex);  		drm_gem_object_unreference_unlocked(gobj);  		return r;  	}  	bo_va = amdgpu_vm_bo_find(&fpriv->vm, rbo);  	if (!bo_va) { -		amdgpu_bo_unreserve(rbo); -		mutex_unlock(&fpriv->vm.mutex); +		ttm_eu_backoff_reservation(&ticket, &list); +		drm_gem_object_unreference_unlocked(gobj);  		return -ENOENT;  	} @@ -581,10 +589,10 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,  	default:  		break;  	} - +	ttm_eu_backoff_reservation(&ticket, &list);  	if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE))  		amdgpu_gem_va_update_vm(adev, bo_va, args->operation); -	mutex_unlock(&fpriv->vm.mutex); +  	drm_gem_object_unreference_unlocked(gobj);  	return r;  }  | 
