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 18 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 19 if (!ctx) 20 return NULL; 21 22 kref_init(&ctx->ref); 23 INIT_LIST_HEAD(&ctx->link); 24 ctx->i915 = i915; 25 26 mutex_init(&ctx->mutex); 27 28 spin_lock_init(&ctx->stale.lock); 29 INIT_LIST_HEAD(&ctx->stale.engines); 30 31 i915_gem_context_set_persistence(ctx); 32 33 mutex_init(&ctx->engines_mutex); 34 e = default_engines(ctx); 35 if (IS_ERR(e)) 36 goto err_free; 37 RCU_INIT_POINTER(ctx->engines, e); 38 39 INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL); 40 mutex_init(&ctx->lut_mutex); 41 42 if (name) { 43 struct i915_ppgtt *ppgtt; 44 45 strncpy(ctx->name, name, sizeof(ctx->name) - 1); 46 47 ppgtt = mock_ppgtt(i915, name); 48 if (!ppgtt) 49 goto err_put; 50 51 mutex_lock(&ctx->mutex); 52 __set_ppgtt(ctx, &ppgtt->vm); 53 mutex_unlock(&ctx->mutex); 54 55 i915_vm_put(&ppgtt->vm); 56 } 57 58 return ctx; 59 60 err_free: 61 kfree(ctx); 62 return NULL; 63 64 err_put: 65 i915_gem_context_set_closed(ctx); 66 i915_gem_context_put(ctx); 67 return NULL; 68 } 69 70 void mock_context_close(struct i915_gem_context *ctx) 71 { 72 context_close(ctx); 73 } 74 75 void mock_init_contexts(struct drm_i915_private *i915) 76 { 77 init_contexts(&i915->gem.contexts); 78 } 79 80 struct i915_gem_context * 81 live_context(struct drm_i915_private *i915, struct file *file) 82 { 83 struct i915_gem_context *ctx; 84 int err; 85 u32 id; 86 87 ctx = i915_gem_create_context(i915, 0); 88 if (IS_ERR(ctx)) 89 return ctx; 90 91 i915_gem_context_set_no_error_capture(ctx); 92 93 err = gem_context_register(ctx, to_drm_file(file)->driver_priv, &id); 94 if (err < 0) 95 goto err_ctx; 96 97 return ctx; 98 99 err_ctx: 100 context_close(ctx); 101 return ERR_PTR(err); 102 } 103 104 struct i915_gem_context * 105 live_context_for_engine(struct intel_engine_cs *engine, struct file *file) 106 { 107 struct i915_gem_engines *engines; 108 struct i915_gem_context *ctx; 109 struct intel_context *ce; 110 111 engines = alloc_engines(1); 112 if (!engines) 113 return ERR_PTR(-ENOMEM); 114 115 ctx = live_context(engine->i915, file); 116 if (IS_ERR(ctx)) { 117 __free_engines(engines, 0); 118 return ctx; 119 } 120 121 ce = intel_context_create(engine); 122 if (IS_ERR(ce)) { 123 __free_engines(engines, 0); 124 return ERR_CAST(ce); 125 } 126 127 intel_context_set_gem(ce, ctx); 128 engines->engines[0] = ce; 129 engines->num_engines = 1; 130 131 mutex_lock(&ctx->engines_mutex); 132 i915_gem_context_set_user_engines(ctx); 133 engines = rcu_replace_pointer(ctx->engines, engines, 1); 134 mutex_unlock(&ctx->engines_mutex); 135 136 engines_idle_release(ctx, engines); 137 138 return ctx; 139 } 140 141 struct i915_gem_context * 142 kernel_context(struct drm_i915_private *i915) 143 { 144 struct i915_gem_context *ctx; 145 146 ctx = i915_gem_create_context(i915, 0); 147 if (IS_ERR(ctx)) 148 return ctx; 149 150 i915_gem_context_clear_bannable(ctx); 151 i915_gem_context_set_persistence(ctx); 152 i915_gem_context_set_no_error_capture(ctx); 153 154 return ctx; 155 } 156 157 void kernel_context_close(struct i915_gem_context *ctx) 158 { 159 context_close(ctx); 160 } 161