1c349dbc7Sjsg /*
2c349dbc7Sjsg * SPDX-License-Identifier: MIT
3c349dbc7Sjsg *
4c349dbc7Sjsg * Copyright © 2016 Intel Corporation
5c349dbc7Sjsg */
6c349dbc7Sjsg
7*1bb76ff1Sjsg #include "i915_file_private.h"
8c349dbc7Sjsg #include "mock_context.h"
9c349dbc7Sjsg #include "selftests/mock_drm.h"
10c349dbc7Sjsg #include "selftests/mock_gtt.h"
11c349dbc7Sjsg
12c349dbc7Sjsg struct i915_gem_context *
mock_context(struct drm_i915_private * i915,const char * name)13c349dbc7Sjsg mock_context(struct drm_i915_private *i915,
14c349dbc7Sjsg const char *name)
15c349dbc7Sjsg {
16c349dbc7Sjsg struct i915_gem_context *ctx;
17c349dbc7Sjsg struct i915_gem_engines *e;
185ca02815Sjsg struct intel_sseu null_sseu = {};
19c349dbc7Sjsg
20c349dbc7Sjsg ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
21c349dbc7Sjsg if (!ctx)
22c349dbc7Sjsg return NULL;
23c349dbc7Sjsg
24c349dbc7Sjsg kref_init(&ctx->ref);
25c349dbc7Sjsg INIT_LIST_HEAD(&ctx->link);
26c349dbc7Sjsg ctx->i915 = i915;
27*1bb76ff1Sjsg INIT_WORK(&ctx->release_work, i915_gem_context_release_work);
28c349dbc7Sjsg
29ad8b1aafSjsg rw_init(&ctx->mutex, "mkctx");
30ad8b1aafSjsg
31c349dbc7Sjsg mtx_init(&ctx->stale.lock, IPL_TTY);
32c349dbc7Sjsg INIT_LIST_HEAD(&ctx->stale.engines);
33c349dbc7Sjsg
34c349dbc7Sjsg i915_gem_context_set_persistence(ctx);
35c349dbc7Sjsg
36c349dbc7Sjsg if (name) {
37c349dbc7Sjsg struct i915_ppgtt *ppgtt;
38c349dbc7Sjsg
39c349dbc7Sjsg strncpy(ctx->name, name, sizeof(ctx->name) - 1);
40c349dbc7Sjsg
41c349dbc7Sjsg ppgtt = mock_ppgtt(i915, name);
42c349dbc7Sjsg if (!ppgtt)
435ca02815Sjsg goto err_free;
44c349dbc7Sjsg
45*1bb76ff1Sjsg ctx->vm = &ppgtt->vm;
46c349dbc7Sjsg }
47c349dbc7Sjsg
485ca02815Sjsg rw_init(&ctx->engines_mutex, "mkeng");
495ca02815Sjsg e = default_engines(ctx, null_sseu);
505ca02815Sjsg if (IS_ERR(e))
515ca02815Sjsg goto err_vm;
525ca02815Sjsg RCU_INIT_POINTER(ctx->engines, e);
535ca02815Sjsg
545ca02815Sjsg INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL);
555ca02815Sjsg rw_init(&ctx->lut_mutex, "lutmtx");
565ca02815Sjsg
57c349dbc7Sjsg return ctx;
58c349dbc7Sjsg
595ca02815Sjsg err_vm:
605ca02815Sjsg if (ctx->vm)
61*1bb76ff1Sjsg i915_vm_put(ctx->vm);
62c349dbc7Sjsg err_free:
63c349dbc7Sjsg kfree(ctx);
64c349dbc7Sjsg return NULL;
65c349dbc7Sjsg }
66c349dbc7Sjsg
mock_context_close(struct i915_gem_context * ctx)67c349dbc7Sjsg void mock_context_close(struct i915_gem_context *ctx)
68c349dbc7Sjsg {
69c349dbc7Sjsg context_close(ctx);
70c349dbc7Sjsg }
71c349dbc7Sjsg
mock_init_contexts(struct drm_i915_private * i915)72c349dbc7Sjsg void mock_init_contexts(struct drm_i915_private *i915)
73c349dbc7Sjsg {
74c349dbc7Sjsg init_contexts(&i915->gem.contexts);
75c349dbc7Sjsg }
76c349dbc7Sjsg
77c349dbc7Sjsg struct i915_gem_context *
live_context(struct drm_i915_private * i915,struct file * file)78c349dbc7Sjsg live_context(struct drm_i915_private *i915, struct file *file)
79c349dbc7Sjsg {
805ca02815Sjsg struct drm_i915_file_private *fpriv = to_drm_file(file)->driver_priv;
815ca02815Sjsg struct i915_gem_proto_context *pc;
82c349dbc7Sjsg struct i915_gem_context *ctx;
83c349dbc7Sjsg int err;
84c349dbc7Sjsg u32 id;
85c349dbc7Sjsg
865ca02815Sjsg pc = proto_context_create(i915, 0);
875ca02815Sjsg if (IS_ERR(pc))
885ca02815Sjsg return ERR_CAST(pc);
895ca02815Sjsg
905ca02815Sjsg ctx = i915_gem_create_context(i915, pc);
91*1bb76ff1Sjsg proto_context_close(i915, pc);
92c349dbc7Sjsg if (IS_ERR(ctx))
93c349dbc7Sjsg return ctx;
94c349dbc7Sjsg
95c349dbc7Sjsg i915_gem_context_set_no_error_capture(ctx);
96c349dbc7Sjsg
975ca02815Sjsg err = xa_alloc(&fpriv->context_xa, &id, NULL, xa_limit_32b, GFP_KERNEL);
98c349dbc7Sjsg if (err < 0)
99c349dbc7Sjsg goto err_ctx;
100c349dbc7Sjsg
1015ca02815Sjsg gem_context_register(ctx, fpriv, id);
1025ca02815Sjsg
103c349dbc7Sjsg return ctx;
104c349dbc7Sjsg
105c349dbc7Sjsg err_ctx:
106c349dbc7Sjsg context_close(ctx);
107c349dbc7Sjsg return ERR_PTR(err);
108c349dbc7Sjsg }
109c349dbc7Sjsg
110c349dbc7Sjsg struct i915_gem_context *
live_context_for_engine(struct intel_engine_cs * engine,struct file * file)111ad8b1aafSjsg live_context_for_engine(struct intel_engine_cs *engine, struct file *file)
112ad8b1aafSjsg {
113ad8b1aafSjsg struct i915_gem_engines *engines;
114ad8b1aafSjsg struct i915_gem_context *ctx;
1155ca02815Sjsg struct intel_sseu null_sseu = {};
116ad8b1aafSjsg struct intel_context *ce;
117ad8b1aafSjsg
118ad8b1aafSjsg engines = alloc_engines(1);
119ad8b1aafSjsg if (!engines)
120ad8b1aafSjsg return ERR_PTR(-ENOMEM);
121ad8b1aafSjsg
122ad8b1aafSjsg ctx = live_context(engine->i915, file);
123ad8b1aafSjsg if (IS_ERR(ctx)) {
124ad8b1aafSjsg __free_engines(engines, 0);
125ad8b1aafSjsg return ctx;
126ad8b1aafSjsg }
127ad8b1aafSjsg
128ad8b1aafSjsg ce = intel_context_create(engine);
129ad8b1aafSjsg if (IS_ERR(ce)) {
130ad8b1aafSjsg __free_engines(engines, 0);
131ad8b1aafSjsg return ERR_CAST(ce);
132ad8b1aafSjsg }
133ad8b1aafSjsg
1345ca02815Sjsg intel_context_set_gem(ce, ctx, null_sseu);
135ad8b1aafSjsg engines->engines[0] = ce;
136ad8b1aafSjsg engines->num_engines = 1;
137ad8b1aafSjsg
138ad8b1aafSjsg mutex_lock(&ctx->engines_mutex);
139ad8b1aafSjsg i915_gem_context_set_user_engines(ctx);
140ad8b1aafSjsg engines = rcu_replace_pointer(ctx->engines, engines, 1);
141ad8b1aafSjsg mutex_unlock(&ctx->engines_mutex);
142ad8b1aafSjsg
143ad8b1aafSjsg engines_idle_release(ctx, engines);
144ad8b1aafSjsg
145ad8b1aafSjsg return ctx;
146ad8b1aafSjsg }
147ad8b1aafSjsg
148ad8b1aafSjsg struct i915_gem_context *
kernel_context(struct drm_i915_private * i915,struct i915_address_space * vm)1495ca02815Sjsg kernel_context(struct drm_i915_private *i915,
1505ca02815Sjsg struct i915_address_space *vm)
151c349dbc7Sjsg {
152c349dbc7Sjsg struct i915_gem_context *ctx;
1535ca02815Sjsg struct i915_gem_proto_context *pc;
154c349dbc7Sjsg
1555ca02815Sjsg pc = proto_context_create(i915, 0);
1565ca02815Sjsg if (IS_ERR(pc))
1575ca02815Sjsg return ERR_CAST(pc);
1585ca02815Sjsg
1595ca02815Sjsg if (vm) {
1605ca02815Sjsg if (pc->vm)
1615ca02815Sjsg i915_vm_put(pc->vm);
1625ca02815Sjsg pc->vm = i915_vm_get(vm);
1635ca02815Sjsg }
1645ca02815Sjsg
1655ca02815Sjsg ctx = i915_gem_create_context(i915, pc);
166*1bb76ff1Sjsg proto_context_close(i915, pc);
167c349dbc7Sjsg if (IS_ERR(ctx))
168c349dbc7Sjsg return ctx;
169c349dbc7Sjsg
170c349dbc7Sjsg i915_gem_context_clear_bannable(ctx);
171c349dbc7Sjsg i915_gem_context_set_persistence(ctx);
172c349dbc7Sjsg i915_gem_context_set_no_error_capture(ctx);
173c349dbc7Sjsg
174c349dbc7Sjsg return ctx;
175c349dbc7Sjsg }
176c349dbc7Sjsg
kernel_context_close(struct i915_gem_context * ctx)177c349dbc7Sjsg void kernel_context_close(struct i915_gem_context *ctx)
178c349dbc7Sjsg {
179c349dbc7Sjsg context_close(ctx);
180c349dbc7Sjsg }
181