Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright © 2008-2010 Intel Corporation
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice (including the next
0012  * paragraph) shall be included in all copies or substantial portions of the
0013  * Software.
0014  *
0015  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0016  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0017  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0018  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0019  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
0020  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
0021  * IN THE SOFTWARE.
0022  *
0023  * Authors:
0024  *    Eric Anholt <eric@anholt.net>
0025  *    Chris Wilson <chris@chris-wilson.co.uuk>
0026  *
0027  */
0028 
0029 #include "gem/i915_gem_context.h"
0030 #include "gt/intel_gt.h"
0031 #include "gt/intel_gt_requests.h"
0032 
0033 #include "i915_drv.h"
0034 #include "i915_gem_evict.h"
0035 #include "i915_trace.h"
0036 
0037 I915_SELFTEST_DECLARE(static struct igt_evict_ctl {
0038     bool fail_if_busy:1;
0039 } igt_evict_ctl;)
0040 
0041 static bool dying_vma(struct i915_vma *vma)
0042 {
0043     return !kref_read(&vma->obj->base.refcount);
0044 }
0045 
0046 static int ggtt_flush(struct intel_gt *gt)
0047 {
0048     /*
0049      * Not everything in the GGTT is tracked via vma (otherwise we
0050      * could evict as required with minimal stalling) so we are forced
0051      * to idle the GPU and explicitly retire outstanding requests in
0052      * the hopes that we can then remove contexts and the like only
0053      * bound by their active reference.
0054      */
0055     return intel_gt_wait_for_idle(gt, MAX_SCHEDULE_TIMEOUT);
0056 }
0057 
0058 static bool grab_vma(struct i915_vma *vma, struct i915_gem_ww_ctx *ww)
0059 {
0060     /*
0061      * We add the extra refcount so the object doesn't drop to zero until
0062      * after ungrab_vma(), this way trylock is always paired with unlock.
0063      */
0064     if (i915_gem_object_get_rcu(vma->obj)) {
0065         if (!i915_gem_object_trylock(vma->obj, ww)) {
0066             i915_gem_object_put(vma->obj);
0067             return false;
0068         }
0069     } else {
0070         /* Dead objects don't need pins */
0071         atomic_and(~I915_VMA_PIN_MASK, &vma->flags);
0072     }
0073 
0074     return true;
0075 }
0076 
0077 static void ungrab_vma(struct i915_vma *vma)
0078 {
0079     if (dying_vma(vma))
0080         return;
0081 
0082     i915_gem_object_unlock(vma->obj);
0083     i915_gem_object_put(vma->obj);
0084 }
0085 
0086 static bool
0087 mark_free(struct drm_mm_scan *scan,
0088       struct i915_gem_ww_ctx *ww,
0089       struct i915_vma *vma,
0090       unsigned int flags,
0091       struct list_head *unwind)
0092 {
0093     if (i915_vma_is_pinned(vma))
0094         return false;
0095 
0096     if (!grab_vma(vma, ww))
0097         return false;
0098 
0099     list_add(&vma->evict_link, unwind);
0100     return drm_mm_scan_add_block(scan, &vma->node);
0101 }
0102 
0103 static bool defer_evict(struct i915_vma *vma)
0104 {
0105     if (i915_vma_is_active(vma))
0106         return true;
0107 
0108     if (i915_vma_is_scanout(vma))
0109         return true;
0110 
0111     return false;
0112 }
0113 
0114 /**
0115  * i915_gem_evict_something - Evict vmas to make room for binding a new one
0116  * @vm: address space to evict from
0117  * @ww: An optional struct i915_gem_ww_ctx.
0118  * @min_size: size of the desired free space
0119  * @alignment: alignment constraint of the desired free space
0120  * @color: color for the desired space
0121  * @start: start (inclusive) of the range from which to evict objects
0122  * @end: end (exclusive) of the range from which to evict objects
0123  * @flags: additional flags to control the eviction algorithm
0124  *
0125  * This function will try to evict vmas until a free space satisfying the
0126  * requirements is found. Callers must check first whether any such hole exists
0127  * already before calling this function.
0128  *
0129  * This function is used by the object/vma binding code.
0130  *
0131  * Since this function is only used to free up virtual address space it only
0132  * ignores pinned vmas, and not object where the backing storage itself is
0133  * pinned. Hence obj->pages_pin_count does not protect against eviction.
0134  *
0135  * To clarify: This is for freeing up virtual address space, not for freeing
0136  * memory in e.g. the shrinker.
0137  */
0138 int
0139 i915_gem_evict_something(struct i915_address_space *vm,
0140              struct i915_gem_ww_ctx *ww,
0141              u64 min_size, u64 alignment,
0142              unsigned long color,
0143              u64 start, u64 end,
0144              unsigned flags)
0145 {
0146     struct drm_mm_scan scan;
0147     struct list_head eviction_list;
0148     struct i915_vma *vma, *next;
0149     struct drm_mm_node *node;
0150     enum drm_mm_insert_mode mode;
0151     struct i915_vma *active;
0152     int ret;
0153 
0154     lockdep_assert_held(&vm->mutex);
0155     trace_i915_gem_evict(vm, min_size, alignment, flags);
0156 
0157     /*
0158      * The goal is to evict objects and amalgamate space in rough LRU order.
0159      * Since both active and inactive objects reside on the same list,
0160      * in a mix of creation and last scanned order, as we process the list
0161      * we sort it into inactive/active, which keeps the active portion
0162      * in a rough MRU order.
0163      *
0164      * The retirement sequence is thus:
0165      *   1. Inactive objects (already retired, random order)
0166      *   2. Active objects (will stall on unbinding, oldest scanned first)
0167      */
0168     mode = DRM_MM_INSERT_BEST;
0169     if (flags & PIN_HIGH)
0170         mode = DRM_MM_INSERT_HIGH;
0171     if (flags & PIN_MAPPABLE)
0172         mode = DRM_MM_INSERT_LOW;
0173     drm_mm_scan_init_with_range(&scan, &vm->mm,
0174                     min_size, alignment, color,
0175                     start, end, mode);
0176 
0177     intel_gt_retire_requests(vm->gt);
0178 
0179 search_again:
0180     active = NULL;
0181     INIT_LIST_HEAD(&eviction_list);
0182     list_for_each_entry_safe(vma, next, &vm->bound_list, vm_link) {
0183         if (vma == active) { /* now seen this vma twice */
0184             if (flags & PIN_NONBLOCK)
0185                 break;
0186 
0187             active = ERR_PTR(-EAGAIN);
0188         }
0189 
0190         /*
0191          * We keep this list in a rough least-recently scanned order
0192          * of active elements (inactive elements are cheap to reap).
0193          * New entries are added to the end, and we move anything we
0194          * scan to the end. The assumption is that the working set
0195          * of applications is either steady state (and thanks to the
0196          * userspace bo cache it almost always is) or volatile and
0197          * frequently replaced after a frame, which are self-evicting!
0198          * Given that assumption, the MRU order of the scan list is
0199          * fairly static, and keeping it in least-recently scan order
0200          * is suitable.
0201          *
0202          * To notice when we complete one full cycle, we record the
0203          * first active element seen, before moving it to the tail.
0204          */
0205         if (active != ERR_PTR(-EAGAIN) && defer_evict(vma)) {
0206             if (!active)
0207                 active = vma;
0208 
0209             list_move_tail(&vma->vm_link, &vm->bound_list);
0210             continue;
0211         }
0212 
0213         if (mark_free(&scan, ww, vma, flags, &eviction_list))
0214             goto found;
0215     }
0216 
0217     /* Nothing found, clean up and bail out! */
0218     list_for_each_entry_safe(vma, next, &eviction_list, evict_link) {
0219         ret = drm_mm_scan_remove_block(&scan, &vma->node);
0220         BUG_ON(ret);
0221         ungrab_vma(vma);
0222     }
0223 
0224     /*
0225      * Can we unpin some objects such as idle hw contents,
0226      * or pending flips? But since only the GGTT has global entries
0227      * such as scanouts, rinbuffers and contexts, we can skip the
0228      * purge when inspecting per-process local address spaces.
0229      */
0230     if (!i915_is_ggtt(vm) || flags & PIN_NONBLOCK)
0231         return -ENOSPC;
0232 
0233     /*
0234      * Not everything in the GGTT is tracked via VMA using
0235      * i915_vma_move_to_active(), otherwise we could evict as required
0236      * with minimal stalling. Instead we are forced to idle the GPU and
0237      * explicitly retire outstanding requests which will then remove
0238      * the pinning for active objects such as contexts and ring,
0239      * enabling us to evict them on the next iteration.
0240      *
0241      * To ensure that all user contexts are evictable, we perform
0242      * a switch to the perma-pinned kernel context. This all also gives
0243      * us a termination condition, when the last retired context is
0244      * the kernel's there is no more we can evict.
0245      */
0246     if (I915_SELFTEST_ONLY(igt_evict_ctl.fail_if_busy))
0247         return -EBUSY;
0248 
0249     ret = ggtt_flush(vm->gt);
0250     if (ret)
0251         return ret;
0252 
0253     cond_resched();
0254 
0255     flags |= PIN_NONBLOCK;
0256     goto search_again;
0257 
0258 found:
0259     /* drm_mm doesn't allow any other other operations while
0260      * scanning, therefore store to-be-evicted objects on a
0261      * temporary list and take a reference for all before
0262      * calling unbind (which may remove the active reference
0263      * of any of our objects, thus corrupting the list).
0264      */
0265     list_for_each_entry_safe(vma, next, &eviction_list, evict_link) {
0266         if (drm_mm_scan_remove_block(&scan, &vma->node)) {
0267             __i915_vma_pin(vma);
0268         } else {
0269             list_del(&vma->evict_link);
0270             ungrab_vma(vma);
0271         }
0272     }
0273 
0274     /* Unbinding will emit any required flushes */
0275     ret = 0;
0276     list_for_each_entry_safe(vma, next, &eviction_list, evict_link) {
0277         __i915_vma_unpin(vma);
0278         if (ret == 0)
0279             ret = __i915_vma_unbind(vma);
0280         ungrab_vma(vma);
0281     }
0282 
0283     while (ret == 0 && (node = drm_mm_scan_color_evict(&scan))) {
0284         vma = container_of(node, struct i915_vma, node);
0285 
0286         /* If we find any non-objects (!vma), we cannot evict them */
0287         if (vma->node.color != I915_COLOR_UNEVICTABLE &&
0288             grab_vma(vma, ww)) {
0289             ret = __i915_vma_unbind(vma);
0290             ungrab_vma(vma);
0291         } else {
0292             ret = -ENOSPC;
0293         }
0294     }
0295 
0296     return ret;
0297 }
0298 
0299 /**
0300  * i915_gem_evict_for_node - Evict vmas to make room for binding a new one
0301  * @vm: address space to evict from
0302  * @ww: An optional struct i915_gem_ww_ctx.
0303  * @target: range (and color) to evict for
0304  * @flags: additional flags to control the eviction algorithm
0305  *
0306  * This function will try to evict vmas that overlap the target node.
0307  *
0308  * To clarify: This is for freeing up virtual address space, not for freeing
0309  * memory in e.g. the shrinker.
0310  */
0311 int i915_gem_evict_for_node(struct i915_address_space *vm,
0312                 struct i915_gem_ww_ctx *ww,
0313                 struct drm_mm_node *target,
0314                 unsigned int flags)
0315 {
0316     LIST_HEAD(eviction_list);
0317     struct drm_mm_node *node;
0318     u64 start = target->start;
0319     u64 end = start + target->size;
0320     struct i915_vma *vma, *next;
0321     int ret = 0;
0322 
0323     lockdep_assert_held(&vm->mutex);
0324     GEM_BUG_ON(!IS_ALIGNED(start, I915_GTT_PAGE_SIZE));
0325     GEM_BUG_ON(!IS_ALIGNED(end, I915_GTT_PAGE_SIZE));
0326 
0327     trace_i915_gem_evict_node(vm, target, flags);
0328 
0329     /*
0330      * Retire before we search the active list. Although we have
0331      * reasonable accuracy in our retirement lists, we may have
0332      * a stray pin (preventing eviction) that can only be resolved by
0333      * retiring.
0334      */
0335     intel_gt_retire_requests(vm->gt);
0336 
0337     if (i915_vm_has_cache_coloring(vm)) {
0338         /* Expand search to cover neighbouring guard pages (or lack!) */
0339         if (start)
0340             start -= I915_GTT_PAGE_SIZE;
0341 
0342         /* Always look at the page afterwards to avoid the end-of-GTT */
0343         end += I915_GTT_PAGE_SIZE;
0344     }
0345     GEM_BUG_ON(start >= end);
0346 
0347     drm_mm_for_each_node_in_range(node, &vm->mm, start, end) {
0348         /* If we find any non-objects (!vma), we cannot evict them */
0349         if (node->color == I915_COLOR_UNEVICTABLE) {
0350             ret = -ENOSPC;
0351             break;
0352         }
0353 
0354         GEM_BUG_ON(!drm_mm_node_allocated(node));
0355         vma = container_of(node, typeof(*vma), node);
0356 
0357         /*
0358          * If we are using coloring to insert guard pages between
0359          * different cache domains within the address space, we have
0360          * to check whether the objects on either side of our range
0361          * abutt and conflict. If they are in conflict, then we evict
0362          * those as well to make room for our guard pages.
0363          */
0364         if (i915_vm_has_cache_coloring(vm)) {
0365             if (node->start + node->size == target->start) {
0366                 if (node->color == target->color)
0367                     continue;
0368             }
0369             if (node->start == target->start + target->size) {
0370                 if (node->color == target->color)
0371                     continue;
0372             }
0373         }
0374 
0375         if (i915_vma_is_pinned(vma)) {
0376             ret = -ENOSPC;
0377             break;
0378         }
0379 
0380         if (flags & PIN_NONBLOCK && i915_vma_is_active(vma)) {
0381             ret = -ENOSPC;
0382             break;
0383         }
0384 
0385         if (!grab_vma(vma, ww)) {
0386             ret = -ENOSPC;
0387             break;
0388         }
0389 
0390         /*
0391          * Never show fear in the face of dragons!
0392          *
0393          * We cannot directly remove this node from within this
0394          * iterator and as with i915_gem_evict_something() we employ
0395          * the vma pin_count in order to prevent the action of
0396          * unbinding one vma from freeing (by dropping its active
0397          * reference) another in our eviction list.
0398          */
0399         __i915_vma_pin(vma);
0400         list_add(&vma->evict_link, &eviction_list);
0401     }
0402 
0403     list_for_each_entry_safe(vma, next, &eviction_list, evict_link) {
0404         __i915_vma_unpin(vma);
0405         if (ret == 0)
0406             ret = __i915_vma_unbind(vma);
0407 
0408         ungrab_vma(vma);
0409     }
0410 
0411     return ret;
0412 }
0413 
0414 /**
0415  * i915_gem_evict_vm - Evict all idle vmas from a vm
0416  * @vm: Address space to cleanse
0417  * @ww: An optional struct i915_gem_ww_ctx. If not NULL, i915_gem_evict_vm
0418  * will be able to evict vma's locked by the ww as well.
0419  *
0420  * This function evicts all vmas from a vm.
0421  *
0422  * This is used by the execbuf code as a last-ditch effort to defragment the
0423  * address space.
0424  *
0425  * To clarify: This is for freeing up virtual address space, not for freeing
0426  * memory in e.g. the shrinker.
0427  */
0428 int i915_gem_evict_vm(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww)
0429 {
0430     int ret = 0;
0431 
0432     lockdep_assert_held(&vm->mutex);
0433     trace_i915_gem_evict_vm(vm);
0434 
0435     /* Switch back to the default context in order to unpin
0436      * the existing context objects. However, such objects only
0437      * pin themselves inside the global GTT and performing the
0438      * switch otherwise is ineffective.
0439      */
0440     if (i915_is_ggtt(vm)) {
0441         ret = ggtt_flush(vm->gt);
0442         if (ret)
0443             return ret;
0444     }
0445 
0446     do {
0447         struct i915_vma *vma, *vn;
0448         LIST_HEAD(eviction_list);
0449         LIST_HEAD(locked_eviction_list);
0450 
0451         list_for_each_entry(vma, &vm->bound_list, vm_link) {
0452             if (i915_vma_is_pinned(vma))
0453                 continue;
0454 
0455             /*
0456              * If we already own the lock, trylock fails. In case
0457              * the resv is shared among multiple objects, we still
0458              * need the object ref.
0459              */
0460             if (dying_vma(vma) ||
0461                 (ww && (dma_resv_locking_ctx(vma->obj->base.resv) == &ww->ctx))) {
0462                 __i915_vma_pin(vma);
0463                 list_add(&vma->evict_link, &locked_eviction_list);
0464                 continue;
0465             }
0466 
0467             if (!i915_gem_object_trylock(vma->obj, ww))
0468                 continue;
0469 
0470             __i915_vma_pin(vma);
0471             list_add(&vma->evict_link, &eviction_list);
0472         }
0473         if (list_empty(&eviction_list) && list_empty(&locked_eviction_list))
0474             break;
0475 
0476         ret = 0;
0477         /* Unbind locked objects first, before unlocking the eviction_list */
0478         list_for_each_entry_safe(vma, vn, &locked_eviction_list, evict_link) {
0479             __i915_vma_unpin(vma);
0480 
0481             if (ret == 0)
0482                 ret = __i915_vma_unbind(vma);
0483             if (ret != -EINTR) /* "Get me out of here!" */
0484                 ret = 0;
0485         }
0486 
0487         list_for_each_entry_safe(vma, vn, &eviction_list, evict_link) {
0488             __i915_vma_unpin(vma);
0489             if (ret == 0)
0490                 ret = __i915_vma_unbind(vma);
0491             if (ret != -EINTR) /* "Get me out of here!" */
0492                 ret = 0;
0493 
0494             i915_gem_object_unlock(vma->obj);
0495         }
0496     } while (ret == 0);
0497 
0498     return ret;
0499 }
0500 
0501 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
0502 #include "selftests/i915_gem_evict.c"
0503 #endif