Skip to content

Commit

Permalink
drm/i915: Move context management under GEM
Browse files Browse the repository at this point in the history
Keep track of the GEM contexts underneath i915->gem.contexts and assign
them their own lock for the purposes of list management.

v2: Focus on lock tracking; ctx->vm is protected by ctx->mutex
v3: Correct split with removal of logical HW ID

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191004134015.13204-15-chris@chris-wilson.co.uk
  • Loading branch information
ickle committed Oct 4, 2019
1 parent 2935ed5 commit a4e7ccd
Show file tree
Hide file tree
Showing 28 changed files with 394 additions and 354 deletions.
177 changes: 88 additions & 89 deletions drivers/gpu/drm/i915/gem/i915_gem_context.c

Large diffs are not rendered by default.

27 changes: 25 additions & 2 deletions drivers/gpu/drm/i915/gem/i915_gem_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@

#include "gt/intel_context.h"

#include "i915_drv.h"
#include "i915_gem.h"
#include "i915_gem_gtt.h"
#include "i915_scheduler.h"
#include "intel_device_info.h"

Expand Down Expand Up @@ -118,8 +120,8 @@ static inline bool i915_gem_context_is_kernel(struct i915_gem_context *ctx)
}

/* i915_gem_context.c */
int __must_check i915_gem_contexts_init(struct drm_i915_private *dev_priv);
void i915_gem_contexts_fini(struct drm_i915_private *dev_priv);
int __must_check 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 Expand Up @@ -158,6 +160,27 @@ static inline void i915_gem_context_put(struct i915_gem_context *ctx)
kref_put(&ctx->ref, i915_gem_context_release);
}

static inline struct i915_address_space *
i915_gem_context_vm(struct i915_gem_context *ctx)
{
return rcu_dereference_protected(ctx->vm, lockdep_is_held(&ctx->mutex));
}

static inline struct i915_address_space *
i915_gem_context_get_vm_rcu(struct i915_gem_context *ctx)
{
struct i915_address_space *vm;

rcu_read_lock();
vm = rcu_dereference(ctx->vm);
if (!vm)
vm = &ctx->i915->ggtt.vm;
vm = i915_vm_get(vm);
rcu_read_unlock();

return vm;
}

static inline struct i915_gem_engines *
i915_gem_context_engines(struct i915_gem_context *ctx)
{
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/gem/i915_gem_context_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ struct i915_gem_context {
* In other modes, this is a NULL pointer with the expectation that
* the caller uses the shared global GTT.
*/
struct i915_address_space *vm;
struct i915_address_space __rcu *vm;

/**
* @pid: process id of creator
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,7 @@ static int eb_select_context(struct i915_execbuffer *eb)
return -ENOENT;

eb->gem_context = ctx;
if (ctx->vm)
if (rcu_access_pointer(ctx->vm))
eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT;

eb->context_flags = 0;
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/i915/gem/i915_gem_userptr.c
Original file line number Diff line number Diff line change
Expand Up @@ -766,7 +766,8 @@ i915_gem_userptr_ioctl(struct drm_device *dev,
* On almost all of the older hw, we cannot tell the GPU that
* a page is readonly.
*/
vm = dev_priv->kernel_context->vm;
vm = rcu_dereference_protected(dev_priv->kernel_context->vm,
true); /* static vm */
if (!vm || !vm->has_read_only)
return -ENODEV;
}
Expand Down
36 changes: 24 additions & 12 deletions drivers/gpu/drm/i915/gem/selftests/huge_pages.c
Original file line number Diff line number Diff line change
Expand Up @@ -1322,15 +1322,15 @@ static int igt_ppgtt_pin_update(void *arg)
struct i915_gem_context *ctx = arg;
struct drm_i915_private *dev_priv = ctx->i915;
unsigned long supported = INTEL_INFO(dev_priv)->page_sizes;
struct i915_address_space *vm = ctx->vm;
struct drm_i915_gem_object *obj;
struct i915_gem_engines_iter it;
struct i915_address_space *vm;
struct intel_context *ce;
struct i915_vma *vma;
unsigned int flags = PIN_USER | PIN_OFFSET_FIXED;
unsigned int n;
int first, last;
int err;
int err = 0;

/*
* Make sure there's no funny business when doing a PIN_UPDATE -- in the
Expand All @@ -1340,9 +1340,10 @@ static int igt_ppgtt_pin_update(void *arg)
* huge-gtt-pages.
*/

if (!vm || !i915_vm_is_4lvl(vm)) {
vm = i915_gem_context_get_vm_rcu(ctx);
if (!i915_vm_is_4lvl(vm)) {
pr_info("48b PPGTT not supported, skipping\n");
return 0;
goto out_vm;
}

first = ilog2(I915_GTT_PAGE_SIZE_64K);
Expand Down Expand Up @@ -1451,6 +1452,8 @@ static int igt_ppgtt_pin_update(void *arg)
i915_vma_close(vma);
out_put:
i915_gem_object_put(obj);
out_vm:
i915_vm_put(vm);

return err;
}
Expand All @@ -1460,7 +1463,7 @@ static int igt_tmpfs_fallback(void *arg)
struct i915_gem_context *ctx = arg;
struct drm_i915_private *i915 = ctx->i915;
struct vfsmount *gemfs = i915->mm.gemfs;
struct i915_address_space *vm = ctx->vm ?: &i915->ggtt.vm;
struct i915_address_space *vm = i915_gem_context_get_vm_rcu(ctx);
struct drm_i915_gem_object *obj;
struct i915_vma *vma;
u32 *vaddr;
Expand Down Expand Up @@ -1510,21 +1513,22 @@ static int igt_tmpfs_fallback(void *arg)
out_restore:
i915->mm.gemfs = gemfs;

i915_vm_put(vm);
return err;
}

