drm/i915: Allow contexts to be unreferenced locklessly
If we move the actual cleanup of the context to a worker, we can allow the final free to be called from any context and avoid undue latency in the caller. v2: Negotiate handling the delayed contexts free by flushing the workqueue before calling i915_gem_context_fini() and performing the final free of the kernel context directly v3: Flush deferred frees before new context allocations Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170620110547.15947-2-chris@chris-wilson.co.uk
This commit is contained in:
@@ -186,16 +186,20 @@ static int igt_vma_create(void *arg)
|
||||
goto end;
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(ctx, cn, &contexts, link)
|
||||
list_for_each_entry_safe(ctx, cn, &contexts, link) {
|
||||
list_del_init(&ctx->link);
|
||||
mock_context_close(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
/* Final pass to lookup all created contexts */
|
||||
err = create_vmas(i915, &objects, &contexts);
|
||||
out:
|
||||
list_for_each_entry_safe(ctx, cn, &contexts, link)
|
||||
list_for_each_entry_safe(ctx, cn, &contexts, link) {
|
||||
list_del_init(&ctx->link);
|
||||
mock_context_close(ctx);
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(obj, on, &objects, st_link)
|
||||
i915_gem_object_put(obj);
|
||||
|
@@ -86,3 +86,12 @@ void mock_context_close(struct i915_gem_context *ctx)
|
||||
|
||||
i915_gem_context_put(ctx);
|
||||
}
|
||||
|
||||
void mock_init_contexts(struct drm_i915_private *i915)
|
||||
{
|
||||
INIT_LIST_HEAD(&i915->contexts.list);
|
||||
ida_init(&i915->contexts.hw_ida);
|
||||
|
||||
INIT_WORK(&i915->contexts.free_work, contexts_free_worker);
|
||||
init_llist_head(&i915->contexts.free_list);
|
||||
}
|
||||
|
@@ -25,6 +25,8 @@
|
||||
#ifndef __MOCK_CONTEXT_H
|
||||
#define __MOCK_CONTEXT_H
|
||||
|
||||
void mock_init_contexts(struct drm_i915_private *i915);
|
||||
|
||||
struct i915_gem_context *
|
||||
mock_context(struct drm_i915_private *i915,
|
||||
const char *name);
|
||||
|
@@ -57,6 +57,7 @@ static void mock_device_release(struct drm_device *dev)
|
||||
|
||||
cancel_delayed_work_sync(&i915->gt.retire_work);
|
||||
cancel_delayed_work_sync(&i915->gt.idle_work);
|
||||
flush_workqueue(i915->wq);
|
||||
|
||||
mutex_lock(&i915->drm.struct_mutex);
|
||||
for_each_engine(engine, i915, id)
|
||||
@@ -160,7 +161,7 @@ struct drm_i915_private *mock_gem_device(void)
|
||||
INIT_LIST_HEAD(&i915->mm.unbound_list);
|
||||
INIT_LIST_HEAD(&i915->mm.bound_list);
|
||||
|
||||
ida_init(&i915->contexts.hw_ida);
|
||||
mock_init_contexts(i915);
|
||||
|
||||
INIT_DELAYED_WORK(&i915->gt.retire_work, mock_retire_work_handler);
|
||||
INIT_DELAYED_WORK(&i915->gt.idle_work, mock_idle_work_handler);
|
||||
|
Reference in New Issue
Block a user