|
@@ -66,8 +66,11 @@ static int ttm_bo_vm_fault_idle(struct ttm_buffer_object *bo,
|
|
if (vmf->flags & FAULT_FLAG_RETRY_NOWAIT)
|
|
if (vmf->flags & FAULT_FLAG_RETRY_NOWAIT)
|
|
goto out_unlock;
|
|
goto out_unlock;
|
|
|
|
|
|
|
|
+ ttm_bo_reference(bo);
|
|
up_read(&vma->vm_mm->mmap_sem);
|
|
up_read(&vma->vm_mm->mmap_sem);
|
|
(void) dma_fence_wait(bo->moving, true);
|
|
(void) dma_fence_wait(bo->moving, true);
|
|
|
|
+ ttm_bo_unreserve(bo);
|
|
|
|
+ ttm_bo_unref(&bo);
|
|
goto out_unlock;
|
|
goto out_unlock;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -120,8 +123,10 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
|
|
|
|
|
if (vmf->flags & FAULT_FLAG_ALLOW_RETRY) {
|
|
if (vmf->flags & FAULT_FLAG_ALLOW_RETRY) {
|
|
if (!(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) {
|
|
if (!(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) {
|
|
|
|
+ ttm_bo_reference(bo);
|
|
up_read(&vma->vm_mm->mmap_sem);
|
|
up_read(&vma->vm_mm->mmap_sem);
|
|
(void) ttm_bo_wait_unreserved(bo);
|
|
(void) ttm_bo_wait_unreserved(bo);
|
|
|
|
+ ttm_bo_unref(&bo);
|
|
}
|
|
}
|
|
|
|
|
|
return VM_FAULT_RETRY;
|
|
return VM_FAULT_RETRY;
|
|
@@ -166,6 +171,13 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
|
ret = ttm_bo_vm_fault_idle(bo, vma, vmf);
|
|
ret = ttm_bo_vm_fault_idle(bo, vma, vmf);
|
|
if (unlikely(ret != 0)) {
|
|
if (unlikely(ret != 0)) {
|
|
retval = ret;
|
|
retval = ret;
|
|
|
|
+
|
|
|
|
+ if (retval == VM_FAULT_RETRY &&
|
|
|
|
+ !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) {
|
|
|
|
+ /* The BO has already been unreserved. */
|
|
|
|
+ return retval;
|
|
|
|
+ }
|
|
|
|
+
|
|
goto out_unlock;
|
|
goto out_unlock;
|
|
}
|
|
}
|
|
|
|
|