summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 4f6773ea7d85..1a87d04e7937 100644
--- 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_i915_private *i915)
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_private *dev_priv,
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))