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