Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 12c255b5 authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915: Provide an i915_active.acquire callback



If we introduce a callback for i915_active that is only called the first
time we use the i915_active and is symmetrically paired with the
i915_active.retire callback, we can replace the open-coded and
non-atomic implementations -- which will be very fragile (i.e. broken)
upon removing the struct_mutex serialisation.

Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarMatthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190621183801.23252-4-chris@chris-wilson.co.uk
parent a93615f9
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -923,8 +923,12 @@ static int context_barrier_task(struct i915_gem_context *ctx,
	if (!cb)
		return -ENOMEM;

	i915_active_init(i915, &cb->base, cb_retire);
	i915_active_acquire(&cb->base);
	i915_active_init(i915, &cb->base, NULL, cb_retire);
	err = i915_active_acquire(&cb->base);
	if (err) {
		kfree(cb);
		return err;
	}

	for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
		struct i915_request *rq;
+30 −35
Original line number Diff line number Diff line
@@ -95,11 +95,15 @@ void intel_context_unpin(struct intel_context *ce)
	intel_context_put(ce);
}

static int __context_pin_state(struct i915_vma *vma, unsigned long flags)
static int __context_pin_state(struct i915_vma *vma)
{
	u64 flags;
	int err;

	err = i915_vma_pin(vma, 0, 0, flags | PIN_GLOBAL);
	flags = i915_ggtt_pin_bias(vma) | PIN_OFFSET_BIAS;
	flags |= PIN_HIGH | PIN_GLOBAL;

	err = i915_vma_pin(vma, 0, 0, flags);
	if (err)
		return err;

@@ -119,7 +123,7 @@ static void __context_unpin_state(struct i915_vma *vma)
	__i915_vma_unpin(vma);
}

static void intel_context_retire(struct i915_active *active)
static void __intel_context_retire(struct i915_active *active)
{
	struct intel_context *ce = container_of(active, typeof(*ce), active);

@@ -130,35 +134,11 @@ static void intel_context_retire(struct i915_active *active)
	intel_context_put(ce);
}

void
intel_context_init(struct intel_context *ce,
		   struct i915_gem_context *ctx,
		   struct intel_engine_cs *engine)
{
	GEM_BUG_ON(!engine->cops);

	kref_init(&ce->ref);

	ce->gem_context = ctx;
	ce->engine = engine;
	ce->ops = engine->cops;
	ce->sseu = engine->sseu;

	INIT_LIST_HEAD(&ce->signal_link);
	INIT_LIST_HEAD(&ce->signals);

	mutex_init(&ce->pin_mutex);

	i915_active_init(ctx->i915, &ce->active, intel_context_retire);
}

int intel_context_active_acquire(struct intel_context *ce, unsigned long flags)
static int __intel_context_active(struct i915_active *active)
{
	struct intel_context *ce = container_of(active, typeof(*ce), active);
	int err;

	if (!i915_active_acquire(&ce->active))
		return 0;

	intel_context_get(ce);

	err = intel_ring_pin(ce->ring);
@@ -168,7 +148,7 @@ int intel_context_active_acquire(struct intel_context *ce, unsigned long flags)
	if (!ce->state)
		return 0;

	err = __context_pin_state(ce->state, flags);
	err = __context_pin_state(ce->state);
	if (err)
		goto err_ring;

@@ -188,15 +168,30 @@ int intel_context_active_acquire(struct intel_context *ce, unsigned long flags)
	intel_ring_unpin(ce->ring);
err_put:
	intel_context_put(ce);
	i915_active_cancel(&ce->active);
	return err;
}

void intel_context_active_release(struct intel_context *ce)
void
intel_context_init(struct intel_context *ce,
		   struct i915_gem_context *ctx,
		   struct intel_engine_cs *engine)
{
	/* Nodes preallocated in intel_context_active() */
	i915_active_acquire_barrier(&ce->active);
	i915_active_release(&ce->active);
	GEM_BUG_ON(!engine->cops);

	kref_init(&ce->ref);

	ce->gem_context = ctx;
	ce->engine = engine;
	ce->ops = engine->cops;
	ce->sseu = engine->sseu;

	INIT_LIST_HEAD(&ce->signal_link);
	INIT_LIST_HEAD(&ce->signals);

	mutex_init(&ce->pin_mutex);

	i915_active_init(ctx->i915, &ce->active,
			 __intel_context_active, __intel_context_retire);
}

static void i915_global_context_shrink(void)
+12 −2
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@

#include <linux/lockdep.h>

#include "i915_active.h"
#include "intel_context_types.h"
#include "intel_engine_types.h"

@@ -102,8 +103,17 @@ static inline void intel_context_exit(struct intel_context *ce)
		ce->ops->exit(ce);
}

int intel_context_active_acquire(struct intel_context *ce, unsigned long flags);
void intel_context_active_release(struct intel_context *ce);
static inline int intel_context_active_acquire(struct intel_context *ce)
{
	return i915_active_acquire(&ce->active);
}

static inline void intel_context_active_release(struct intel_context *ce)
{
	/* Nodes preallocated in intel_context_active() */
	i915_active_acquire_barrier(&ce->active);
	i915_active_release(&ce->active);
}

static inline struct intel_context *intel_context_get(struct intel_context *ce)
{
+2 −4
Original line number Diff line number Diff line
@@ -1542,12 +1542,10 @@ __execlists_context_pin(struct intel_context *ce,
		goto err;
	GEM_BUG_ON(!ce->state);

	ret = intel_context_active_acquire(ce,
					   engine->i915->ggtt.pin_bias |
					   PIN_OFFSET_BIAS |
					   PIN_HIGH);
	ret = intel_context_active_acquire(ce);
	if (ret)
		goto err;
	GEM_BUG_ON(!i915_vma_is_pinned(ce->state));

	vaddr = i915_gem_object_pin_map(ce->state->obj,
					i915_coherent_map_type(engine->i915) |
+1 −1
Original line number Diff line number Diff line
@@ -1455,7 +1455,7 @@ static int ring_context_pin(struct intel_context *ce)
		ce->state = vma;
	}

	err = intel_context_active_acquire(ce, PIN_HIGH);
	err = intel_context_active_acquire(ce);
	if (err)
		return err;

Loading