drm/i915/gem: Drop free_work for GEM contexts

The free_list and worker was introduced in commit 5f09a9c8ab ("drm/i915:
Allow contexts to be unreferenced locklessly"), but subsequently made
redundant by the removal of the last sleeping lock in commit 2935ed5339
("drm/i915: Remove logical HW ID"). As we can now free the GEM context
immediately from any context, remove the deferral of the free_list

v2: Lift removing the context from the global list into close().

Suggested-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215152138.8158-1-chris@chris-wilson.co.uk
This commit is contained in:
Chris Wilson 2020-12-15 15:21:38 +00:00
parent 5f22cc0b13
commit f8246cf4d9
6 changed files with 8 additions and 60 deletions

View file

@ -334,13 +334,12 @@ static struct i915_gem_engines *default_engines(struct i915_gem_context *ctx)
return e; return e;
} }
static void i915_gem_context_free(struct i915_gem_context *ctx) void i915_gem_context_release(struct kref *ref)
{ {
GEM_BUG_ON(!i915_gem_context_is_closed(ctx)); struct i915_gem_context *ctx = container_of(ref, typeof(*ctx), ref);
spin_lock(&ctx->i915->gem.contexts.lock); trace_i915_context_free(ctx);
list_del(&ctx->link); GEM_BUG_ON(!i915_gem_context_is_closed(ctx));
spin_unlock(&ctx->i915->gem.contexts.lock);
mutex_destroy(&ctx->engines_mutex); mutex_destroy(&ctx->engines_mutex);
mutex_destroy(&ctx->lut_mutex); mutex_destroy(&ctx->lut_mutex);
@ -354,37 +353,6 @@ static void i915_gem_context_free(struct i915_gem_context *ctx)
kfree_rcu(ctx, rcu); kfree_rcu(ctx, rcu);
} }
static void contexts_free_all(struct llist_node *list)
{
struct i915_gem_context *ctx, *cn;
llist_for_each_entry_safe(ctx, cn, list, free_link)
i915_gem_context_free(ctx);
}
static void contexts_flush_free(struct i915_gem_contexts *gc)
{
contexts_free_all(llist_del_all(&gc->free_list));
}
static void contexts_free_worker(struct work_struct *work)
{
struct i915_gem_contexts *gc =
container_of(work, typeof(*gc), free_work);
contexts_flush_free(gc);
}
void i915_gem_context_release(struct kref *ref)
{
struct i915_gem_context *ctx = container_of(ref, typeof(*ctx), ref);
struct i915_gem_contexts *gc = &ctx->i915->gem.contexts;
trace_i915_context_free(ctx);
if (llist_add(&ctx->free_link, &gc->free_list))
schedule_work(&gc->free_work);
}
static inline struct i915_gem_engines * static inline struct i915_gem_engines *
__context_engines_static(const struct i915_gem_context *ctx) __context_engines_static(const struct i915_gem_context *ctx)
{ {
@ -633,6 +601,10 @@ static void context_close(struct i915_gem_context *ctx)
*/ */
lut_close(ctx); lut_close(ctx);
spin_lock(&ctx->i915->gem.contexts.lock);
list_del(&ctx->link);
spin_unlock(&ctx->i915->gem.contexts.lock);
mutex_unlock(&ctx->mutex); mutex_unlock(&ctx->mutex);
/* /*
@ -850,9 +822,6 @@ i915_gem_create_context(struct drm_i915_private *i915, unsigned int flags)
!HAS_EXECLISTS(i915)) !HAS_EXECLISTS(i915))
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
/* Reap the stale contexts */
contexts_flush_free(&i915->gem.contexts);
ctx = __create_context(i915); ctx = __create_context(i915);
if (IS_ERR(ctx)) if (IS_ERR(ctx))
return ctx; return ctx;
@ -897,9 +866,6 @@ static void init_contexts(struct i915_gem_contexts *gc)
{ {
spin_lock_init(&gc->lock); spin_lock_init(&gc->lock);
INIT_LIST_HEAD(&gc->list); INIT_LIST_HEAD(&gc->list);
INIT_WORK(&gc->free_work, contexts_free_worker);
init_llist_head(&gc->free_list);
} }
void i915_gem_init__contexts(struct drm_i915_private *i915) void i915_gem_init__contexts(struct drm_i915_private *i915)
@ -907,12 +873,6 @@ void i915_gem_init__contexts(struct drm_i915_private *i915)
init_contexts(&i915->gem.contexts); init_contexts(&i915->gem.contexts);
} }
void i915_gem_driver_release__contexts(struct drm_i915_private *i915)
{
flush_work(&i915->gem.contexts.free_work);
rcu_barrier(); /* and flush the left over RCU frees */
}
static int gem_context_register(struct i915_gem_context *ctx, static int gem_context_register(struct i915_gem_context *ctx,
struct drm_i915_file_private *fpriv, struct drm_i915_file_private *fpriv,
u32 *id) u32 *id)
@ -986,7 +946,6 @@ int i915_gem_context_open(struct drm_i915_private *i915,
void i915_gem_context_close(struct drm_file *file) void i915_gem_context_close(struct drm_file *file)
{ {
struct drm_i915_file_private *file_priv = file->driver_priv; struct drm_i915_file_private *file_priv = file->driver_priv;
struct drm_i915_private *i915 = file_priv->dev_priv;
struct i915_address_space *vm; struct i915_address_space *vm;
struct i915_gem_context *ctx; struct i915_gem_context *ctx;
unsigned long idx; unsigned long idx;
@ -998,8 +957,6 @@ void i915_gem_context_close(struct drm_file *file)
xa_for_each(&file_priv->vm_xa, idx, vm) xa_for_each(&file_priv->vm_xa, idx, vm)
i915_vm_put(vm); i915_vm_put(vm);
xa_destroy(&file_priv->vm_xa); xa_destroy(&file_priv->vm_xa);
contexts_flush_free(&i915->gem.contexts);
} }
int i915_gem_vm_create_ioctl(struct drm_device *dev, void *data, int i915_gem_vm_create_ioctl(struct drm_device *dev, void *data,

View file

@ -110,7 +110,6 @@ i915_gem_context_clear_user_engines(struct i915_gem_context *ctx)
/* i915_gem_context.c */ /* i915_gem_context.c */
void i915_gem_init__contexts(struct drm_i915_private *i915); void i915_gem_init__contexts(struct drm_i915_private *i915);
void i915_gem_driver_release__contexts(struct drm_i915_private *i915);
int i915_gem_context_open(struct drm_i915_private *i915, int i915_gem_context_open(struct drm_i915_private *i915,
struct drm_file *file); struct drm_file *file);

View file

@ -108,7 +108,6 @@ struct i915_gem_context {
/** link: place with &drm_i915_private.context_list */ /** link: place with &drm_i915_private.context_list */
struct list_head link; struct list_head link;
struct llist_node free_link;
/** /**
* @ref: reference count * @ref: reference count

View file

@ -1172,9 +1172,6 @@ struct drm_i915_private {
struct i915_gem_contexts { struct i915_gem_contexts {
spinlock_t lock; /* locks list */ spinlock_t lock; /* locks list */
struct list_head list; struct list_head list;
struct llist_head free_list;
struct work_struct free_work;
} contexts; } contexts;
/* /*

View file

@ -1207,8 +1207,6 @@ void i915_gem_driver_remove(struct drm_i915_private *dev_priv)
void i915_gem_driver_release(struct drm_i915_private *dev_priv) void i915_gem_driver_release(struct drm_i915_private *dev_priv)
{ {
i915_gem_driver_release__contexts(dev_priv);
intel_gt_driver_release(&dev_priv->gt); intel_gt_driver_release(&dev_priv->gt);
intel_wa_list_free(&dev_priv->gt_wa_list); intel_wa_list_free(&dev_priv->gt_wa_list);

View file

@ -64,8 +64,6 @@ static void mock_device_release(struct drm_device *dev)
mock_device_flush(i915); mock_device_flush(i915);
intel_gt_driver_remove(&i915->gt); intel_gt_driver_remove(&i915->gt);
i915_gem_driver_release__contexts(i915);
i915_gem_drain_workqueue(i915); i915_gem_drain_workqueue(i915);
i915_gem_drain_freed_objects(i915); i915_gem_drain_freed_objects(i915);