Following the pattern now used for obj->mm.pages, use just pin_fence and
unpin_fence to control access to the fence registers. I.e. instead of
calling get_fence(); pin_fence(), we now just need to call pin_fence().
This will make it easier to reduce the locking requirements around
fence registers.

Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_drv.h            |  2 --
 drivers/gpu/drm/i915/i915_gem.c            |  3 ++-
 drivers/gpu/drm/i915/i915_gem_execbuffer.c | 10 ++++-----
 drivers/gpu/drm/i915/i915_gem_fence_reg.c  | 33 +++++++++++++++++++++++++-----
 drivers/gpu/drm/i915/i915_vma.c            |  3 +--
 drivers/gpu/drm/i915/i915_vma.h            | 20 ++++++++----------
 drivers/gpu/drm/i915/intel_display.c       |  3 +--
 7 files changed, 45 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a4b49016593e..f8d98d3736ac 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3714,8 +3714,6 @@ i915_vm_to_ppgtt(struct i915_address_space *vm)
 }
 
 /* i915_gem_fence_reg.c */
-int __must_check i915_vma_get_fence(struct i915_vma *vma);
-int __must_check i915_vma_put_fence(struct i915_vma *vma);
 struct drm_i915_fence_reg *
 i915_reserve_fence(struct drm_i915_private *dev_priv);
 void i915_unreserve_fence(struct drm_i915_fence_reg *fence);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index a72376007b64..90bf5cba712f 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1912,7 +1912,7 @@ int i915_gem_fault(struct vm_fault *vmf)
        if (ret)
                goto err_unpin;
 
-       ret = i915_vma_get_fence(vma);
+       ret = i915_vma_pin_fence(vma);
        if (ret)
                goto err_unpin;
 
@@ -1928,6 +1928,7 @@ int i915_gem_fault(struct vm_fault *vmf)
                               min_t(u64, vma->size, area->vm_end - 
area->vm_start),
                               &ggtt->mappable);
 
