LCOV - code coverage report
Current view: top level - dev/pci/drm/i915 - i915_gem_evict.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 68 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 3 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright © 2008-2010 Intel Corporation
       3             :  *
       4             :  * Permission is hereby granted, free of charge, to any person obtaining a
       5             :  * copy of this software and associated documentation files (the "Software"),
       6             :  * to deal in the Software without restriction, including without limitation
       7             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
       8             :  * and/or sell copies of the Software, and to permit persons to whom the
       9             :  * Software is furnished to do so, subject to the following conditions:
      10             :  *
      11             :  * The above copyright notice and this permission notice (including the next
      12             :  * paragraph) shall be included in all copies or substantial portions of the
      13             :  * Software.
      14             :  *
      15             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      18             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      20             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
      21             :  * IN THE SOFTWARE.
      22             :  *
      23             :  * Authors:
      24             :  *    Eric Anholt <eric@anholt.net>
      25             :  *    Chris Wilson <chris@chris-wilson.co.uuk>
      26             :  *
      27             :  */
      28             : 
      29             : #include <dev/pci/drm/drmP.h>
      30             : #include <dev/pci/drm/i915_drm.h>
      31             : 
      32             : #include "i915_drv.h"
      33             : #include "intel_drv.h"
      34             : #include "i915_trace.h"
      35             : 
      36             : static bool
      37           0 : mark_free(struct i915_vma *vma, struct list_head *unwind)
      38             : {
      39           0 :         if (vma->pin_count)
      40           0 :                 return false;
      41             : 
      42           0 :         if (WARN_ON(!list_empty(&vma->exec_list)))
      43           0 :                 return false;
      44             : 
      45           0 :         list_add(&vma->exec_list, unwind);
      46           0 :         return drm_mm_scan_add_block(&vma->node);
      47           0 : }
      48             : 
      49             : /**
      50             :  * i915_gem_evict_something - Evict vmas to make room for binding a new one
      51             :  * @dev: drm_device
      52             :  * @vm: address space to evict from
      53             :  * @min_size: size of the desired free space
      54             :  * @alignment: alignment constraint of the desired free space
      55             :  * @cache_level: cache_level for the desired space
      56             :  * @start: start (inclusive) of the range from which to evict objects
      57             :  * @end: end (exclusive) of the range from which to evict objects
      58             :  * @flags: additional flags to control the eviction algorithm
      59             :  *
      60             :  * This function will try to evict vmas until a free space satisfying the
      61             :  * requirements is found. Callers must check first whether any such hole exists
      62             :  * already before calling this function.
      63             :  *
      64             :  * This function is used by the object/vma binding code.
      65             :  *
      66             :  * Since this function is only used to free up virtual address space it only
      67             :  * ignores pinned vmas, and not object where the backing storage itself is
      68             :  * pinned. Hence obj->pages_pin_count does not protect against eviction.
      69             :  *
      70             :  * To clarify: This is for freeing up virtual address space, not for freeing
      71             :  * memory in e.g. the shrinker.
      72             :  */
      73             : int
      74           0 : i915_gem_evict_something(struct drm_device *dev, struct i915_address_space *vm,
      75             :                          int min_size, unsigned alignment, unsigned cache_level,
      76             :                          unsigned long start, unsigned long end,
      77             :                          unsigned flags)
      78             : {
      79           0 :         struct list_head eviction_list, unwind_list;
      80             :         struct i915_vma *vma;
      81             :         int ret = 0;
      82             :         int pass = 0;
      83             : 
      84           0 :         trace_i915_gem_evict(dev, min_size, alignment, flags);
      85             : 
      86             :         /*
      87             :          * The goal is to evict objects and amalgamate space in LRU order.
      88             :          * The oldest idle objects reside on the inactive list, which is in
      89             :          * retirement order. The next objects to retire are those on the (per
      90             :          * ring) active list that do not have an outstanding flush. Once the
      91             :          * hardware reports completion (the seqno is updated after the
      92             :          * batchbuffer has been finished) the clean buffer objects would
      93             :          * be retired to the inactive list. Any dirty objects would be added
      94             :          * to the tail of the flushing list. So after processing the clean
      95             :          * active objects we need to emit a MI_FLUSH to retire the flushing
      96             :          * list, hence the retirement order of the flushing list is in
      97             :          * advance of the dirty objects on the active lists.
      98             :          *
      99             :          * The retirement sequence is thus:
     100             :          *   1. Inactive objects (already retired)
     101             :          *   2. Clean active objects
     102             :          *   3. Flushing list
     103             :          *   4. Dirty active objects.
     104             :          *
     105             :          * On each list, the oldest objects lie at the HEAD with the freshest
     106             :          * object on the TAIL.
     107             :          */
     108             : 
     109           0 :         INIT_LIST_HEAD(&unwind_list);
     110           0 :         if (start != 0 || end != vm->total) {
     111           0 :                 drm_mm_init_scan_with_range(&vm->mm, min_size,
     112           0 :                                             alignment, cache_level,
     113             :                                             start, end);
     114           0 :         } else
     115           0 :                 drm_mm_init_scan(&vm->mm, min_size, alignment, cache_level);
     116             : 
     117             : search_again:
     118             :         /* First see if there is a large enough contiguous idle region... */
     119           0 :         list_for_each_entry(vma, &vm->inactive_list, mm_list) {
     120           0 :                 if (mark_free(vma, &unwind_list))
     121             :                         goto found;
     122             :         }
     123             : 
     124           0 :         if (flags & PIN_NONBLOCK)
     125             :                 goto none;
     126             : 
     127             :         /* Now merge in the soon-to-be-expired objects... */
     128           0 :         list_for_each_entry(vma, &vm->active_list, mm_list) {
     129           0 :                 if (mark_free(vma, &unwind_list))
     130             :                         goto found;
     131             :         }
     132             : 
     133             : none:
     134             :         /* Nothing found, clean up and bail out! */
     135           0 :         while (!list_empty(&unwind_list)) {
     136           0 :                 vma = list_first_entry(&unwind_list,
     137             :                                        struct i915_vma,
     138             :                                        exec_list);
     139           0 :                 ret = drm_mm_scan_remove_block(&vma->node);
     140           0 :                 BUG_ON(ret);
     141             : 
     142           0 :                 list_del_init(&vma->exec_list);
     143             :         }
     144             : 
     145             :         /* Can we unpin some objects such as idle hw contents,
     146             :          * or pending flips?
     147             :          */
     148           0 :         if (flags & PIN_NONBLOCK)
     149           0 :                 return -ENOSPC;
     150             : 
     151             :         /* Only idle the GPU and repeat the search once */
     152           0 :         if (pass++ == 0) {
     153           0 :                 ret = i915_gpu_idle(dev);
     154           0 :                 if (ret)
     155           0 :                         return ret;
     156             : 
     157           0 :                 i915_gem_retire_requests(dev);
     158           0 :                 goto search_again;
     159             :         }
     160             : 
     161             :         /* If we still have pending pageflip completions, drop
     162             :          * back to userspace to give our workqueues time to
     163             :          * acquire our locks and unpin the old scanouts.
     164             :          */
     165           0 :         return intel_has_pending_fb_unpin(dev) ? -EAGAIN : -ENOSPC;
     166             : 
     167             : found:
     168             :         /* drm_mm doesn't allow any other other operations while
     169             :          * scanning, therefore store to be evicted objects on a
     170             :          * temporary list. */
     171           0 :         INIT_LIST_HEAD(&eviction_list);
     172           0 :         while (!list_empty(&unwind_list)) {
     173           0 :                 vma = list_first_entry(&unwind_list,
     174             :                                        struct i915_vma,
     175             :                                        exec_list);
     176           0 :                 if (drm_mm_scan_remove_block(&vma->node)) {
     177           0 :                         list_move(&vma->exec_list, &eviction_list);
     178           0 :                         drm_gem_object_reference(&vma->obj->base);
     179           0 :                         continue;
     180             :                 }
     181           0 :                 list_del_init(&vma->exec_list);
     182             :         }
     183             : 
     184             :         /* Unbinding will emit any required flushes */
     185           0 :         while (!list_empty(&eviction_list)) {
     186             :                 struct drm_gem_object *obj;
     187           0 :                 vma = list_first_entry(&eviction_list,
     188             :                                        struct i915_vma,
     189             :                                        exec_list);
     190             : 
     191           0 :                 obj =  &vma->obj->base;
     192           0 :                 list_del_init(&vma->exec_list);
     193           0 :                 if (ret == 0)
     194           0 :                         ret = i915_vma_unbind(vma);
     195             : 
     196           0 :                 drm_gem_object_unreference(obj);
     197             :         }
     198             : 
     199           0 :         return ret;
     200           0 : }
     201             : 
     202             : /**
     203             :  * i915_gem_evict_vm - Evict all idle vmas from a vm
     204             :  * @vm: Address space to cleanse
     205             :  * @do_idle: Boolean directing whether to idle first.
     206             :  *
     207             :  * This function evicts all idles vmas from a vm. If all unpinned vmas should be
     208             :  * evicted the @do_idle needs to be set to true.
     209             :  *
     210             :  * This is used by the execbuf code as a last-ditch effort to defragment the
     211             :  * address space.
     212             :  *
     213             :  * To clarify: This is for freeing up virtual address space, not for freeing
     214             :  * memory in e.g. the shrinker.
     215             :  */
     216           0 : int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle)
     217             : {
     218             :         struct i915_vma *vma, *next;
     219             :         int ret;
     220             : 
     221           0 :         WARN_ON(!mutex_is_locked(&vm->dev->struct_mutex));
     222           0 :         trace_i915_gem_evict_vm(vm);
     223             : 
     224           0 :         if (do_idle) {
     225           0 :                 ret = i915_gpu_idle(vm->dev);
     226           0 :                 if (ret)
     227           0 :                         return ret;
     228             : 
     229           0 :                 i915_gem_retire_requests(vm->dev);
     230             : 
     231           0 :                 WARN_ON(!list_empty(&vm->active_list));
     232           0 :         }
     233             : 
     234           0 :         list_for_each_entry_safe(vma, next, &vm->inactive_list, mm_list)
     235           0 :                 if (vma->pin_count == 0)
     236           0 :                         WARN_ON(i915_vma_unbind(vma));
     237             : 
     238           0 :         return 0;
     239           0 : }

Generated by: LCOV version 1.13