mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-02-20 23:30:27 +07:00
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
@ -41,6 +41,51 @@
|
|||||||
|
|
||||||
#define TTM_BO_VM_NUM_PREFAULT 16
|
#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)
|
static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
||||||
{
|
{
|
||||||
struct ttm_buffer_object *bo = (struct ttm_buffer_object *)
|
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
|
* Wait for buffer data in transit, due to a pipelined
|
||||||
* move.
|
* move.
|
||||||
*/
|
*/
|
||||||
|
ret = ttm_bo_vm_fault_idle(bo, vma, vmf);
|
||||||
spin_lock(&bdev->fence_lock);
|
if (unlikely(ret != 0)) {
|
||||||
if (test_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags)) {
|
retval = ret;
|
||||||
ret = ttm_bo_wait(bo, false, true, false);
|
goto out_unlock;
|
||||||
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_mem_io_lock(man, true);
|
ret = ttm_mem_io_lock(man, true);
|
||||||
if (unlikely(ret != 0)) {
|
if (unlikely(ret != 0)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user