diff options
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem_evict.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index b7376533633d..8f3adc7d0dc8 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c | |||
| @@ -88,6 +88,7 @@ i915_gem_evict_something(struct drm_device *dev, struct i915_address_space *vm, | |||
| 88 | } else | 88 | } else |
| 89 | drm_mm_init_scan(&vm->mm, min_size, alignment, cache_level); | 89 | drm_mm_init_scan(&vm->mm, min_size, alignment, cache_level); |
| 90 | 90 | ||
| 91 | search_again: | ||
| 91 | /* First see if there is a large enough contiguous idle region... */ | 92 | /* First see if there is a large enough contiguous idle region... */ |
| 92 | list_for_each_entry(vma, &vm->inactive_list, mm_list) { | 93 | list_for_each_entry(vma, &vm->inactive_list, mm_list) { |
| 93 | if (mark_free(vma, &unwind_list)) | 94 | if (mark_free(vma, &unwind_list)) |
| @@ -115,10 +116,17 @@ none: | |||
| 115 | list_del_init(&vma->exec_list); | 116 | list_del_init(&vma->exec_list); |
| 116 | } | 117 | } |
| 117 | 118 | ||
| 118 | /* We expect the caller to unpin, evict all and try again, or give up. | 119 | /* Can we unpin some objects such as idle hw contents, |
| 119 | * So calling i915_gem_evict_vm() is unnecessary. | 120 | * or pending flips? |
| 120 | */ | 121 | */ |
| 121 | return -ENOSPC; | 122 | ret = nonblocking ? -ENOSPC : i915_gpu_idle(dev); |
| 123 | if (ret) | ||
| 124 | return ret; | ||
| 125 | |||
| 126 | /* Only idle the GPU and repeat the search once */ | ||
| 127 | i915_gem_retire_requests(dev); | ||
| 128 | nonblocking = true; | ||
| 129 | goto search_again; | ||
| 122 | 130 | ||
| 123 | found: | 131 | found: |
| 124 | /* drm_mm doesn't allow any other other operations while | 132 | /* drm_mm doesn't allow any other other operations while |
