drm/i915/gt: Pull release of node->age under the spinlock
authorChris Wilson <chris@chris-wilson.co.uk>
Thu, 30 Jul 2020 13:40:49 +0000 (14:40 +0100)
committerJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Mon, 7 Sep 2020 10:16:58 +0000 (13:16 +0300)
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>
Link: https://patchwork.freedesktop.org/patch/msgid/20200730134049.8822-1-chris@chris-wilson.co.uk
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c

index 9e938d4f6bfe1340fd5c8ef783a4c0f7b6e81b74..4b7671ac5dca417c8fe3a2e9787591f5dd3ba4f2 100644 (file)
@@ -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,