static int igt_shrink_thp(void *arg)
{
struct i915_gem_context *ctx = arg;
struct drm_i915_private *i915 = ctx->i915;
struct i915_address_space *vm = ctx->vm ?: &i915->ggtt.vm;
struct i915_address_space *vm = i915_gem_context_get_vm_rcu(ctx);
struct drm_i915_gem_object *obj;
struct i915_gem_engines_iter it;
struct intel_context *ce;
struct i915_vma *vma;
unsigned int flags = PIN_USER;
unsigned int n;
int err;
int err = 0;

/*
* Sanity check shrinking huge-paged object -- make sure nothing blows
Expand All @@ -1533,12 +1537,14 @@ static int igt_shrink_thp(void *arg)

if (!igt_can_allocate_thp(i915)) {
pr_info("missing THP support, skipping\n");
return 0;
goto out_vm;
}

obj = i915_gem_object_create_shmem(i915, SZ_2M);
if (IS_ERR(obj))
return PTR_ERR(obj);
if (IS_ERR(obj)) {
err = PTR_ERR(obj);
goto out_vm;
}

vma = i915_vma_instance(obj, vm, NULL);
if (IS_ERR(vma)) {
Expand Down Expand Up @@ -1607,6 +1613,8 @@ static int igt_shrink_thp(void *arg)
i915_vma_close(vma);
out_put:
i915_gem_object_put(obj);
out_vm:
i915_vm_put(vm);

return err;
}
Expand Down Expand Up @@ -1675,6 +1683,7 @@ int i915_gem_huge_page_live_selftests(struct drm_i915_private *i915)
};
struct drm_file *file;
struct i915_gem_context *ctx;
struct i915_address_space *vm;
intel_wakeref_t wakeref;
int err;

Expand All @@ -1699,8 +1708,11 @@ int i915_gem_huge_page_live_selftests(struct drm_i915_private *i915)
goto out_unlock;
}

if (ctx->vm)
ctx->vm->scrub_64K = true;
mutex_lock(&ctx->mutex);
vm = i915_gem_context_vm(ctx);
if (vm)
WRITE_ONCE(vm->scrub_64K, true);
mutex_unlock(&ctx->mutex);

err = i915_subtests(tests, ctx);

Expand Down
Loading

0 comments on commit a4e7ccd

Please sign in to comment.