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