Blob Blame History Raw
From cb0aeaa81842948e32f39838f0ec113e3bb52291 Mon Sep 17 00:00:00 2001
From: Chris Wilson <chris@chris-wilson.co.uk>
Date: Wed, 5 Jul 2017 15:26:34 +0100
Subject: [PATCH] drm/i915: Only free the oldest stale context before allocating
Git-commit: cb0aeaa81842948e32f39838f0ec113e3bb52291
Patch-mainline: v4.14-rc1
References: FATE#322643 bsc#1055900

Currently, we move all unreferenced contexts to an RCU free list and
then onto a worker for eventual reaping. To compensate against this
growing into a long list with frequent allocations starving the system
of available memory, before we allocate a new context we reap all the
stale contexts. This puts all the cost of destroying the context into
the next allocator, which is presumably more sensitive to syscall
latency and unfair. We can limit the number of contexts being freed by
the new allocator to both keep the list trimmed and to allow the
allocator to be reasonably fast.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170705142634.18554-4-chris@chris-wilson.co.uk
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Acked-by: Takashi Iwai <tiwai@suse.de>

---
 drivers/gpu/drm/i915/i915_gem_context.c |   19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -201,6 +201,21 @@ static void contexts_free(struct drm_i91
 		i915_gem_context_free(ctx);
 }
 
+static void contexts_free_first(struct drm_i915_private *i915)
+{
+	struct i915_gem_context *ctx;
+	struct llist_node *freed;
+
+	lockdep_assert_held(&i915->drm.struct_mutex);
+
+	freed = llist_del_first(&i915->contexts.free_list);
+	if (!freed)
+		return;
+
+	ctx = container_of(freed, typeof(*ctx), free_link);
+	i915_gem_context_free(ctx);
+}
+
 static void contexts_free_worker(struct work_struct *work)
 {
 	struct drm_i915_private *i915 =
@@ -383,8 +398,8 @@ i915_gem_create_context(struct drm_i915_
 
 	lockdep_assert_held(&dev_priv->drm.struct_mutex);
 
-	/* Reap stale contexts */
-	contexts_free(dev_priv);
+	/* Reap the most stale context */
+	contexts_free_first(dev_priv);
 
 	ctx = __create_hw_context(dev_priv, file_priv);
 	if (IS_ERR(ctx))