[PATCH 16/33] drm/i915: Make fence->pin_count atomic to allow unlocked unpinning

Chris Wilson chris at chris-wilson.co.uk
Tue Jul 4 18:54:48 UTC 2017


When we unpin a fence, we do no other operation than mark it available.
This we can do outside of any locking by making the operation atomic.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/gvt/aperture_gm.c    |  2 +-
 drivers/gpu/drm/i915/i915_debugfs.c       |  2 +-
 drivers/gpu/drm/i915/i915_gem_fence_reg.c | 15 ++++++++-------
 drivers/gpu/drm/i915/i915_gem_fence_reg.h |  2 +-
 drivers/gpu/drm/i915/i915_vma.h           |  9 ++++++---
 5 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/aperture_gm.c b/drivers/gpu/drm/i915/gvt/aperture_gm.c
index 325618d969fe..c34cd56eb83a 100644
--- a/drivers/gpu/drm/i915/gvt/aperture_gm.c
+++ b/drivers/gpu/drm/i915/gvt/aperture_gm.c
@@ -196,7 +196,7 @@ static int alloc_vgpu_fence(struct intel_vgpu *vgpu)
 	i = 0;
 	list_for_each_safe(pos, q, &dev_priv->mm.fence_list) {
 		reg = list_entry(pos, struct drm_i915_fence_reg, link);
-		if (reg->pin_count || reg->vma)
+		if (atomic_read(&reg->pin_count) || reg->vma)
 			continue;
 		list_del(pos);
 		vgpu->fence.regs[i] = reg;
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index a7a99c779e0b..986e9fa94d06 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -965,7 +965,7 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data)
 		struct i915_vma *vma = dev_priv->fence_regs[i].vma;
 
 		seq_printf(m, "Fence %d, pin count = %d, object = ",
-			   i, dev_priv->fence_regs[i].pin_count);
+			   i, atomic_read(&dev_priv->fence_regs[i].pin_count));
 		if (!vma)
 			seq_puts(m, "unused");
 		else
diff --git a/drivers/gpu/drm/i915/i915_gem_fence_reg.c b/drivers/gpu/drm/i915/i915_gem_fence_reg.c
index d0cd051c19fd..02d487c44a77 100644
--- a/drivers/gpu/drm/i915/i915_gem_fence_reg.c
+++ b/drivers/gpu/drm/i915/i915_gem_fence_reg.c
@@ -340,7 +340,7 @@ int i915_vma_put_fence(struct i915_vma *vma)
 
 	GEM_BUG_ON(fence->vma != vma);
 
-	if (fence->pin_count)
+	if (atomic_read(&fence->pin_count))
 		return -EBUSY;
 
 	return fence_update(fence, NULL);
@@ -353,7 +353,7 @@ static struct drm_i915_fence_reg *fence_find(struct drm_i915_private *dev_priv)
 	list_for_each_entry(fence, &dev_priv->mm.fence_list, link) {
 		GEM_BUG_ON(fence->vma && fence->vma->fence != fence);
 
-		if (fence->pin_count)
+		if (atomic_read(&fence->pin_count))
 			continue;
 
 		return fence;
@@ -400,7 +400,7 @@ i915_vma_pin_fence(struct i915_vma *vma)
 	fence = vma->fence;
 	if (fence) {
 		GEM_BUG_ON(fence->vma != vma);
-		fence->pin_count++;
+		atomic_inc(&fence->pin_count);
 		if (!fence->dirty) {
 			err = i915_gem_active_retire(&fence->pipelined,
 						     &fence->i915->drm.struct_mutex);
@@ -415,7 +415,8 @@ i915_vma_pin_fence(struct i915_vma *vma)
 		fence = fence_find(vma->vm->i915);
 		if (IS_ERR(fence))
 			return PTR_ERR(fence);
-		fence->pin_count++;
+
+		atomic_inc(&fence->pin_count);
 	} else
 		return 0;
 
@@ -426,7 +427,7 @@ i915_vma_pin_fence(struct i915_vma *vma)
 	return 0;
 
 err_unpin:
-	fence->pin_count--;
+	atomic_dec(&fence->pin_count);
 	return err;
 }
 
@@ -459,7 +460,7 @@ int i915_vma_reserve_fence(struct i915_vma *vma)
 		fence->vma = vma;
 		fence->dirty = true;
 	}
-	fence->pin_count++;
+	atomic_inc(&fence->pin_count);
 	list_move_tail(&fence->link, &fence->i915->mm.fence_list);
 
 	GEM_BUG_ON(!i915_gem_object_is_tiled(vma->obj));
@@ -478,7 +479,7 @@ int i915_vma_emit_pipelined_fence(struct i915_vma *vma,
 	int err;
 
 	lockdep_assert_held(&vma->vm->i915->drm.struct_mutex);
-	GEM_BUG_ON(fence && !fence->pin_count);
+	GEM_BUG_ON(fence && !atomic_read(&fence->pin_count));
 
 	if (!fence)
 		goto out;
diff --git a/drivers/gpu/drm/i915/i915_gem_fence_reg.h b/drivers/gpu/drm/i915/i915_gem_fence_reg.h
index ce45972fc5c6..f69d894997fb 100644
--- a/drivers/gpu/drm/i915/i915_gem_fence_reg.h
+++ b/drivers/gpu/drm/i915/i915_gem_fence_reg.h
@@ -36,7 +36,7 @@ struct drm_i915_fence_reg {
 	struct list_head link;
 	struct drm_i915_private *i915;
 	struct i915_vma *vma;
-	int pin_count;
+	atomic_t pin_count;
 	int id;
 	/**
 	 * Whether the tiling parameters for the currently
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index f0dc6eaebeab..9d95fdae017c 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -347,8 +347,8 @@ int __must_check i915_vma_put_fence(struct i915_vma *vma);
 
 static inline void __i915_vma_unpin_fence(struct i915_vma *vma)
 {
-	GEM_BUG_ON(vma->fence->pin_count <= 0);
-	vma->fence->pin_count--;
+	GEM_BUG_ON(atomic_read(&vma->fence->pin_count) <= 0);
+	atomic_dec(&vma->fence->pin_count);
 }
 
 /**
@@ -362,7 +362,10 @@ static inline void __i915_vma_unpin_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);
+	/* The assumption is if the caller has a fence, the caller owns a pin
+	 * on that fence, i.e. that vma->fence cannot become NULL prior to us
+	 * releasing our pin.
+	 */
 	if (vma->fence)
 		__i915_vma_unpin_fence(vma);
 }
-- 
2.13.2



More information about the Intel-gfx-trybot mailing list