Skip to content

Commit

Permalink
drm/i915: Remove i915->kernel_context
Browse files Browse the repository at this point in the history
Allocate only an internal intel_context for the kernel_context, forgoing
a global GEM context for internal use as we only require a separate
address space (for our own protection).

Now having weaned GT from requiring ce->gem_context, we can stop
referencing it entirely. This also means we no longer have to create random
and unnecessary GEM contexts for internal use.

GEM contexts are now entirely for tracking GEM clients, and intel_context
the execution environment on the GPU.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Andi Shyti <andi.shyti@intel.com>
Acked-by: Andi Shyti <andi.shyti@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191221160324.1073045-1-chris@chris-wilson.co.uk
  • Loading branch information
Chris Wilson committed Dec 21, 2019
1 parent ed7dd73 commit e6ba764
Show file tree
Hide file tree
Showing 34 changed files with 388 additions and 507 deletions.
97 changes: 43 additions & 54 deletions drivers/gpu/drm/i915/gem/i915_gem_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,35 @@ context_get_vm_rcu(struct i915_gem_context *ctx)
} while (1);
}

static void intel_context_set_gem(struct intel_context *ce,
struct i915_gem_context *ctx)
{
GEM_BUG_ON(ce->gem_context);
ce->gem_context = ctx;

if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags))
ce->ring = __intel_context_ring_size(SZ_16K);

if (rcu_access_pointer(ctx->vm)) {
struct i915_address_space *vm;

rcu_read_lock();
vm = context_get_vm_rcu(ctx); /* hmm */
rcu_read_unlock();

i915_vm_put(ce->vm);
ce->vm = vm;
}

GEM_BUG_ON(ce->timeline);
if (ctx->timeline)
ce->timeline = intel_timeline_get(ctx->timeline);

if (ctx->sched.priority >= I915_PRIORITY_NORMAL &&
intel_engine_has_semaphores(ce->engine))
__set_bit(CONTEXT_USE_SEMAPHORES, &ce->flags);
}

static void __free_engines(struct i915_gem_engines *e, unsigned int count)
{
while (count--) {
Expand Down Expand Up @@ -251,12 +280,14 @@ static struct i915_gem_engines *default_engines(struct i915_gem_context *ctx)
GEM_BUG_ON(engine->legacy_idx >= I915_NUM_ENGINES);
GEM_BUG_ON(e->engines[engine->legacy_idx]);

ce = intel_context_create(ctx, engine);
ce = intel_context_create(engine);
if (IS_ERR(ce)) {
__free_engines(e, e->num_engines + 1);
return ERR_CAST(ce);
}

intel_context_set_gem(ce, ctx);

e->engines[engine->legacy_idx] = ce;
e->num_engines = max(e->num_engines, engine->legacy_idx);
}
Expand Down Expand Up @@ -706,37 +737,6 @@ i915_gem_create_context(struct drm_i915_private *i915, unsigned int flags)
return ctx;
}

static void
destroy_kernel_context(struct i915_gem_context **ctxp)
{
struct i915_gem_context *ctx;

/* Keep the context ref so that we can free it immediately ourselves */
ctx = i915_gem_context_get(fetch_and_zero(ctxp));
GEM_BUG_ON(!i915_gem_context_is_kernel(ctx));

context_close(ctx);
i915_gem_context_free(ctx);
}

struct i915_gem_context *
i915_gem_context_create_kernel(struct drm_i915_private *i915, int prio)
{
struct i915_gem_context *ctx;

ctx = i915_gem_create_context(i915, 0);
if (IS_ERR(ctx))
return ctx;

i915_gem_context_clear_bannable(ctx);
i915_gem_context_set_persistence(ctx);
ctx->sched.priority = I915_USER_PRIORITY(prio);

GEM_BUG_ON(!i915_gem_context_is_kernel(ctx));

return ctx;
}

static void init_contexts(struct i915_gem_contexts *gc)
{
spin_lock_init(&gc->lock);
Expand All @@ -746,32 +746,16 @@ static void init_contexts(struct i915_gem_contexts *gc)
init_llist_head(&gc->free_list);
}

int i915_gem_init_contexts(struct drm_i915_private *i915)
void i915_gem_init__contexts(struct drm_i915_private *i915)
{
struct i915_gem_context *ctx;

/* Reassure ourselves we are only called once */
GEM_BUG_ON(i915->kernel_context);

init_contexts(&i915->gem.contexts);

/* lowest priority; idle task */
ctx = i915_gem_context_create_kernel(i915, I915_PRIORITY_MIN);
if (IS_ERR(ctx)) {
DRM_ERROR("Failed to create default global context\n");
return PTR_ERR(ctx);
}
i915->kernel_context = ctx;

DRM_DEBUG_DRIVER("%s context support initialized\n",
DRIVER_CAPS(i915)->has_logical_contexts ?
"logical" : "fake");
return 0;
}

void i915_gem_driver_release__contexts(struct drm_i915_private *i915)
{
destroy_kernel_context(&i915->kernel_context);
flush_work(&i915->gem.contexts.free_work);
}

