Skip to content

Commit a4e7ccd

Browse files
committed
drm/i915: Move context management under GEM
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 <[email protected]> Cc: Tvrtko Ursulin <[email protected]> Reviewed-by: Tvrtko Ursulin <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 2935ed5 commit a4e7ccd

28 files changed

+394
-354
lines changed

drivers/gpu/drm/i915/gem/i915_gem_context.c

Lines changed: 88 additions & 89 deletions
Large diffs are not rendered by default.

drivers/gpu/drm/i915/gem/i915_gem_context.h

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111

1212
#include "gt/intel_context.h"
1313

14+
#include "i915_drv.h"
1415
#include "i915_gem.h"
16+
#include "i915_gem_gtt.h"
1517
#include "i915_scheduler.h"
1618
#include "intel_device_info.h"
1719

@@ -118,8 +120,8 @@ static inline bool i915_gem_context_is_kernel(struct i915_gem_context *ctx)
118120
}
119121

120122
/* i915_gem_context.c */
121-
int __must_check i915_gem_contexts_init(struct drm_i915_private *dev_priv);
122-
void i915_gem_contexts_fini(struct drm_i915_private *dev_priv);
123+
int __must_check i915_gem_init_contexts(struct drm_i915_private *i915);
124+
void i915_gem_driver_release__contexts(struct drm_i915_private *i915);
123125

124126
int i915_gem_context_open(struct drm_i915_private *i915,
125127
struct drm_file *file);
@@ -158,6 +160,27 @@ static inline void i915_gem_context_put(struct i915_gem_context *ctx)
158160
kref_put(&ctx->ref, i915_gem_context_release);
159161
}
160162

163+
static inline struct i915_address_space *
164+
i915_gem_context_vm(struct i915_gem_context *ctx)
165+
{
166+
return rcu_dereference_protected(ctx->vm, lockdep_is_held(&ctx->mutex));
167+
}
168+
169+
static inline struct i915_address_space *
170+
i915_gem_context_get_vm_rcu(struct i915_gem_context *ctx)
171+
{
172+
struct i915_address_space *vm;
173+
174+
rcu_read_lock();
175+
vm = rcu_dereference(ctx->vm);
176+
if (!vm)
177+
vm = &ctx->i915->ggtt.vm;
178+
vm = i915_vm_get(vm);
179+
rcu_read_unlock();
180+
181+
return vm;
182+
}
183+
161184
static inline struct i915_gem_engines *
162185
i915_gem_context_engines(struct i915_gem_context *ctx)
163186
{

drivers/gpu/drm/i915/gem/i915_gem_context_types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ struct i915_gem_context {
8888
* In other modes, this is a NULL pointer with the expectation that
8989
* the caller uses the shared global GTT.
9090
*/
91-
struct i915_address_space *vm;
91+
struct i915_address_space __rcu *vm;
9292

9393
/**
9494
* @pid: process id of creator

drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,7 @@ static int eb_select_context(struct i915_execbuffer *eb)
728728
return -ENOENT;
729729

730730
eb->gem_context = ctx;
731-
if (ctx->vm)
731+
if (rcu_access_pointer(ctx->vm))
732732
eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
733733

734734
eb->context_flags = 0;

drivers/gpu/drm/i915/gem/i915_gem_userptr.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,8 @@ i915_gem_userptr_ioctl(struct drm_device *dev,
766766
* On almost all of the older hw, we cannot tell the GPU that
767767
* a page is readonly.
768768
*/
769-
vm = dev_priv->kernel_context->vm;
769+
vm = rcu_dereference_protected(dev_priv->kernel_context->vm,
770+
true); /* static vm */
770771
if (!vm || !vm->has_read_only)
771772
return -ENODEV;
772773
}

drivers/gpu/drm/i915/gem/selftests/huge_pages.c

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,15 +1322,15 @@ static int igt_ppgtt_pin_update(void *arg)
13221322
struct i915_gem_context *ctx = arg;
13231323
struct drm_i915_private *dev_priv = ctx->i915;
13241324
unsigned long supported = INTEL_INFO(dev_priv)->page_sizes;
1325-
struct i915_address_space *vm = ctx->vm;
13261325
struct drm_i915_gem_object *obj;
13271326
struct i915_gem_engines_iter it;
1327+
struct i915_address_space *vm;
13281328
struct intel_context *ce;
13291329
struct i915_vma *vma;
13301330
unsigned int flags = PIN_USER | PIN_OFFSET_FIXED;
13311331
unsigned int n;
13321332
int first, last;
1333-
int err;
1333+
int err = 0;
13341334

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

1343-
if (!vm || !i915_vm_is_4lvl(vm)) {
1343+
vm = i915_gem_context_get_vm_rcu(ctx);
1344+
if (!i915_vm_is_4lvl(vm)) {
13441345
pr_info("48b PPGTT not supported, skipping\n");
1345-
return 0;
1346+
goto out_vm;
13461347
}
13471348

13481349
first = ilog2(I915_GTT_PAGE_SIZE_64K);
@@ -1451,6 +1452,8 @@ static int igt_ppgtt_pin_update(void *arg)
14511452
i915_vma_close(vma);
14521453
out_put:
14531454
i915_gem_object_put(obj);
1455+
out_vm:
1456+
i915_vm_put(vm);
14541457

14551458
return err;
14561459
}
@@ -1460,7 +1463,7 @@ static int igt_tmpfs_fallback(void *arg)
14601463
struct i915_gem_context *ctx = arg;
14611464
struct drm_i915_private *i915 = ctx->i915;
14621465
struct vfsmount *gemfs = i915->mm.gemfs;
1463-
struct i915_address_space *vm = ctx->vm ?: &i915->ggtt.vm;
1466+
struct i915_address_space *vm = i915_gem_context_get_vm_rcu(ctx);
14641467
struct drm_i915_gem_object *obj;
14651468
struct i915_vma *vma;
14661469
u32 *vaddr;
@@ -1510,21 +1513,22 @@ static int igt_tmpfs_fallback(void *arg)
15101513
out_restore:
15111514
i915->mm.gemfs = gemfs;
15121515

1516+
i915_vm_put(vm);
15131517
return err;
15141518
}
15151519