+       i915_vma_unpin_fence(vma);
 err_unpin:
        __i915_vma_unpin(vma);
 err_unlock:
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 7687483ff218..da12bba60c40 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -366,12 +366,12 @@ eb_pin_vma(struct i915_execbuffer *eb,
                return false;
 
        if (unlikely(exec_flags & EXEC_OBJECT_NEEDS_FENCE)) {
-               if (unlikely(i915_vma_get_fence(vma))) {
+               if (unlikely(i915_vma_pin_fence(vma))) {
                        i915_vma_unpin(vma);
                        return false;
                }
 
-               if (i915_vma_pin_fence(vma))
+               if (vma->fence)
                        exec_flags |= __EXEC_OBJECT_HAS_FENCE;
        }
 
@@ -384,7 +384,7 @@ static inline void __eb_unreserve_vma(struct i915_vma *vma, 
unsigned int flags)
        GEM_BUG_ON(!(flags & __EXEC_OBJECT_HAS_PIN));
 
        if (unlikely(flags & __EXEC_OBJECT_HAS_FENCE))
-               i915_vma_unpin_fence(vma);
+               __i915_vma_unpin_fence(vma);
 
        __i915_vma_unpin(vma);
 }
@@ -562,13 +562,13 @@ static int eb_reserve_vma(const struct i915_execbuffer 
*eb,
        }
 
        if (unlikely(exec_flags & EXEC_OBJECT_NEEDS_FENCE)) {
-               err = i915_vma_get_fence(vma);
+               err = i915_vma_pin_fence(vma);
                if (unlikely(err)) {
                        i915_vma_unpin(vma);
                        return err;
                }
 
-               if (i915_vma_pin_fence(vma))
+               if (vma->fence)
                        exec_flags |= __EXEC_OBJECT_HAS_FENCE;
        }
 
diff --git a/drivers/gpu/drm/i915/i915_gem_fence_reg.c 
b/drivers/gpu/drm/i915/i915_gem_fence_reg.c
index 2783d63bd1ad..af824b8d73ea 100644
--- a/drivers/gpu/drm/i915/i915_gem_fence_reg.c
+++ b/drivers/gpu/drm/i915/i915_gem_fence_reg.c
@@ -280,8 +280,7 @@ static int fence_update(struct drm_i915_fence_reg *fence,
  *
  * 0 on success, negative error code on failure.
  */
-int
-i915_vma_put_fence(struct i915_vma *vma)
+int i915_vma_put_fence(struct i915_vma *vma)
 {
        struct drm_i915_fence_reg *fence = vma->fence;
 
@@ -299,6 +298,8 @@ static struct drm_i915_fence_reg *fence_find(struct 
drm_i915_private *dev_priv)
        struct drm_i915_fence_reg *fence;
 
        list_for_each_entry(fence, &dev_priv->mm.fence_list, link) {
+               GEM_BUG_ON(fence->vma && fence->vma->fence != fence);
+
                if (fence->pin_count)
                        continue;
 
@@ -313,7 +314,7 @@ static struct drm_i915_fence_reg *fence_find(struct 
drm_i915_private *dev_priv)
 }
 
 /**
- * i915_vma_get_fence - set up fencing for a vma
+ * i915_vma_pin_fence - set up fencing for a vma
  * @vma: vma to map through a fence reg
  *
  * When mapping objects through the GTT, userspace wants to be able to write
@@ -331,10 +332,11 @@ static struct drm_i915_fence_reg *fence_find(struct 
drm_i915_private *dev_priv)
  * 0 on success, negative error code on failure.
  */
 int
-i915_vma_get_fence(struct i915_vma *vma)
+i915_vma_pin_fence(struct i915_vma *vma)
 {
        struct drm_i915_fence_reg *fence;
        struct i915_vma *set = i915_gem_object_is_tiled(vma->obj) ? vma : NULL;
+       int err;
 
        /* Note that we revoke fences on runtime suspend. Therefore the user
         * must keep the device awake whilst using the fence.
@@ -344,6 +346,8 @@ i915_vma_get_fence(struct i915_vma *vma)
        /* Just update our place in the LRU if our fence is getting reused. */
        if (vma->fence) {
                fence = vma->fence;
+               GEM_BUG_ON(fence->vma != vma);
+               fence->pin_count++;
                if (!fence->dirty) {
                        list_move_tail(&fence->link,
                                       &fence->i915->mm.fence_list);
@@ -353,10 +357,25 @@ i915_vma_get_fence(struct i915_vma *vma)
                fence = fence_find(vma->vm->i915);
                if (IS_ERR(fence))
                        return PTR_ERR(fence);
+
+               GEM_BUG_ON(fence->pin_count);
+               fence->pin_count++;
        } else
                return 0;
 
-       return fence_update(fence, set);
+       err = fence_update(fence, set);
+       if (err)
+               goto out_unpin;
+
+       GEM_BUG_ON(fence->vma != set);
+       GEM_BUG_ON(vma->fence != (set ? fence : NULL));
+
+       if (set)
+               return 0;
+
+out_unpin:
+       fence->pin_count--;
+       return err;
 }
 
 /**
@@ -429,6 +448,8 @@ void i915_gem_revoke_fences(struct drm_i915_private 
*dev_priv)
        for (i = 0; i < dev_priv->num_fence_regs; i++) {
                struct drm_i915_fence_reg *fence = &dev_priv->fence_regs[i];
 
+               GEM_BUG_ON(fence->vma && fence->vma->fence != fence);
+
                if (fence->vma)
                        i915_gem_release_mmap(fence->vma->obj);
        }
@@ -450,6 +471,8 @@ void i915_gem_restore_fences(struct drm_i915_private 
*dev_priv)
                struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i];
                struct i915_vma *vma = reg->vma;
 
+               GEM_BUG_ON(vma && vma->fence != reg);
+
                /*
                 * Commit delayed tiling changes if we have an object still
                 * attached to the fence, otherwise just clear the fence.
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index f15542e64808..c7d5604b4489 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -303,12 +303,11 @@ void __iomem *i915_vma_pin_iomap(struct i915_vma *vma)
 
        __i915_vma_pin(vma);
 
-       ret = i915_vma_get_fence(vma);
+       ret = i915_vma_pin_fence(vma);
        if (ret) {
                __i915_vma_unpin(vma);
                return IO_ERR_PTR(ret);
        }
-       i915_vma_pin_fence(vma);
 
        return ptr;
 }
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 347a40d08b9b..ab4a3c0b1526 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -344,15 +344,13 @@ static inline struct page *i915_vma_first_page(struct 
i915_vma *vma)
  *
  * True if the vma has a fence, false otherwise.
  */
-static inline bool
-i915_vma_pin_fence(struct i915_vma *vma)
+int i915_vma_pin_fence(struct i915_vma *vma);
+int __must_check i915_vma_put_fence(struct i915_vma *vma);
+
+static inline void __i915_vma_unpin_fence(struct i915_vma *vma)
 {
-       lockdep_assert_held(&vma->obj->base.dev->struct_mutex);
-       if (vma->fence) {
-               vma->fence->pin_count++;
-               return true;
-       } else
-               return false;
+       GEM_BUG_ON(vma->fence->pin_count <= 0);
+       vma->fence->pin_count--;
 }
 
 /**
@@ -367,10 +365,8 @@ static inline void
 i915_vma_unpin_fence(struct i915_vma *vma)
 {
        lockdep_assert_held(&vma->obj->base.dev->struct_mutex);
-       if (vma->fence) {
-               GEM_BUG_ON(vma->fence->pin_count <= 0);
-               vma->fence->pin_count--;
-       }
+       if (vma->fence)
+               __i915_vma_unpin_fence(vma);
 }
 
 #endif
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index efb8c0875fc8..581cd21065e4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2219,8 +2219,7 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, 
unsigned int rotation)
                 * something and try to run the system in a "less than optimal"
                 * mode that matches the user configuration.
                 */
-               if (i915_vma_get_fence(vma) == 0)
-                       i915_vma_pin_fence(vma);
+               i915_vma_pin_fence(vma);
        }
 
        i915_vma_get(vma);
-- 
2.14.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to