Expand Down Expand Up @@ -840,7 +824,6 @@ int i915_gem_context_open(struct drm_i915_private *i915,
if (err < 0)
goto err_ctx;

GEM_BUG_ON(i915_gem_context_is_kernel(ctx));
GEM_BUG_ON(err > 0);

return 0;
Expand Down Expand Up @@ -1531,12 +1514,14 @@ set_engines__load_balance(struct i915_user_extension __user *base, void *data)
}
}

ce = intel_execlists_create_virtual(set->ctx, siblings, n);
ce = intel_execlists_create_virtual(siblings, n);
if (IS_ERR(ce)) {
err = PTR_ERR(ce);
goto out_siblings;
}

intel_context_set_gem(ce, set->ctx);

if (cmpxchg(&set->engines->engines[idx], NULL, ce)) {
intel_context_put(ce);
err = -EEXIST;
Expand Down Expand Up @@ -1706,12 +1691,14 @@ set_engines(struct i915_gem_context *ctx,
return -ENOENT;
}

ce = intel_context_create(ctx, engine);
ce = intel_context_create(engine);
if (IS_ERR(ce)) {
__free_engines(set.engines, n);
return PTR_ERR(ce);
}

intel_context_set_gem(ce, ctx);

set.engines->engines[n] = ce;
}
set.engines->num_engines = num_engines;
Expand Down Expand Up @@ -2016,13 +2003,15 @@ static int clone_engines(struct i915_gem_context *dst,
*/
if (intel_engine_is_virtual(engine))
clone->engines[n] =
intel_execlists_clone_virtual(dst, engine);
intel_execlists_clone_virtual(engine);
else
clone->engines[n] = intel_context_create(dst, engine);
clone->engines[n] = intel_context_create(engine);
if (IS_ERR_OR_NULL(clone->engines[n])) {
__free_engines(clone, n);
goto err_unlock;
}

intel_context_set_gem(clone->engines[n], dst);
}
clone->num_engines = n;

Expand Down
10 changes: 1 addition & 9 deletions drivers/gpu/drm/i915/gem/i915_gem_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,8 @@ i915_gem_context_clear_user_engines(struct i915_gem_context *ctx)
clear_bit(CONTEXT_USER_ENGINES, &ctx->flags);
}

static inline bool i915_gem_context_is_kernel(struct i915_gem_context *ctx)
{
return !ctx->file_priv;
}

/* i915_gem_context.c */
int __must_check 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,
Expand All @@ -140,9 +135,6 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
int i915_gem_context_reset_stats_ioctl(struct drm_device *dev, void *data,
struct drm_file *file);

struct i915_gem_context *
i915_gem_context_create_kernel(struct drm_i915_private *i915, int prio);

static inline struct i915_gem_context *
i915_gem_context_get(struct i915_gem_context *ctx)
{
Expand Down
6 changes: 1 addition & 5 deletions drivers/gpu/drm/i915/gem/i915_gem_userptr.c
Original file line number Diff line number Diff line change
Expand Up @@ -779,15 +779,11 @@ i915_gem_userptr_ioctl(struct drm_device *dev,
return -EFAULT;

if (args->flags & I915_USERPTR_READ_ONLY) {
struct i915_address_space *vm;

/*
* On almost all of the older hw, we cannot tell the GPU that
* a page is readonly.
*/
vm = rcu_dereference_protected(dev_priv->kernel_context->vm,
true); /* static vm */
if (!vm || !vm->has_read_only)
if (!dev_priv->gt.vm->has_read_only)
return -ENODEV;
}

Expand Down
5 changes: 2 additions & 3 deletions drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ static int live_parallel_switch(void *arg)
if (!data[m].ce[0])
continue;

ce = intel_context_create(ctx, data[m].ce[0]->engine);
ce = intel_context_create(data[m].ce[0]->engine);
if (IS_ERR(ce))
goto out;

Expand Down Expand Up @@ -1264,8 +1264,7 @@ __igt_ctx_sseu(struct drm_i915_private *i915,
hweight32(engine->sseu.slice_mask),
hweight32(pg_sseu.slice_mask));

ce = intel_context_create(engine->kernel_context->gem_context,
engine);
ce = intel_context_create(engine);
if (IS_ERR(ce)) {
ret = PTR_ERR(ce);
goto out_put;
Expand Down
11 changes: 10 additions & 1 deletion drivers/gpu/drm/i915/gem/selftests/mock_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,16 @@ live_context(struct drm_i915_private *i915, struct file *file)
struct i915_gem_context *
kernel_context(struct drm_i915_private *i915)
{
return i915_gem_context_create_kernel(i915, I915_PRIORITY_NORMAL);
struct i915_gem_context *ctx;

ctx = i915_gem_create_context(i915, 0);
if (IS_ERR(ctx))
return ctx;

i915_gem_context_clear_bannable(ctx);
i915_gem_context_set_persistence(ctx);

return ctx;
}

void kernel_context_close(struct i915_gem_context *ctx)
Expand Down
32 changes: 7 additions & 25 deletions drivers/gpu/drm/i915/gt/intel_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,15 @@ void intel_context_free(struct intel_context *ce)
}

struct intel_context *
intel_context_create(struct i915_gem_context *ctx,
struct intel_engine_cs *engine)
intel_context_create(struct intel_engine_cs *engine)
{
struct intel_context *ce;

ce = intel_context_alloc();
if (!ce)
return ERR_PTR(-ENOMEM);

intel_context_init(ce, ctx, engine);
intel_context_init(ce, engine);
return ce;
}

Expand Down Expand Up @@ -71,8 +70,6 @@ int __intel_context_do_pin(struct intel_context *ce)
CE_TRACE(ce, "pin ring:{head:%04x, tail:%04x}\n",
ce->ring->head, ce->ring->tail);

i915_gem_context_get(ce->gem_context); /* for ctx->ppgtt */

smp_mb__before_atomic(); /* flush pin before it is visible */
}

Expand Down Expand Up @@ -101,7 +98,6 @@ void intel_context_unpin(struct intel_context *ce)

ce->ops->unpin(ce);

i915_gem_context_put(ce->gem_context);
intel_context_active_release(ce);
}

