]> git.baikalelectronics.ru Git - kernel.git/commitdiff
drm/i915: Replace i915_vma_put_fence()
authorChris Wilson <chris@chris-wilson.co.uk>
Thu, 22 Aug 2019 06:15:57 +0000 (07:15 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Thu, 22 Aug 2019 07:53:42 +0000 (08:53 +0100)
Avoid calling i915_vma_put_fence() by using our alternate paths that
bind a secondary vma avoiding the original fenced vma. For the few
instances where we need to release the fence (i.e. on binding when the
GGTT range becomes invalid), replace the put_fence with a revoke_fence.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190822061557.18402-1-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/display/intel_overlay.c
drivers/gpu/drm/i915/gem/i915_gem_domain.c
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_fence_reg.c
drivers/gpu/drm/i915/i915_vma.c
drivers/gpu/drm/i915/i915_vma.h

index eca41c4a5aa6afd2b9a4ad37ed2e488f6a5dc790..29edfc3437163c74e02ad6205eead6e65b3904dc 100644 (file)
@@ -770,10 +770,6 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
        }
        intel_frontbuffer_flush(new_bo->frontbuffer, ORIGIN_DIRTYFB);
 
-       ret = i915_vma_put_fence(vma);
-       if (ret)
-               goto out_unpin;
-
        if (!overlay->active) {
                u32 oconfig;
 
index a1afc2690e9e109ebf857f7babc8df79a9a8c7e0..9c58e8fac1d977c02dca65df0a4cb7b9ab715158 100644 (file)
@@ -221,6 +221,8 @@ restart:
         * state and so involves less work.
         */
        if (atomic_read(&obj->bind_count)) {
+               struct drm_i915_private *i915 = to_i915(obj->base.dev);
+
                /* Before we change the PTE, the GPU must not be accessing it.
                 * If we wait upon the object, we know that all the bound
                 * VMA are no longer active.
@@ -232,18 +234,30 @@ restart:
                if (ret)
                        return ret;
 
-               if (!HAS_LLC(to_i915(obj->base.dev)) &&
-                   cache_level != I915_CACHE_NONE) {
-                       /* Access to snoopable pages through the GTT is
+               if (!HAS_LLC(i915) && cache_level != I915_CACHE_NONE) {
+                       intel_wakeref_t wakeref =
+                               intel_runtime_pm_get(&i915->runtime_pm);
+
+                       /*
+                        * Access to snoopable pages through the GTT is
                         * incoherent and on some machines causes a hard
                         * lockup. Relinquish the CPU mmaping to force
                         * userspace to refault in the pages and we can
                         * then double check if the GTT mapping is still
                         * valid for that pointer access.
                         */
-                       i915_gem_object_release_mmap(obj);
+                       ret = mutex_lock_interruptible(&i915->ggtt.vm.mutex);
+                       if (ret) {
+                               intel_runtime_pm_put(&i915->runtime_pm,
+                                                    wakeref);
+                               return ret;
+                       }
 
-                       /* As we no longer need a fence for GTT access,
+                       if (obj->userfault_count)
+                               __i915_gem_object_release_mmap(obj);
+
+                       /*
+                        * As we no longer need a fence for GTT access,
                         * we can relinquish it now (and so prevent having
                         * to steal a fence from someone else on the next
                         * fence request). Note GPU activity would have
@@ -251,12 +265,17 @@ restart:
                         * supposed to be linear.
                         */
                        for_each_ggtt_vma(vma, obj) {
-                               ret = i915_vma_put_fence(vma);
+                               ret = i915_vma_revoke_fence(vma);
                                if (ret)
-                                       return ret;
+                                       break;
                        }
+                       mutex_unlock(&i915->ggtt.vm.mutex);
+                       intel_runtime_pm_put(&i915->runtime_pm, wakeref);
+                       if (ret)
+                               return ret;
                } else {
-                       /* We either have incoherent backing store and
+                       /*
+                        * We either have incoherent backing store and
                         * so no GTT access or the architecture is fully
                         * coherent. In such cases, existing GTT mmaps
                         * ignore the cache bit in the PTE and we can
index a5c3fbb53b63617af991b1efe57c9e13c555f946..f813fcb8ceb6e9eac389a7a46168f68a60180039 100644 (file)
@@ -1024,6 +1024,9 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
                struct i915_vma *vma;
                int err;
 
+               if (i915_gem_object_is_tiled(obj))
+                       return ERR_PTR(-EINVAL);
+
                if (use_cpu_reloc(cache, obj))
                        return NULL;
 
@@ -1047,12 +1050,6 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
                        if (err) /* no inactive aperture space, use cpu reloc */
                                return NULL;
                } else {
-                       err = i915_vma_put_fence(vma);
-                       if (err) {
-                               i915_vma_unpin(vma);
-                               return ERR_PTR(err);
-                       }
-
                        cache->node.start = vma->node.start;
                        cache->node.mm = (void *)vma;
                }
index 68976689d5691bda299b7aefc78494e1c890ceb6..eb31b69a316a933f34e7d2ec5d0c43d890de59bb 100644 (file)
@@ -343,20 +343,16 @@ i915_gem_gtt_pread(struct drm_i915_gem_object *obj,
                return ret;
 
        wakeref = intel_runtime_pm_get(&i915->runtime_pm);
-       vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0,
-                                      PIN_MAPPABLE |
-                                      PIN_NONBLOCK /* NOWARN */ |
-                                      PIN_NOEVICT);
+       vma = ERR_PTR(-ENODEV);
+       if (!i915_gem_object_is_tiled(obj))
+               vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0,
+                                              PIN_MAPPABLE |
+                                              PIN_NONBLOCK /* NOWARN */ |
+                                              PIN_NOEVICT);
        if (!IS_ERR(vma)) {
                node.start = i915_ggtt_offset(vma);
                node.allocated = false;
-               ret = i915_vma_put_fence(vma);
-               if (ret) {
-                       i915_vma_unpin(vma);
-                       vma = ERR_PTR(ret);
-               }
-       }
-       if (IS_ERR(vma)) {
+       } else {
                ret = insert_mappable_node(ggtt, &node, PAGE_SIZE);
                if (ret)
                        goto out_unlock;
@@ -557,20 +553,16 @@ i915_gem_gtt_pwrite_fast(struct drm_i915_gem_object *obj,
                wakeref = intel_runtime_pm_get(rpm);
        }
 
-       vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0,
-                                      PIN_MAPPABLE |
-                                      PIN_NONBLOCK /* NOWARN */ |
-                                      PIN_NOEVICT);
+       vma = ERR_PTR(-ENODEV);
+       if (!i915_gem_object_is_tiled(obj))
+               vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0,
+                                              PIN_MAPPABLE |
+                                              PIN_NONBLOCK /* NOWARN */ |
+                                              PIN_NOEVICT);
        if (!IS_ERR(vma)) {
                node.start = i915_ggtt_offset(vma);
                node.allocated = false;
-               ret = i915_vma_put_fence(vma);
-               if (ret) {
-                       i915_vma_unpin(vma);
-                       vma = ERR_PTR(ret);
-               }
-       }
-       if (IS_ERR(vma)) {
+       } else {
                ret = insert_mappable_node(ggtt, &node, PAGE_SIZE);
                if (ret)
                        goto out_rpm;
index 6a33a0bb97a979fe1560bb2d574e9d4002e33cb6..615a9f4ef30c2952f345cb224c3f5577c8d991d4 100644 (file)
@@ -287,7 +287,7 @@ static int fence_update(struct i915_fence_reg *fence,
 }
 
 /**
- * i915_vma_put_fence - force-remove fence for a VMA
+ * i915_vma_revoke_fence - force-remove fence for a VMA
  * @vma: vma to map linearly (not through a fence reg)
  *
  * This function force-removes any fence from the given object, which is useful
@@ -297,26 +297,18 @@ static int fence_update(struct i915_fence_reg *fence,
  *
  * 0 on success, negative error code on failure.
  */
-int i915_vma_put_fence(struct i915_vma *vma)
+int i915_vma_revoke_fence(struct i915_vma *vma)
 {
-       struct i915_ggtt *ggtt = i915_vm_to_ggtt(vma->vm);
        struct i915_fence_reg *fence = vma->fence;
-       int err;
 
+       lockdep_assert_held(&vma->vm->mutex);
        if (!fence)
                return 0;
 
        if (atomic_read(&fence->pin_count))
                return -EBUSY;
 
-       err = mutex_lock_interruptible(&ggtt->vm.mutex);
-       if (err)
-               return err;
-
-       err = fence_update(fence, NULL);
-       mutex_unlock(&ggtt->vm.mutex);
-
-       return err;
+       return fence_update(fence, NULL);
 }
 
 static struct i915_fence_reg *fence_find(struct drm_i915_private *i915)
index 9840cb2f70b9e11eccf06ca2b6a26d5a0ab96500..e0e677b2a3a94e8348b70fa7bdc9a3a41ad06140 100644 (file)
@@ -982,7 +982,9 @@ int i915_vma_unbind(struct i915_vma *vma)
                GEM_BUG_ON(i915_vma_has_ggtt_write(vma));
 
                /* release the fence reg _after_ flushing */
-               ret = i915_vma_put_fence(vma);
+               mutex_lock(&vma->vm->mutex);
+               ret = i915_vma_revoke_fence(vma);
+               mutex_unlock(&vma->vm->mutex);
                if (ret)
                        return ret;
 
index cf6c0437091da4ffce79c81a32c90afbfd64c409..889fc7cb910ac66e8d5396c314e3b13abf6854d9 100644 (file)
@@ -421,8 +421,8 @@ static inline struct page *i915_vma_first_page(struct i915_vma *vma)
  *
  * True if the vma has a fence, false otherwise.
  */
-int i915_vma_pin_fence(struct i915_vma *vma);
-int __must_check i915_vma_put_fence(struct i915_vma *vma);
+int __must_check i915_vma_pin_fence(struct i915_vma *vma);
+int __must_check i915_vma_revoke_fence(struct i915_vma *vma);
 
 static inline void __i915_vma_unpin_fence(struct i915_vma *vma)
 {