diff mbox series

drm/i915/gt: Pull release of node->age under the spinlock

Message ID 20200730134049.8822-1-chris@chris-wilson.co.uk (mailing list archive)
State New, archived
Headers show
Series drm/i915/gt: Pull release of node->age under the spinlock | expand

Commit Message

Chris Wilson July 30, 2020, 1:40 p.m. UTC
We need to ensure that the list is valid prior to marking the node as
retrievable, otherwise we may see two threads compete over the same node
in intel_gt_get_buffer_pool(). If the first thread acquires and releases
the node in the same jiffie, the second thread may then acquire it (as
the jiffie now again matches the expected value) and claim the node
before it is put back into the list.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Matthew Auld July 30, 2020, 7:37 p.m. UTC | #1
On Thu, 30 Jul 2020 at 14:41, Chris Wilson <chris@chris-wilson.co.uk> wrote:
>
> We need to ensure that the list is valid prior to marking the node as
> retrievable, otherwise we may see two threads compete over the same node
> in intel_gt_get_buffer_pool(). If the first thread acquires and releases
> the node in the same jiffie, the second thread may then acquire it (as
> the jiffie now again matches the expected value) and claim the node
> before it is put back into the list.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c b/drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c
index 9e938d4f6bfe..4b7671ac5dca 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c
@@ -134,9 +134,9 @@  static void pool_retire(struct i915_active *ref)
 	/* Return this object to the shrinker pool */
 	i915_gem_object_make_purgeable(node->obj);
 
-	WRITE_ONCE(node->age, jiffies ?: 1); /* 0 reserved for active nodes */
 	spin_lock_irqsave(&pool->lock, flags);
 	list_add_rcu(&node->link, list);
+	WRITE_ONCE(node->age, jiffies ?: 1); /* 0 reserved for active nodes */
 	spin_unlock_irqrestore(&pool->lock, flags);
 
 	schedule_delayed_work(&pool->work,