diff options
author | Thomas Hellstrom <thellstrom-at-vmware-dot-com> | 2009-03-23 09:10:52 +0100 |
---|---|---|
committer | Thomas Hellstrom <thellstrom-at-vmware-dot-com> | 2009-03-23 09:11:48 +0100 |
commit | feb4a2b2de94f2cba3cf15be871439809e68a78d (patch) | |
tree | dc03282077e60b12649fa978708e0a695be9a2e3 | |
parent | 7f38882b15dd048b1453123526fcb0e2d27c01a8 (diff) |
ttm: Work around a locking order reversal in fault().
Signed-off-by: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
-rw-r--r-- | linux-core/ttm/ttm_bo_vm.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/linux-core/ttm/ttm_bo_vm.c b/linux-core/ttm/ttm_bo_vm.c index 3a89b3e0..d2dbf421 100644 --- a/linux-core/ttm/ttm_bo_vm.c +++ b/linux-core/ttm/ttm_bo_vm.c @@ -95,9 +95,18 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) unsigned long address = (unsigned long)vmf->virtual_address; int retval = VM_FAULT_NOPAGE; - ret = ttm_bo_reserve(bo, true, false, false, 0); - if (unlikely(ret != 0)) + /* + * 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. + */ + + ret = ttm_bo_reserve(bo, true, true, false, 0); + if (unlikely(ret != 0)) { + if (ret == -EBUSY) + set_need_resched(); return VM_FAULT_NOPAGE; + } mutex_lock(&bo->mutex); @@ -230,9 +239,18 @@ static unsigned long ttm_bo_vm_nopfn(struct vm_area_struct *vma, bool is_iomem; unsigned long retval = NOPFN_REFAULT; - ret = ttm_bo_reserve(bo, true, false, false, 0); - if (unlikely(ret != 0)) + /* + * 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. + */ + + ret = ttm_bo_reserve(bo, true, true, false, 0); + if (unlikely(ret != 0)) { + if (ret == -EBUSY) + set_need_resched(); return NOPFN_REFAULT; + } mutex_lock(&bo->mutex); |