]> git.baikalelectronics.ru Git - kernel.git/commitdiff
drm/i915/gt: Fix termination condition for freeing all buffer objects
authorChris Wilson <chris@chris-wilson.co.uk>
Wed, 29 Jul 2020 11:07:56 +0000 (12:07 +0100)
committerJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Mon, 7 Sep 2020 10:14:22 +0000 (13:14 +0300)
A last minute change, that unfortunately broke CI so badly it declared
SUCCESS, was to refactor the debug free all buffer pool code to reuse
the normal worker, inverted the termination condition so that it instead
of discarding the nodes, they were all declared young enough and
eligible for reuse.

Fixes: 06b73c2d0b65 ("drm/i915/gt: Delay taking the spinlock for grabbing from the buffer pool")
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/20200729110756.2344-1-chris@chris-wilson.co.uk
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
[Joonas: Updating Fixes: link after rebasing and reordering into drm-intel-gt-next]
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c

index 16dbf543617950154edf8fa9c0357669f925fd42..9e938d4f6bfe1340fd5c8ef783a4c0f7b6e81b74 100644 (file)
@@ -38,8 +38,7 @@ static void node_free(struct intel_gt_buffer_pool_node *node)
        kfree_rcu(node, rcu);
 }
 
-static bool
-pool_free_older_than(struct intel_gt_buffer_pool *pool, unsigned long old)
+static bool pool_free_older_than(struct intel_gt_buffer_pool *pool, long keep)
 {
        struct intel_gt_buffer_pool_node *node, *stale = NULL;
        bool active = false;
@@ -57,8 +56,12 @@ pool_free_older_than(struct intel_gt_buffer_pool *pool, unsigned long old)
 
                        /* Most recent at head; oldest at tail */
                        list_for_each_prev(pos, list) {
+                               unsigned long age;
+
                                node = list_entry(pos, typeof(*node), link);
-                               if (time_before(node->age, old))
+
+                               age = READ_ONCE(node->age);
+                               if (!age || jiffies - age < keep)
                                        break;
 
                                /* Check we are the first to claim this node */
@@ -90,7 +93,7 @@ static void pool_free_work(struct work_struct *wrk)
        struct intel_gt_buffer_pool *pool =
                container_of(wrk, typeof(*pool), work.work);
 
-       if (pool_free_older_than(pool, jiffies - HZ))
+       if (pool_free_older_than(pool, HZ))
                schedule_delayed_work(&pool->work,
                                      round_jiffies_up_relative(HZ));
 }
@@ -230,7 +233,7 @@ void intel_gt_flush_buffer_pool(struct intel_gt *gt)
        struct intel_gt_buffer_pool *pool = &gt->buffer_pool;
 
        do {
-               while (pool_free_older_than(pool, jiffies + 1))
+               while (pool_free_older_than(pool, 0))
                        ;
        } while (cancel_delayed_work_sync(&pool->work));
 }