Expand Down Expand Up @@ -193,7 +189,7 @@ int intel_context_active_acquire(struct intel_context *ce)
return err;

/* Preallocate tracking nodes */
if (!i915_gem_context_is_kernel(ce->gem_context)) {
if (!intel_context_is_barrier(ce)) {
err = i915_active_acquire_preallocate_barrier(&ce->active,
ce->engine);
if (err) {
Expand All @@ -214,33 +210,19 @@ 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)
{
struct i915_address_space *vm;

GEM_BUG_ON(!engine->cops);
GEM_BUG_ON(!engine->gt->vm);

kref_init(&ce->ref);

ce->gem_context = ctx;
rcu_read_lock();
vm = rcu_dereference(ctx->vm);
if (vm)
ce->vm = i915_vm_get(vm);
else
ce->vm = i915_vm_get(&engine->gt->ggtt->vm);
rcu_read_unlock();
if (ctx->timeline)
ce->timeline = intel_timeline_get(ctx->timeline);
if (ctx->sched.priority >= I915_PRIORITY_NORMAL &&
intel_engine_has_semaphores(engine))
__set_bit(CONTEXT_USE_SEMAPHORES, &ce->flags);

ce->engine = engine;
ce->ops = engine->cops;
ce->sseu = engine->sseu;
ce->ring = __intel_context_ring_size(SZ_16K);
ce->ring = __intel_context_ring_size(SZ_4K);

ce->vm = i915_vm_get(engine->gt->vm);

INIT_LIST_HEAD(&ce->signal_link);
INIT_LIST_HEAD(&ce->signals);
Expand Down
9 changes: 6 additions & 3 deletions drivers/gpu/drm/i915/gt/intel_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,11 @@
} while (0)

void intel_context_init(struct intel_context *ce,
struct i915_gem_context *ctx,
struct intel_engine_cs *engine);
void intel_context_fini(struct intel_context *ce);

struct intel_context *
intel_context_create(struct i915_gem_context *ctx,
struct intel_engine_cs *engine);
intel_context_create(struct intel_engine_cs *engine);

void intel_context_free(struct intel_context *ce);

Expand Down Expand Up @@ -162,6 +160,11 @@ static inline struct intel_ring *__intel_context_ring_size(u64 sz)
return u64_to_ptr(struct intel_ring, sz);
}

static inline bool intel_context_is_barrier(const struct intel_context *ce)
{
return test_bit(CONTEXT_BARRIER_BIT, &ce->flags);
}

static inline bool intel_context_use_semaphores(const struct intel_context *ce)
{
return test_bit(CONTEXT_USE_SEMAPHORES, &ce->flags);
Expand Down
13 changes: 7 additions & 6 deletions drivers/gpu/drm/i915/gt/intel_context_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,13 @@ struct intel_context {
struct intel_timeline *timeline;

unsigned long flags;
#define CONTEXT_ALLOC_BIT 0
#define CONTEXT_VALID_BIT 1
#define CONTEXT_USE_SEMAPHORES 2
#define CONTEXT_BANNED 3
#define CONTEXT_FORCE_SINGLE_SUBMISSION 4
#define CONTEXT_NOPREEMPT 5
#define CONTEXT_BARRIER_BIT 0
#define CONTEXT_ALLOC_BIT 1
#define CONTEXT_VALID_BIT 2
#define CONTEXT_USE_SEMAPHORES 3
#define CONTEXT_BANNED 4
#define CONTEXT_FORCE_SINGLE_SUBMISSION 5
#define CONTEXT_NOPREEMPT 6

u32 *lrc_reg_state;
u64 lrc_desc;
Expand Down
Loading

0 comments on commit e6ba764

Please sign in to comment.