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))