15161520
static int igt_shrink_thp(void *arg)
15171521
{
15181522
struct i915_gem_context *ctx = arg;
15191523
struct drm_i915_private *i915 = ctx->i915;
1520-
struct i915_address_space *vm = ctx->vm ?: &i915->ggtt.vm;
1524+
struct i915_address_space *vm = i915_gem_context_get_vm_rcu(ctx);
15211525
struct drm_i915_gem_object *obj;
15221526
struct i915_gem_engines_iter it;
15231527
struct intel_context *ce;
15241528
struct i915_vma *vma;
15251529
unsigned int flags = PIN_USER;
15261530
unsigned int n;
1527-
int err;
1531+
int err = 0;
15281532

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

15341538
if (!igt_can_allocate_thp(i915)) {
15351539
pr_info("missing THP support, skipping\n");
1536-
return 0;
1540+
goto out_vm;
15371541
}
15381542

15391543
obj = i915_gem_object_create_shmem(i915, SZ_2M);
1540-
if (IS_ERR(obj))
1541-
return PTR_ERR(obj);
1544+
if (IS_ERR(obj)) {
1545+
err = PTR_ERR(obj);
1546+
goto out_vm;
1547+
}
15421548

15431549
vma = i915_vma_instance(obj, vm, NULL);
15441550
if (IS_ERR(vma)) {
@@ -1607,6 +1613,8 @@ static int igt_shrink_thp(void *arg)
16071613
i915_vma_close(vma);
16081614
out_put:
16091615
i915_gem_object_put(obj);
1616+
out_vm:
1617+
i915_vm_put(vm);
16101618

16111619
return err;
16121620
}
@@ -1675,6 +1683,7 @@ int i915_gem_huge_page_live_selftests(struct drm_i915_private *i915)
16751683
};
16761684
struct drm_file *file;
16771685
struct i915_gem_context *ctx;
1686+
struct i915_address_space *vm;
16781687
intel_wakeref_t wakeref;
16791688
int err;
16801689

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

1702-
if (ctx->vm)
1703-
ctx->vm->scrub_64K = true;
1711+
mutex_lock(&ctx->mutex);
1712+
vm = i915_gem_context_vm(ctx);
1713+
if (vm)
1714+
WRITE_ONCE(vm->scrub_64K, true);
1715+
mutex_unlock(&ctx->mutex);
17041716

17051717
err = i915_subtests(tests, ctx);
17061718

0 commit comments

Comments
 (0)