Commit f8246cf4 authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915/gem: Drop free_work for GEM contexts



The free_list and worker was introduced in commit 5f09a9c8 ("drm/i915:
Allow contexts to be unreferenced locklessly"), but subsequently made
redundant by the removal of the last sleeping lock in commit 2935ed53
("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: default avatarMika Kuoppala <mika.kuoppala@linux.intel.com>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: default avatarMatthew Brost <matthew.brost@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201215152138.8158-1-chris@chris-wilson.co.uk
parent 5f22cc0b
Loading
Loading
Loading
Loading
+8 −51
Original line number Diff line number Diff line
@@ -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);
@@ -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)
{
@@ -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);

	/*
@@ -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;
@@ -897,9 +866,6 @@ 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)
@@ -907,12 +873,6 @@ 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)
@@ -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;
@@ -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,
+0 −1
Original line number Diff line number Diff line
@@ -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);
+0 −1
Original line number Diff line number Diff line
@@ -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
+0 −3
Original line number Diff line number Diff line
@@ -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;

		/*
+0 −2
Original line number Diff line number Diff line
@@ -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);
Loading