1 /* 2 * SPDX-License-Identifier: MIT 3 * 4 * Copyright © 2016 Intel Corporation 5 */ 6 7 #include "i915_file_private.h" 8 #include "mock_context.h" 9 #include "selftests/mock_drm.h" 10 #include "selftests/mock_gtt.h" 11 12 struct i915_gem_context * 13 mock_context(struct drm_i915_private *i915, 14 const char *name) 15 { 16 struct i915_gem_context *ctx; 17 struct i915_gem_engines *e; 18 struct intel_sseu null_sseu = {}; 19 20 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 21 if (!ctx) 22 return NULL; 23 24 kref_init(&ctx->ref); 25 INIT_LIST_HEAD(&ctx->link); 26 ctx->i915 = i915; 27 INIT_WORK(&ctx->release_work, i915_gem_context_release_work); 28 29 mutex_init(&ctx->mutex); 30 31 spin_lock_init(&ctx->stale.lock); 32 INIT_LIST_HEAD(&ctx->stale.engines); 33 34 i915_gem_context_set_persistence(ctx); 35 36 if (name) { 37 struct i915_ppgtt *ppgtt; 38 39 strncpy(ctx->name, name, sizeof(ctx->name) - 1); 40 41 ppgtt = mock_ppgtt(i915, name); 42 if (!ppgtt) 43 goto err_free; 44 45 ctx->vm = i915_vm_open(&ppgtt->vm); 46 i915_vm_put(&ppgtt->vm); 47 } 48 49 mutex_init(&ctx->engines_mutex); 50 e = default_engines(ctx, null_sseu); 51 if (IS_ERR(e)) 52 goto err_vm; 53 RCU_INIT_POINTER(ctx->engines, e); 54 55 INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL); 56 mutex_init(&ctx->lut_mutex); 57 58 return ctx; 59 60 err_vm: 61 if (ctx->vm) 62 i915_vm_close(ctx->vm); 63 err_free: 64 kfree(ctx); 65 return NULL; 66 } 67 68 void mock_context_close(struct i915_gem_context *ctx) 69 { 70 context_close(ctx); 71 } 72 73 void mock_init_contexts(struct drm_i915_private *i915) 74 { 75 init_contexts(&i915->gem.contexts); 76 } 77 78 struct i915_gem_context * 79 live_context(struct drm_i915_private *i915, struct file *file) 80 { 81 struct drm_i915_file_private *fpriv = to_drm_file(file)->driver_priv; 82 struct i915_gem_proto_context *pc; 83 struct i915_gem_context *ctx; 84 int err; 85 u32 id; 86 87 pc = proto_context_create(i915, 0); 88 if (IS_ERR(pc)) 89 return ERR_CAST(pc); 90 91 ctx = i915_gem_create_context(i915, pc); 92 proto_context_close(i915, pc); 93 if (IS_ERR(ctx)) 94 return ctx; 95 96 i915_gem_context_set_no_error_capture(ctx); 97 98 err = xa_alloc(&fpriv->context_xa, &id, NULL, xa_limit_32b, GFP_KERNEL); 99 if (err < 0) 100 goto err_ctx; 101 102 gem_context_register(ctx, fpriv, id); 103 104 return ctx; 105 106 err_ctx: 107 context_close(ctx); 108 return ERR_PTR(err); 109 } 110 111 struct i915_gem_context * 112 live_context_for_engine(struct intel_engine_cs *engine, struct file *file) 113 { 114 struct i915_gem_engines *engines; 115 struct i915_gem_context *ctx; 116 struct intel_sseu null_sseu = {}; 117 struct intel_context *ce; 118 119 engines = alloc_engines(1); 120 if (!engines) 121 return ERR_PTR(-ENOMEM); 122 123 ctx = live_context(engine->i915, file); 124 if (IS_ERR(ctx)) { 125 __free_engines(engines, 0); 126 return ctx; 127 } 128 129 ce = intel_context_create(engine); 130 if (IS_ERR(ce)) { 131 __free_engines(engines, 0); 132 return ERR_CAST(ce); 133 } 134 135 intel_context_set_gem(ce, ctx, null_sseu); 136 engines->engines[0] = ce; 137 engines->num_engines = 1; 138 139 mutex_lock(&ctx->engines_mutex); 140 i915_gem_context_set_user_engines(ctx); 141 engines = rcu_replace_pointer(ctx->engines, engines, 1); 142 mutex_unlock(&ctx->engines_mutex); 143 144 engines_idle_release(ctx, engines); 145 146 return ctx; 147 } 148 149 struct i915_gem_context * 150 kernel_context(struct drm_i915_private *i915, 151 struct i915_address_space *vm) 152 { 153 struct i915_gem_context *ctx; 154 struct i915_gem_proto_context *pc; 155 156 pc = proto_context_create(i915, 0); 157 if (IS_ERR(pc)) 158 return ERR_CAST(pc); 159 160 if (vm) { 161 if (pc->vm) 162 i915_vm_put(pc->vm); 163 pc->vm = i915_vm_get(vm); 164 } 165 166 ctx = i915_gem_create_context(i915, pc); 167 proto_context_close(i915, pc); 168 if (IS_ERR(ctx)) 169 return ctx; 170 171 i915_gem_context_clear_bannable(ctx); 172 i915_gem_context_set_persistence(ctx); 173 i915_gem_context_set_no_error_capture(ctx); 174 175 return ctx; 176 } 177 178 void kernel_context_close(struct i915_gem_context *ctx) 179 { 180 context_close(ctx); 181 } 182