drm/ttm: Allow vm fault retries
Make use of the FAULT_FLAG_ALLOW_RETRY flag to allow dropping the mmap_sem while waiting for bo idle. FAULT_FLAG_ALLOW_RETRY appears to be primarily designed for disk waits but should work just as fine for GPU waits.. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>
This commit is contained in:
parent
4695b03970
commit
cbe12e74ee
1 changed files with 50 additions and 12 deletions
|
@ -41,6 +41,51 @@
|
|||
|
||||
#define TTM_BO_VM_NUM_PREFAULT 16
|
||||
|
||||
static int ttm_bo_vm_fault_idle(struct ttm_buffer_object *bo,
|
||||
struct vm_area_struct *vma,
|
||||
struct vm_fault *vmf)
|
||||
{
|
||||
struct ttm_bo_device *bdev = bo->bdev;
|
||||
int ret = 0;
|
||||
|
||||
spin_lock(&bdev->fence_lock);
|
||||
if (likely(!test_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags)))
|
||||
goto out_unlock;
|
||||
|
||||
/*
|
||||
* Quick non-stalling check for idle.
|
||||
*/
|
||||
ret = ttm_bo_wait(bo, false, false, true);
|
||||
if (likely(ret == 0))
|
||||
goto out_unlock;
|
||||
|
||||
/*
|
||||
* If possible, avoid waiting for GPU with mmap_sem
|
||||
* held.
|
||||
*/
|
||||
if (vmf->flags & FAULT_FLAG_ALLOW_RETRY) {
|
||||
ret = VM_FAULT_RETRY;
|
||||
if (vmf->flags & FAULT_FLAG_RETRY_NOWAIT)
|
||||
goto out_unlock;
|
||||
|
||||
up_read(&vma->vm_mm->mmap_sem);
|
||||
(void) ttm_bo_wait(bo, false, true, false);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ordinary wait.
|
||||
*/
|
||||
ret = ttm_bo_wait(bo, false, true, false);
|
||||
if (unlikely(ret != 0))
|
||||
ret = (ret != -ERESTARTSYS) ? VM_FAULT_SIGBUS :
|
||||
VM_FAULT_NOPAGE;
|
||||
|
||||
out_unlock:
|
||||
spin_unlock(&bdev->fence_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
||||
{
|
||||
struct ttm_buffer_object *bo = (struct ttm_buffer_object *)
|
||||
|
@ -91,18 +136,11 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
|||
* Wait for buffer data in transit, due to a pipelined
|
||||
* move.
|
||||
*/
|
||||
|
||||
spin_lock(&bdev->fence_lock);
|
||||
if (test_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags)) {
|
||||
ret = ttm_bo_wait(bo, false, true, false);
|
||||
spin_unlock(&bdev->fence_lock);
|
||||
if (unlikely(ret != 0)) {
|
||||
retval = (ret != -ERESTARTSYS) ?
|
||||
VM_FAULT_SIGBUS : VM_FAULT_NOPAGE;
|
||||
goto out_unlock;
|
||||
}
|
||||
} else
|
||||
spin_unlock(&bdev->fence_lock);
|
||||
ret = ttm_bo_vm_fault_idle(bo, vma, vmf);
|
||||
if (unlikely(ret != 0)) {
|
||||
retval = ret;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
ret = ttm_mem_io_lock(man, true);
|
||||
if (unlikely(ret != 0)) {
|
||||
|
|
Loading…
Reference in a new issue