181 lines · c
1/*2 * SPDX-License-Identifier: MIT3 *4 * Copyright © 2016 Intel Corporation5 */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 12struct i915_gem_context *13mock_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 strscpy(ctx->name, name, sizeof(ctx->name));40 41 ppgtt = mock_ppgtt(i915, name);42 if (!ppgtt)43 goto err_free;44 45 ctx->vm = &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 59err_vm:60 if (ctx->vm)61 i915_vm_put(ctx->vm);62err_free:63 kfree(ctx);64 return NULL;65}66 67void mock_context_close(struct i915_gem_context *ctx)68{69 context_close(ctx);70}71 72void mock_init_contexts(struct drm_i915_private *i915)73{74 init_contexts(&i915->gem.contexts);75}76 77struct i915_gem_context *78live_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(fpriv, 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 105err_ctx:106 context_close(ctx);107 return ERR_PTR(err);108}109 110struct i915_gem_context *111live_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 148struct i915_gem_context *149kernel_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(NULL, 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 177void kernel_context_close(struct i915_gem_context *ctx)178{179 context_close(ctx);180}181