mirror of
https://github.com/torvalds/linux.git
synced 2026-05-04 14:32:27 -04:00
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 <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
This commit is contained in:
@@ -221,12 +221,20 @@ 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);
|
||||
|
||||
kref_init(&ce->ref);
|
||||
|
||||
ce->gem_context = ctx;
|
||||
ce->vm = i915_vm_get(ctx->vm ?: &engine->gt->ggtt->vm);
|
||||
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);
|
||||
|
||||
|
||||
@@ -155,13 +155,9 @@ static int live_context_size(void *arg)
|
||||
* HW tries to write past the end of one.
|
||||
*/
|
||||
|
||||
mutex_lock(>->i915->drm.struct_mutex);
|
||||
|
||||
fixme = kernel_context(gt->i915);
|
||||
if (IS_ERR(fixme)) {
|
||||
err = PTR_ERR(fixme);
|
||||
goto unlock;
|
||||
}
|
||||
if (IS_ERR(fixme))
|
||||
return PTR_ERR(fixme);
|
||||
|
||||
for_each_engine(engine, gt->i915, id) {
|
||||
struct {
|
||||
@@ -201,8 +197,6 @@ static int live_context_size(void *arg)
|
||||
}
|
||||
|
||||
kernel_context_close(fixme);
|
||||
unlock:
|
||||
mutex_unlock(>->i915->drm.struct_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -305,12 +299,10 @@ static int live_active_context(void *arg)
|
||||
if (IS_ERR(file))
|
||||
return PTR_ERR(file);
|
||||
|
||||
mutex_lock(>->i915->drm.struct_mutex);
|
||||
|
||||
fixme = live_context(gt->i915, file);
|
||||
if (IS_ERR(fixme)) {
|
||||
err = PTR_ERR(fixme);
|
||||
goto unlock;
|
||||
goto out_file;
|
||||
}
|
||||
|
||||
for_each_engine(engine, gt->i915, id) {
|
||||
@@ -323,8 +315,7 @@ static int live_active_context(void *arg)
|
||||
break;
|
||||
}
|
||||
|
||||
unlock:
|
||||
mutex_unlock(>->i915->drm.struct_mutex);
|
||||
out_file:
|
||||
mock_file_free(gt->i915, file);
|
||||
return err;
|
||||
}
|
||||
@@ -418,12 +409,10 @@ static int live_remote_context(void *arg)
|
||||
if (IS_ERR(file))
|
||||
return PTR_ERR(file);
|
||||
|
||||
mutex_lock(>->i915->drm.struct_mutex);
|
||||
|
||||
fixme = live_context(gt->i915, file);
|
||||
if (IS_ERR(fixme)) {
|
||||
err = PTR_ERR(fixme);
|
||||
goto unlock;
|
||||
goto out_file;
|
||||
}
|
||||
|
||||
for_each_engine(engine, gt->i915, id) {
|
||||
@@ -436,8 +425,7 @@ static int live_remote_context(void *arg)
|
||||
break;
|
||||
}
|
||||
|
||||
unlock:
|
||||
mutex_unlock(>->i915->drm.struct_mutex);
|
||||
out_file:
|
||||
mock_file_free(gt->i915, file);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -58,9 +58,7 @@ static int hang_init(struct hang *h, struct intel_gt *gt)
|
||||
memset(h, 0, sizeof(*h));
|
||||
h->gt = gt;
|
||||
|
||||
mutex_lock(>->i915->drm.struct_mutex);
|
||||
h->ctx = kernel_context(gt->i915);
|
||||
mutex_unlock(>->i915->drm.struct_mutex);
|
||||
if (IS_ERR(h->ctx))
|
||||
return PTR_ERR(h->ctx);
|
||||
|
||||
@@ -133,7 +131,7 @@ static struct i915_request *
|
||||
hang_create_request(struct hang *h, struct intel_engine_cs *engine)
|
||||
{
|
||||
struct intel_gt *gt = h->gt;
|
||||
struct i915_address_space *vm = h->ctx->vm ?: &engine->gt->ggtt->vm;
|
||||
struct i915_address_space *vm = i915_gem_context_get_vm_rcu(h->ctx);
|
||||
struct drm_i915_gem_object *obj;
|
||||
struct i915_request *rq = NULL;
|
||||
struct i915_vma *hws, *vma;
|
||||
@@ -143,12 +141,15 @@ hang_create_request(struct hang *h, struct intel_engine_cs *engine)
|
||||
int err;
|
||||
|
||||
obj = i915_gem_object_create_internal(gt->i915, PAGE_SIZE);
|
||||
if (IS_ERR(obj))
|
||||
if (IS_ERR(obj)) {
|
||||
i915_vm_put(vm);
|
||||
return ERR_CAST(obj);
|
||||
}
|
||||
|
||||
vaddr = i915_gem_object_pin_map(obj, i915_coherent_map_type(gt->i915));
|
||||
if (IS_ERR(vaddr)) {
|
||||
i915_gem_object_put(obj);
|
||||
i915_vm_put(vm);
|
||||
return ERR_CAST(vaddr);
|
||||
}
|
||||
|
||||
@@ -159,16 +160,22 @@ hang_create_request(struct hang *h, struct intel_engine_cs *engine)
|
||||
h->batch = vaddr;
|
||||
|
||||
vma = i915_vma_instance(h->obj, vm, NULL);
|
||||
if (IS_ERR(vma))
|
||||
if (IS_ERR(vma)) {
|
||||
i915_vm_put(vm);
|
||||
return ERR_CAST(vma);
|
||||
}
|
||||
|
||||
hws = i915_vma_instance(h->hws, vm, NULL);
|
||||
if (IS_ERR(hws))
|
||||
if (IS_ERR(hws)) {
|
||||
i915_vm_put(vm);
|
||||
return ERR_CAST(hws);
|
||||
}
|
||||
|
||||
err = i915_vma_pin(vma, 0, 0, PIN_USER);
|
||||
if (err)
|
||||
if (err) {
|
||||
i915_vm_put(vm);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
err = i915_vma_pin(hws, 0, 0, PIN_USER);
|
||||
if (err)
|
||||
@@ -266,6 +273,7 @@ unpin_hws:
|
||||
i915_vma_unpin(hws);
|
||||
unpin_vma:
|
||||
i915_vma_unpin(vma);
|
||||
i915_vm_put(vm);
|
||||
return err ? ERR_PTR(err) : rq;
|
||||
}
|
||||
|
||||
@@ -382,9 +390,7 @@ static int igt_reset_nop(void *arg)
|
||||
if (IS_ERR(file))
|
||||
return PTR_ERR(file);
|
||||
|
||||
mutex_lock(>->i915->drm.struct_mutex);
|
||||
ctx = live_context(gt->i915, file);
|
||||
mutex_unlock(>->i915->drm.struct_mutex);
|
||||
if (IS_ERR(ctx)) {
|
||||
err = PTR_ERR(ctx);
|
||||
goto out;
|
||||
@@ -458,9 +464,7 @@ static int igt_reset_nop_engine(void *arg)
|
||||
if (IS_ERR(file))
|
||||
return PTR_ERR(file);
|
||||
|
||||
mutex_lock(>->i915->drm.struct_mutex);
|
||||
ctx = live_context(gt->i915, file);
|
||||
mutex_unlock(>->i915->drm.struct_mutex);
|
||||
if (IS_ERR(ctx)) {
|
||||
err = PTR_ERR(ctx);
|
||||
goto out;
|
||||
@@ -705,9 +709,7 @@ static int active_engine(void *data)
|
||||
return PTR_ERR(file);
|
||||
|
||||
for (count = 0; count < ARRAY_SIZE(ctx); count++) {
|
||||
mutex_lock(&engine->i915->drm.struct_mutex);
|
||||
ctx[count] = live_context(engine->i915, file);
|
||||
mutex_unlock(&engine->i915->drm.struct_mutex);
|
||||
if (IS_ERR(ctx[count])) {
|
||||
err = PTR_ERR(ctx[count]);
|
||||
while (--count)
|
||||
@@ -1291,6 +1293,7 @@ static int igt_reset_evict_ppgtt(void *arg)
|
||||
{
|
||||
struct intel_gt *gt = arg;
|
||||
struct i915_gem_context *ctx;
|
||||
struct i915_address_space *vm;
|
||||
struct drm_file *file;
|
||||
int err;
|
||||
|
||||
@@ -1298,18 +1301,20 @@ static int igt_reset_evict_ppgtt(void *arg)
|
||||
if (IS_ERR(file))
|
||||
return PTR_ERR(file);
|
||||
|
||||
mutex_lock(>->i915->drm.struct_mutex);
|
||||
ctx = live_context(gt->i915, file);
|
||||
mutex_unlock(>->i915->drm.struct_mutex);
|
||||
if (IS_ERR(ctx)) {
|
||||
err = PTR_ERR(ctx);
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = 0;
|
||||
if (ctx->vm) /* aliasing == global gtt locking, covered above */
|
||||
err = __igt_reset_evict_vma(gt, ctx->vm,
|
||||
vm = i915_gem_context_get_vm_rcu(ctx);
|
||||
if (!i915_is_ggtt(vm)) {
|
||||
/* aliasing == global gtt locking, covered above */
|
||||
err = __igt_reset_evict_vma(gt, vm,
|
||||
evict_vma, EXEC_OBJECT_WRITE);
|
||||
}
|
||||
i915_vm_put(vm);
|
||||
|
||||
out:
|
||||
mock_file_free(gt->i915, file);
|
||||
|
||||
@@ -1631,7 +1631,11 @@ static int smoke_submit(struct preempt_smoke *smoke,
|
||||
int err = 0;
|
||||
|
||||
if (batch) {
|
||||
vma = i915_vma_instance(batch, ctx->vm, NULL);
|
||||
struct i915_address_space *vm;
|
||||
|
||||
vm = i915_gem_context_get_vm_rcu(ctx);
|
||||
vma = i915_vma_instance(batch, vm, NULL);
|
||||
i915_vm_put(vm);
|
||||
if (IS_ERR(vma))
|
||||
return PTR_ERR(vma);
|
||||
|
||||
|
||||
@@ -260,7 +260,6 @@ switch_to_scratch_context(struct intel_engine_cs *engine,
|
||||
rq = igt_spinner_create_request(spin, ce, MI_NOOP);
|
||||
|
||||
intel_context_put(ce);
|
||||
kernel_context_close(ctx);
|
||||
|
||||
if (IS_ERR(rq)) {
|
||||
spin = NULL;
|
||||
@@ -279,6 +278,7 @@ err:
|
||||
if (err && spin)
|
||||
igt_spinner_end(spin);
|
||||
|
||||
kernel_context_close(ctx);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -355,6 +355,7 @@ out_ctx:
|
||||
static struct i915_vma *create_batch(struct i915_gem_context *ctx)
|
||||
{
|
||||
struct drm_i915_gem_object *obj;
|
||||
struct i915_address_space *vm;
|
||||
struct i915_vma *vma;
|
||||
int err;
|
||||
|
||||
@@ -362,7 +363,9 @@ static struct i915_vma *create_batch(struct i915_gem_context *ctx)
|
||||
if (IS_ERR(obj))
|
||||
return ERR_CAST(obj);
|
||||
|
||||
vma = i915_vma_instance(obj, ctx->vm, NULL);
|
||||
vm = i915_gem_context_get_vm_rcu(ctx);
|
||||
vma = i915_vma_instance(obj, vm, NULL);
|
||||
i915_vm_put(vm);
|
||||
if (IS_ERR(vma)) {
|
||||
err = PTR_ERR(vma);
|
||||
goto err_obj;
|
||||
@@ -463,12 +466,15 @@ static int check_dirty_whitelist(struct i915_gem_context *ctx,
|
||||
0xffff00ff,
|
||||
0xffffffff,
|
||||
};
|
||||
struct i915_address_space *vm;
|
||||
struct i915_vma *scratch;
|
||||
struct i915_vma *batch;
|
||||
int err = 0, i, v;
|
||||
u32 *cs, *results;
|
||||
|
||||
scratch = create_scratch(ctx->vm, 2 * ARRAY_SIZE(values) + 1);
|
||||
vm = i915_gem_context_get_vm_rcu(ctx);
|
||||
scratch = create_scratch(vm, 2 * ARRAY_SIZE(values) + 1);
|
||||
i915_vm_put(vm);
|
||||
if (IS_ERR(scratch))
|
||||
return PTR_ERR(scratch);
|
||||
|
||||
@@ -1010,6 +1016,7 @@ static int live_isolated_whitelist(void *arg)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(client); i++) {
|
||||
struct i915_address_space *vm;
|
||||
struct i915_gem_context *c;
|
||||
|
||||
c = kernel_context(i915);
|
||||
@@ -1018,22 +1025,27 @@ static int live_isolated_whitelist(void *arg)
|
||||
goto err;
|
||||
}
|
||||
|
||||
client[i].scratch[0] = create_scratch(c->vm, 1024);
|
||||
vm = i915_gem_context_get_vm_rcu(c);
|
||||
|
||||
client[i].scratch[0] = create_scratch(vm, 1024);
|
||||
if (IS_ERR(client[i].scratch[0])) {
|
||||
err = PTR_ERR(client[i].scratch[0]);
|
||||
i915_vm_put(vm);
|
||||
kernel_context_close(c);
|
||||
goto err;
|
||||
}
|
||||
|
||||
client[i].scratch[1] = create_scratch(c->vm, 1024);
|
||||
client[i].scratch[1] = create_scratch(vm, 1024);
|
||||
if (IS_ERR(client[i].scratch[1])) {
|
||||
err = PTR_ERR(client[i].scratch[1]);
|
||||
i915_vma_unpin_and_release(&client[i].scratch[0], 0);
|
||||
i915_vm_put(vm);
|
||||
kernel_context_close(c);
|
||||
goto err;
|
||||
}
|
||||
|
||||
client[i].ctx = c;
|
||||
i915_vm_put(vm);
|
||||
}
|
||||
|
||||
for_each_engine(engine, i915, id) {
|
||||
|
||||
Reference in New Issue
Block a user