Skip to content

Commit

Permalink
drm/i915/gem: Drop free_work for GEM contexts
Browse files Browse the repository at this point in the history
The free_list and worker was introduced in commit 5f09a9c ("drm/i915:
Allow contexts to be unreferenced locklessly"), but subsequently made
redundant by the removal of the last sleeping lock in commit 2935ed5
("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
  • Loading branch information
ickle committed Dec 16, 2020
1 parent 5f22cc0 commit f8246cf
Show file tree
Hide file tree
Showing 6 changed files with 8 additions and 60 deletions.
59 changes: 8 additions & 51 deletions drivers/gpu/drm/i915/gem/i915_gem_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -334,13 +334,12 @@ static struct i915_gem_engines *default_engines(struct i915_gem_context *ctx)
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);
list_del(&ctx->link);
spin_unlock(&ctx->i915->gem.contexts.lock);
trace_i915_context_free(ctx);
GEM_BUG_ON(!i915_gem_context_is_closed(ctx));

mutex_destroy(&ctx->engines_mutex);
mutex_destroy(&ctx->lut_mutex);
Expand All @@ -354,37 +353,6 @@ static void i915_gem_context_free(struct i915_gem_context *ctx)
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 *
__context_engines_static(const struct i915_gem_context *ctx)
{
Expand Down Expand Up @@ -633,6 +601,10 @@ static void context_close(struct i915_gem_context *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);

/*
Expand Down Expand Up @@ -850,9 +822,6 @@ i915_gem_create_context(struct drm_i915_private *i915, unsigned int flags)
!HAS_EXECLISTS(i915))
return ERR_PTR(-EINVAL);

/* Reap the stale contexts */
contexts_flush_free(&i915->gem.contexts);

ctx = __create_context(i915);
if (IS_ERR(ctx))
return ctx;
Expand Down Expand Up @@ -897,22 +866,13 @@ static void init_contexts(struct i915_gem_contexts *gc)
{
spin_lock_init(&gc->lock);
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)
{
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,
struct drm_i915_file_private *fpriv,
u32 *id)
Expand Down Expand Up @@ -986,7 +946,6 @@ int i915_gem_context_open(struct drm_i915_private *i915,
void i915_gem_context_close(struct drm_file *file)
{
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_gem_context *ctx;
unsigned long idx;
Expand All @@ -998,8 +957,6 @@ void i915_gem_context_close(struct drm_file *file)
xa_for_each(&file_priv->vm_xa, idx, vm)
i915_vm_put(vm);
xa_destroy(&file_priv->vm_xa);

contexts_flush_free(&i915->gem.contexts);
}

int i915_gem_vm_create_ioctl(struct drm_device *dev, void *data,
Expand Down
1 change: 0 additions & 1 deletion drivers/gpu/drm/i915/gem/i915_gem_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ i915_gem_context_clear_user_engines(struct i915_gem_context *ctx)

/* i915_gem_context.c */
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,
struct drm_file *file);
Expand Down
1 change: 0 additions & 1 deletion drivers/gpu/drm/i915/gem/i915_gem_context_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ struct i915_gem_context {

/** link: place with &drm_i915_private.context_list */
struct list_head link;
struct llist_node free_link;

/**
* @ref: reference count
Expand Down
3 changes: 0 additions & 3 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1172,9 +1172,6 @@ struct drm_i915_private {
struct i915_gem_contexts {
spinlock_t lock; /* locks list */
struct list_head list;

struct llist_head free_list;
struct work_struct free_work;
} contexts;

/*
Expand Down
2 changes: 0 additions & 2 deletions drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
i915_gem_driver_release__contexts(dev_priv);

intel_gt_driver_release(&dev_priv->gt);

intel_wa_list_free(&dev_priv->gt_wa_list);
Expand Down
2 changes: 0 additions & 2 deletions drivers/gpu/drm/i915/selftests/mock_gem_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@ static void mock_device_release(struct drm_device *dev)
mock_device_flush(i915);
intel_gt_driver_remove(&i915->gt);

i915_gem_driver_release__contexts(i915);

i915_gem_drain_workqueue(i915);
i915_gem_drain_freed_objects(i915);

Expand Down

0 comments on commit f8246cf

Please sign in to comment.