diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 1006c15..55c487d 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -61,13 +61,22 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) /* * Work around locking order reversal in fault / nopfn * between mmap_sem and bo_reserve: Perform a trylock operation - * for reserve, and if it fails, retry the fault after scheduling. + * for reserve, and if it fails, retry the fault after releasing + * the mmap_sem and waiting. */ ret = ttm_bo_reserve(bo, true, true, false, 0); if (unlikely(ret != 0)) { - if (ret == -EBUSY) - set_need_resched(); + if (ret == -EBUSY) { + if ((vmf->flags & FAULT_FLAG_ALLOW_RETRY) && + !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) { + up_read(&vma->vm_mm->mmap_sem); + ttm_bo_reserve_nolru(bo, true, false, false, + NULL); + ww_mutex_unlock(&bo->resv->lock); + return VM_FAULT_RETRY; + } + } return VM_FAULT_NOPAGE; }