1. 04 10月, 2019 1 次提交
    • C
      drm/i915: Pull i915_vma_pin under the vm->mutex · 2850748e
      Chris Wilson 提交于
      Replace the struct_mutex requirement for pinning the i915_vma with the
      local vm->mutex instead. Note that the vm->mutex is tainted by the
      shrinker (we require unbinding from inside fs-reclaim) and so we cannot
      allocate while holding that mutex. Instead we have to preallocate
      workers to do allocate and apply the PTE updates after we have we
      reserved their slot in the drm_mm (using fences to order the PTE writes
      with the GPU work and with later unbind).
      
      In adding the asynchronous vma binding, one subtle requirement is to
      avoid coupling the binding fence into the backing object->resv. That is
      the asynchronous binding only applies to the vma timeline itself and not
      to the pages as that is a more global timeline (the binding of one vma
      does not need to be ordered with another vma, nor does the implicit GEM
      fencing depend on a vma, only on writes to the backing store). Keeping
      the vma binding distinct from the backing store timelines is verified by
      a number of async gem_exec_fence and gem_exec_schedule tests. The way we
      do this is quite simple, we keep the fence for the vma binding separate
      and only wait on it as required, and never add it to the obj->resv
      itself.
      
      Another consequence in reducing the locking around the vma is the
      destruction of the vma is no longer globally serialised by struct_mutex.
      A natural solution would be to add a kref to i915_vma, but that requires
      decoupling the reference cycles, possibly by introducing a new
      i915_mm_pages object that is own by both obj->mm and vma->pages.
      However, we have not taken that route due to the overshadowing lmem/ttm
      discussions, and instead play a series of complicated games with
      trylocks to (hopefully) ensure that only one destruction path is called!
      
      v2: Add some commentary, and some helpers to reduce patch churn.
      Signed-off-by: NChris Wilson <chris@chris-wilson.co.uk>
      Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
      Reviewed-by: NTvrtko Ursulin <tvrtko.ursulin@intel.com>
      Link: https://patchwork.freedesktop.org/patch/msgid/20191004134015.13204-4-chris@chris-wilson.co.uk
      2850748e
  2. 11 9月, 2019 1 次提交
  3. 03 9月, 2019 1 次提交
    • C
      drm/i915: Replace obj->pin_global with obj->frontbuffer · 5a90606d
      Chris Wilson 提交于
      obj->pin_global was originally used as a means to keep the shrinker off
      the active scanout, but we use the vma->pin_count itself for that and
      the obj->frontbuffer to delay shrinking active framebuffers. The other
      role that obj->pin_global gained was for spotting display objects inside
      GEM and working harder to keep those coherent; for which we can again
      simply inspect obj->frontbuffer directly.
      
      Coming up next, we will want to manipulate the pin_global counter
      outside of the principle locks, so would need to make pin_global atomic.
      However, since obj->frontbuffer is already managed atomically, it makes
      sense to use that the primary key for display objects instead of having
      pin_global.
      
      Ville pointed out the principle difference is that obj->frontbuffer is
      set for as long as an intel_framebuffer is attached to an object, but
      obj->pin_global was only raised for as long as the object was active. In
      practice, this means that we consider the object as being on the scanout
      for longer than is strictly required, causing us to be more proactive in
      flushing -- though it should be true that we would have flushed
      eventually when the back became the front, except that on the flip path
      that flush is async but when hit from another ioctl it will be
      synchronous.
      
      v2: i915_gem_object_is_framebuffer()
      Signed-off-by: NChris Wilson <chris@chris-wilson.co.uk>
      Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
      Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
      Reviewed-by: NVille Syrjälä <ville.syrjala@linux.intel.com>
      Link: https://patchwork.freedesktop.org/patch/msgid/20190902040303.14195-5-chris@chris-wilson.co.uk
      5a90606d
  4. 06 8月, 2019 1 次提交
  5. 03 8月, 2019 1 次提交
    • C
      drm/i915: Hide unshrinkable context objects from the shrinker · 1aff1903
      Chris Wilson 提交于
      The shrinker cannot touch objects used by the contexts (logical state
      and ring). Currently we mark those as "pin_global" to let the shrinker
      skip over them, however, if we remove them from the shrinker lists
      entirely, we don't event have to include them in our shrink accounting.
      
      By keeping the unshrinkable objects in our shrinker tracking, we report
      a large number of objects available to be shrunk, and leave the shrinker
      deeply unsatisfied when we fail to reclaim those. The shrinker will
      persist in trying to reclaim the unavailable objects, forcing the system
      into a livelock (not even hitting the dread oomkiller).
      
      v2: Extend unshrinkable protection for perma-pinned scratch and guc
      allocations (Tvrtko)
      v3: Notice that we should be pinned when marking unshrinkable and so the
      link cannot be empty; merge duplicate paths.
      Signed-off-by: NChris Wilson <chris@chris-wilson.co.uk>
      Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
      Reviewed-by: NMatthew Auld <matthew.auld@intel.com>
      Link: https://patchwork.freedesktop.org/patch/msgid/20190802212137.22207-1-chris@chris-wilson.co.uk
      1aff1903
  6. 03 7月, 2019 1 次提交
  7. 22 6月, 2019 2 次提交
  8. 19 6月, 2019 1 次提交
  9. 15 6月, 2019 1 次提交
    • C
      drm/i915: Keep contexts pinned until after the next kernel context switch · ce476c80
      Chris Wilson 提交于
      We need to keep the context image pinned in memory until after the GPU
      has finished writing into it. Since it continues to write as we signal
      the final breadcrumb, we need to keep it pinned until the request after
      it is complete. Currently we know the order in which requests execute on
      each engine, and so to remove that presumption we need to identify a
      request/context-switch we know must occur after our completion. Any
      request queued after the signal must imply a context switch, for
      simplicity we use a fresh request from the kernel context.
      
      The sequence of operations for keeping the context pinned until saved is:
      
       - On context activation, we preallocate a node for each physical engine
         the context may operate on. This is to avoid allocations during
         unpinning, which may be from inside FS_RECLAIM context (aka the
         shrinker)
      
       - On context deactivation on retirement of the last active request (which
         is before we know the context has been saved), we add the
         preallocated node onto a barrier list on each engine
      
       - On engine idling, we emit a switch to kernel context. When this
         switch completes, we know that all previous contexts must have been
         saved, and so on retiring this request we can finally unpin all the
         contexts that were marked as deactivated prior to the switch.
      
      We can enhance this in future by flushing all the idle contexts on a
      regular heartbeat pulse of a switch to kernel context, which will also
      be used to check for hung engines.
      
      v2: intel_context_active_acquire/_release
      Signed-off-by: NChris Wilson <chris@chris-wilson.co.uk>
      Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
      Reviewed-by: NMika Kuoppala <mika.kuoppala@linux.intel.com>
      Link: https://patchwork.freedesktop.org/patch/msgid/20190614164606.15633-1-chris@chris-wilson.co.uk
      ce476c80
  10. 14 6月, 2019 2 次提交
  11. 12 6月, 2019 2 次提交
  12. 11 6月, 2019 1 次提交
  13. 01 6月, 2019 2 次提交
    • C
      drm/i915: Report all objects with allocated pages to the shrinker · d82b4b26
      Chris Wilson 提交于
      Currently, we try to report to the shrinker the precise number of
      objects (pages) that are available to be reaped at this moment. This
      requires searching all objects with allocated pages to see if they
      fulfill the search criteria, and this count is performed quite
      frequently. (The shrinker tries to free ~128 pages on each invocation,
      before which we count all the objects; counting takes longer than
      unbinding the objects!) If we take the pragmatic view that with
      sufficient desire, all objects are eventually reapable (they become
      inactive, or no longer used as framebuffer etc), we can simply return
      the count of pinned pages maintained during get_pages/put_pages rather
      than walk the lists every time.
      
      The downside is that we may (slightly) over-report the number of
      objects/pages we could shrink and so penalize ourselves by shrinking
      more than required. This is mitigated by keeping the order in which we
      shrink objects such that we avoid penalizing active and frequently used
      objects, and if memory is so tight that we need to free them we would
      need to anyway.
      
      v2: Only expose shrinkable objects to the shrinker; a small reduction in
      not considering stolen and foreign objects.
      v3: Restore the tracking from a "backup" copy from before the gem/ split
      Signed-off-by: NChris Wilson <chris@chris-wilson.co.uk>
      Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
      Cc: Matthew Auld <matthew.auld@intel.com>
      Reviewed-by: NMatthew Auld <matthew.auld@intel.com>
      Link: https://patchwork.freedesktop.org/patch/msgid/20190530203500.26272-2-chris@chris-wilson.co.uk
      d82b4b26
    • C
      drm/i915: Track the purgeable objects on a separate eviction list · 3b4fa964
      Chris Wilson 提交于
      Currently the purgeable objects, I915_MADV_DONTNEED, are mixed in the
      normal bound/unbound lists. Every shrinker pass starts with an attempt
      to purge from this set of unneeded objects, which entails us doing a
      walk over both lists looking for any candidates. If there are none, and
      since we are shrinking we can reasonably assume that the lists are
      full!, this becomes a very slow futile walk.
      
      If we separate out the purgeable objects into own list, this search then
      becomes its own phase that is preferentially handled during shrinking.
      Instead the cost becomes that we then need to filter the purgeable list
      if we want to distinguish between bound and unbound objects.
      Signed-off-by: NChris Wilson <chris@chris-wilson.co.uk>
      Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
      Cc: Matthew Auld <matthew.william.auld@gmail.com>
      Reviewed-by: NMatthew Auld <matthew.william.auld@gmail.com>
      Link: https://patchwork.freedesktop.org/patch/msgid/20190530203500.26272-1-chris@chris-wilson.co.uk
      3b4fa964
  14. 28 5月, 2019 2 次提交
  15. 20 4月, 2019 1 次提交
    • C
      drm/i915: Start writeback from the shrinker · 2d6692e6
      Chris Wilson 提交于
      When we are called to relieve mempressue via the shrinker, the only way
      we can make progress is either by discarding unwanted pages (those
      objects that userspace has marked MADV_DONTNEED) or by reclaiming the
      dirty objects via swap. As we know that is the only way to make further
      progress, we can initiate the writeback as we invalidate the objects.
      This means the objects we put onto the inactive anon lru list are
      already marked for reclaim+writeback and so will trigger a wait upon the
      writeback inside direct reclaim, greatly improving the success rate of
      direct reclaim on i915 objects.
      
      The corollary is that we may start a slow swap on opportunistic
      mempressure from the likes of the compaction + migration kthreads. This
      is limited by those threads only being allowed to shrink idle pages, but
      also that if we reactivate the page before it is swapped out by gpu
      activity, we only page the cost of repinning the page. The cost is most
      felt when an object is reused after mempressure, which hopefully
      excludes the latency sensitive tasks (as we are just extending the
      impact of swap thrashing to them).
      
      Apparently this is not the first time we've had this idea. Back in
      commit 5537252b ("drm/i915: Invalidate our pages under memory
      pressure") we wanted to start writeback but settled on invalidate after
      Hugh Dickins warned us about a possibility of a deadlock within shmemfs
      if we started writeback from shrink_slab. Looking at the callchain,
      using writeback from i915_gem_shrink should be equivalent to the pageout
      also employed by shrink_slab, i.e. it should not be any riskier afaict.
      
      v2: Leave mmapings intact. At this point, the only mmapings of our
      objects will be via CPU mmaps on the shmemfs filp, which are
      out-of-scope for our LRU tracking. Instead leave those pages to the
      inactive anon LRU page list for aging and pageout as normal.
      
      v3: Be selective on which paths trigger writeback, in particular
      excluding paths shrinking just to reclaim vm space (e.g. mmap, vmap
      reapers) and avoid starting writeback on the entire process space from
      within the pm freezer.
      
      References: https://bugs.freedesktop.org/show_bug.cgi?id=108686Signed-off-by: NChris Wilson <chris@chris-wilson.co.uk>
      Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
      Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
      Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
      Cc: Matthew Auld <matthew.auld@intel.com>
      Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
      Cc: Michal Hocko <mhocko@suse.com>
      Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> #v1
      Link: https://patchwork.freedesktop.org/patch/msgid/20190420115539.29081-1-chris@chris-wilson.co.uk
      2d6692e6
  16. 29 1月, 2019 2 次提交
    • C
      drm/i915: Pull VM lists under the VM mutex. · 09d7e46b
      Chris Wilson 提交于
      A starting point to counter the pervasive struct_mutex. For the goal of
      avoiding (or at least blocking under them!) global locks during user
      request submission, a simple but important step is being able to manage
      each clients GTT separately. For which, we want to replace using the
      struct_mutex as the guard for all things GTT/VM and switch instead to a
      specific mutex inside i915_address_space.
      Signed-off-by: NChris Wilson <chris@chris-wilson.co.uk>
      Reviewed-by: NTvrtko Ursulin <tvrtko.ursulin@intel.com>
      Link: https://patchwork.freedesktop.org/patch/msgid/20190128102356.15037-2-chris@chris-wilson.co.uk
      09d7e46b
    • C
      drm/i915: Stop tracking MRU activity on VMA · 499197dc
      Chris Wilson 提交于
      Our goal is to remove struct_mutex and replace it with fine grained
      locking. One of the thorny issues is our eviction logic for reclaiming
      space for an execbuffer (or GTT mmaping, among a few other examples).
      While eviction itself is easy to move under a per-VM mutex, performing
      the activity tracking is less agreeable. One solution is not to do any
      MRU tracking and do a simple coarse evaluation during eviction of
      active/inactive, with a loose temporal ordering of last
      insertion/evaluation. That keeps all the locking constrained to when we
      are manipulating the VM itself, neatly avoiding the tricky handling of
      possible recursive locking during execbuf and elsewhere.
      
      Note that discarding the MRU (currently implemented as a pair of lists,
      to avoid scanning the active list for a NONBLOCKING search) is unlikely
      to impact upon our efficiency to reclaim VM space (where we think a LRU
      model is best) as our current strategy is to use random idle replacement
      first before doing a search, and over time the use of softpinned 48b
      per-ppGTT is growing (thereby eliminating any need to perform any eviction
      searches, in theory at least) with the remaining users being found on
      much older devices (gen2-gen6).
      
      v2: Changelog and commentary rewritten to elaborate on the duality of a
      single list being both an inactive and active list.
      v3: Consolidate bool parameters into a single set of flags; don't
      comment on the duality of a single variable being a multiplicity of
      bits.
      Signed-off-by: NChris Wilson <chris@chris-wilson.co.uk>
      Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
      Reviewed-by: NTvrtko Ursulin <tvrtko.ursulin@intel.com>
      Link: https://patchwork.freedesktop.org/patch/msgid/20190128102356.15037-1-chris@chris-wilson.co.uk
      499197dc
  17. 15 1月, 2019 3 次提交
  18. 10 1月, 2019 2 次提交
  19. 09 1月, 2019 1 次提交
  20. 08 1月, 2019 1 次提交
    • C
      drm/i915: Return immediately if trylock fails for direct-reclaim · d25f71a1
      Chris Wilson 提交于
      Ignore trying to shrink from i915 if we fail to acquire the struct_mutex
      in the shrinker while performing direct-reclaim. The trade-off being
      (much) lower latency for non-i915 clients at an increased risk of being
      unable to obtain a page from direct-reclaim without hitting the
      oom-notifier. The proviso being that we still keep trying to hard
      obtain the lock for kswapd so that we can reap under heavy memory
      pressure.
      
      v2: Taint all mutexes taken within the shrinker with the struct_mutex
      subclass as an early warning system, and drop I915_SHRINK_ACTIVE from
      vmap to reduce the number of dangerous paths. We also have to drop
      I915_SHRINK_ACTIVE from oom-notifier to be able to make the same claim
      that ACTIVE is only used from outside context, which fits in with a
      longer strategy of avoiding stalls due to scanning active during
      shrinking.
      
      The danger in using the subclass struct_mutex is that we declare
      ourselves more knowledgable than lockdep and deprive ourselves of
      automatic coverage. Instead, we require ourselves to mark up any mutex
      taken inside the shrinker in order to detect lock-inversion, and if we
      miss any we are doomed to a deadlock at the worst possible moment.
      Signed-off-by: NChris Wilson <chris@chris-wilson.co.uk>
      Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
      Reviewed-by: NTvrtko Ursulin <tvrtko.ursulin@intel.com>
      Link: https://patchwork.freedesktop.org/patch/msgid/20190107115509.12523-1-chris@chris-wilson.co.uk
      d25f71a1
  21. 11 7月, 2018 1 次提交
  22. 09 7月, 2018 1 次提交
    • C
      drm/i915: Provide a timeout to i915_gem_wait_for_idle() · ec625fb9
      Chris Wilson 提交于
      Usually we have no idea about the upper bound we need to wait to catch
      up with userspace when idling the device, but in a few situations we
      know the system was idle beforehand and can provide a short timeout in
      order to very quickly catch a failure, long before hangcheck kicks in.
      
      In the following patches, we will use the timeout to curtain two overly
      long waits, where we know we can expect the GPU to complete within a
      reasonable time or declare it broken.
      
      In particular, with a broken GPU we expect it to fail during the initial
      GPU setup where do a couple of context switches to record the defaults.
      This is a task that takes a few milliseconds even on the slowest of
      devices, but we may have to wait 60s for hangcheck to give in and
      declare the machine inoperable. In this a case where any gpu hang is
      unacceptable, both from a timeliness and practical standpoint.
      
      The other improvement is that in selftests, we do not need to arm an
      independent timer to inject a wedge, as we can just limit the timeout on
      the wait directly.
      
      v2: Include the timeout parameter in the trace.
      Signed-off-by: NChris Wilson <chris@chris-wilson.co.uk>
      Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
      Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
      Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
      Reviewed-by: NMika Kuoppala <mika.kuoppala@linux.intel.com>
      Link: https://patchwork.freedesktop.org/patch/msgid/20180709122044.7028-1-chris@chris-wilson.co.uk
      ec625fb9
  23. 06 6月, 2018 1 次提交
  24. 22 2月, 2018 1 次提交
  25. 01 2月, 2018 1 次提交
  26. 18 1月, 2018 1 次提交
  27. 28 11月, 2017 2 次提交
  28. 09 11月, 2017 1 次提交
    • C
      drm/i915: Idle the GPU before shinking everything · 0676e794
      Chris Wilson 提交于
      The handling of contexts are peculiar. Instead of tieing their vma to
      activity, we pin the context. This means that we cannot simply unbind
      the context object itself at will (which would normally cause us to wait
      for the vma to be idle), but must manually idle the GPU and retire
      requests first.
      
      A consequence of this peculiarity is when doing a last desperate attempt
      to recover memory. If the memory is tied up inside active context
      objects, we will fail to recover any memory simply by trying to unbind
      the objects without first doing a wait-for-idle.
      
      A side-effect of removing the call to shrinker_lock_uninterruptible()
      from i915_gem_shrinker_oom() was that we removed an unlocked
      wait-for-idle, and so lost the "natural" shrinkage of context objects.
      By replacing that with a locked wait from inside i915_gem_shrink(), we
      not only replace it with the ability to recover all context objects, but
      do so for all i915_gem_shrink_all() callers.
      
      v2: Switching requires request allocation, which is not permitted from
      inside the shrinker as it only uses ordinary allocations.
      
      References: https://bugs.freedesktop.org/show_bug.cgi?id=102936
      Fixes: f2123818 ("drm/i915: Move dev_priv->mm.[un]bound_list to its own lock")
      Signed-off-by: NChris Wilson <chris@chris-wilson.co.uk>
      Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
      Link: https://patchwork.freedesktop.org/patch/msgid/20171108094400.1386-1-chris@chris-wilson.co.ukReviewed-by: NJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
      (cherry picked from commit 2f6a3783)
      Signed-off-by: NJani Nikula <jani.nikula@intel.com>
      0676e794
  29. 08 11月, 2017 1 次提交
    • C
      drm/i915: Idle the GPU before shinking everything · 2f6a3783
      Chris Wilson 提交于
      The handling of contexts are peculiar. Instead of tieing their vma to
      activity, we pin the context. This means that we cannot simply unbind
      the context object itself at will (which would normally cause us to wait
      for the vma to be idle), but must manually idle the GPU and retire
      requests first.
      
      A consequence of this peculiarity is when doing a last desperate attempt
      to recover memory. If the memory is tied up inside active context
      objects, we will fail to recover any memory simply by trying to unbind
      the objects without first doing a wait-for-idle.
      
      A side-effect of removing the call to shrinker_lock_uninterruptible()
      from i915_gem_shrinker_oom() was that we removed an unlocked
      wait-for-idle, and so lost the "natural" shrinkage of context objects.
      By replacing that with a locked wait from inside i915_gem_shrink(), we
      not only replace it with the ability to recover all context objects, but
      do so for all i915_gem_shrink_all() callers.
      
      v2: Switching requires request allocation, which is not permitted from
      inside the shrinker as it only uses ordinary allocations.
      
      References: https://bugs.freedesktop.org/show_bug.cgi?id=102936
      Fixes: f2123818 ("drm/i915: Move dev_priv->mm.[un]bound_list to its own lock")
      Signed-off-by: NChris Wilson <chris@chris-wilson.co.uk>
      Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
      Link: https://patchwork.freedesktop.org/patch/msgid/20171108094400.1386-1-chris@chris-wilson.co.ukReviewed-by: NJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
      2f6a3783
  30. 17 10月, 2017 1 次提交