[Intel-gfx] [PATCH 33/40] drm/i915: Extend CREATE_CONTEXT to allow inheritance ala clone()
Tvrtko Ursulin
tvrtko.ursulin at linux.intel.com
Mon Sep 24 17:22:43 UTC 2018
On 19/09/2018 20:55, Chris Wilson wrote:
> A context encompasses the driver's view of process related state, and
> encapsulates the logical GPU state where available. Each context is
> currently equivalent to a process in CPU terms. Like with processes,
> sometimes the user wants a lighter encapsulation that shares some state
> with the parent process, for example two threads have unique register
> state but share the virtual memory mappings. We can support exactly the
> same principle using contexts where we may share the GTT but keep the
> logical GPU state distinct. This allows quicker switching between those
> contexts, and for userspace to allocate a single offset in the GTT and
> use it across multiple contexts. Like with clone(), in the future we may
> wish to allow userspace to select more features to copy across from the
> parent, but for now we only allow sharing of the GTT.
>
> Note that if full per-process GTT is not supported on the harder, the
s/harder/hardware/
> GTT are already implicitly shared between contexts, and this request
> to create contexts with shared GTT fails. With full ppGTT, every fd
> (i.e. every process) is allocated a unique GTT so this request cannot be
> used to share GTT between processes/fds, it can only share GTT belonging
> to this fd.
>
> Testcase: igt/gem_ctx_shared
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
> Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
> Cc: Mika Kuoppala <mika.kuoppala at linux.intel.com>
> Cc: MichaĆ Winiarski <michal.winiarski at intel.com>
> ---
> drivers/gpu/drm/i915/i915_gem_context.c | 62 ++++-
> drivers/gpu/drm/i915/i915_gem_gtt.c | 19 +-
> drivers/gpu/drm/i915/i915_gem_gtt.h | 14 +-
> drivers/gpu/drm/i915/selftests/huge_pages.c | 1 -
> .../gpu/drm/i915/selftests/i915_gem_context.c | 252 +++++++++++++-----
> drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 1 -
> drivers/gpu/drm/i915/selftests/mock_context.c | 2 +-
> drivers/gpu/drm/i915/selftests/mock_gtt.c | 2 +
> include/uapi/drm/i915_drm.h | 11 +-
> 9 files changed, 279 insertions(+), 85 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
> index 150d7a6b2bd3..da2ac10f8e8a 100644
> --- a/drivers/gpu/drm/i915/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/i915_gem_context.c
> @@ -110,6 +110,8 @@ static void lut_close(struct i915_gem_context *ctx)
> struct i915_vma *vma = rcu_dereference_raw(*slot);
>
> radix_tree_iter_delete(&ctx->handles_vma, &iter, slot);
> +
> + vma->open_count--;
> __i915_gem_object_release_unless_active(vma->obj);
> }
> rcu_read_unlock();
> @@ -292,7 +294,7 @@ static void context_close(struct i915_gem_context *ctx)
> */
> lut_close(ctx);
> if (ctx->ppgtt)
> - i915_ppgtt_close(&ctx->ppgtt->vm);
> + i915_ppgtt_close(ctx->ppgtt);
>
> ctx->file_priv = ERR_PTR(-EBADF);
> i915_gem_context_put(ctx);
> @@ -399,9 +401,12 @@ static void __destroy_hw_context(struct i915_gem_context *ctx,
> context_close(ctx);
> }
>
> +#define CREATE_VM BIT(0)
> +
> static struct i915_gem_context *
> i915_gem_create_context(struct drm_i915_private *dev_priv,
> - struct drm_i915_file_private *file_priv)
> + struct drm_i915_file_private *file_priv,
> + unsigned int flags)
> {
> struct i915_gem_context *ctx;
>
> @@ -414,7 +419,7 @@ i915_gem_create_context(struct drm_i915_private *dev_priv,
> if (IS_ERR(ctx))
> return ctx;
>
> - if (USES_FULL_PPGTT(dev_priv)) {
> + if (flags & CREATE_VM && USES_FULL_PPGTT(dev_priv)) {
> struct i915_hw_ppgtt *ppgtt;
>
> ppgtt = i915_ppgtt_create(dev_priv, file_priv);
> @@ -493,7 +498,7 @@ i915_gem_context_create_kernel(struct drm_i915_private *i915, int prio)
> struct i915_gem_context *ctx;
> int err;
>
> - ctx = i915_gem_create_context(i915, NULL);
> + ctx = i915_gem_create_context(i915, NULL, CREATE_VM);
> if (IS_ERR(ctx))
> return ctx;
>
> @@ -620,7 +625,7 @@ int i915_gem_context_open(struct drm_i915_private *i915,
> idr_init(&file_priv->context_idr);
>
> mutex_lock(&i915->drm.struct_mutex);
> - ctx = i915_gem_create_context(i915, file_priv);
> + ctx = i915_gem_create_context(i915, file_priv, CREATE_VM);
> mutex_unlock(&i915->drm.struct_mutex);
> if (IS_ERR(ctx)) {
> idr_destroy(&file_priv->context_idr);
> @@ -778,10 +783,12 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
> struct drm_file *file)
> {
> struct drm_i915_private *dev_priv = to_i915(dev);
> - struct drm_i915_gem_context_create *args = data;
> + struct drm_i915_gem_context_create_v2 *args = data;
> struct drm_i915_file_private *file_priv = file->driver_priv;
> + struct i915_gem_context *share = NULL;
> struct i915_gem_context *ctx;
> - int ret;
> + unsigned int flags = CREATE_VM;
> + int err;
>
> if (!DRIVER_CAPS(dev_priv)->has_logical_contexts)
> return -ENODEV;
> @@ -789,6 +796,9 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
> if (args->pad != 0)
> return -EINVAL;
>
> + if (args->flags & ~I915_GEM_CONTEXT_SHARE_GTT)
> + return -EINVAL;
> +
> if (client_is_banned(file_priv)) {
> DRM_DEBUG("client %s[%d] banned from creating ctx\n",
> current->comm,
> @@ -797,21 +807,45 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
> return -EIO;
> }
>
> - ret = i915_mutex_lock_interruptible(dev);
> - if (ret)
> - return ret;
> + if (args->flags & I915_GEM_CONTEXT_SHARE_GTT) {
> + share = i915_gem_context_lookup(file_priv, args->share_ctx);
> + if (!share)
> + return -ENOENT;
> +
> + if (!share->ppgtt) {
> + err = -ENODEV;
> + goto out;
> + }
> +
> + flags &= ~CREATE_VM;
> + }
>
> - ctx = i915_gem_create_context(dev_priv, file_priv);
> + err = i915_mutex_lock_interruptible(dev);
> + if (err)
> + goto out;
> +
> + ctx = i915_gem_create_context(dev_priv, file_priv, flags);
> mutex_unlock(&dev->struct_mutex);
> - if (IS_ERR(ctx))
> - return PTR_ERR(ctx);
> + if (IS_ERR(ctx)) {
> + err = PTR_ERR(ctx);
> + goto out;
> + }
> +
> + if (!(flags & CREATE_VM)) {
> + ctx->desc_template = share->desc_template;
> + ctx->ppgtt = i915_ppgtt_get(share->ppgtt);
> + i915_ppgtt_open(ctx->ppgtt);
i915_ppgtt_open/close are guarded by struct mutex?
As such it looks open_count can drop to zero between the context lookup
and here. In which case the assert in i915_ppgtt_open would trigger.
Is it acceptable that you have something like i915_ppgtt_try_open?
> + }
>
> GEM_BUG_ON(i915_gem_context_is_kernel(ctx));
>
> args->ctx_id = ctx->user_handle;
> DRM_DEBUG("HW context %d created\n", args->ctx_id);
>
> - return 0;
> +out:
> + if (share)
> + i915_gem_context_put(share);
> + return err;
> }
>
> int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index d1ca67459bc2..caf48a1a1c97 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -1644,6 +1644,7 @@ static struct i915_hw_ppgtt *gen8_ppgtt_create(struct drm_i915_private *i915)
> return ERR_PTR(-ENOMEM);
>
> kref_init(&ppgtt->ref);
> + ppgtt->open_count = 1;
>
> ppgtt->vm.i915 = i915;
> ppgtt->vm.dma = &i915->drm.pdev->dev;
> @@ -2160,6 +2161,7 @@ static struct i915_hw_ppgtt *gen6_ppgtt_create(struct drm_i915_private *i915)
> return ERR_PTR(-ENOMEM);
>
> kref_init(&ppgtt->base.ref);
> + ppgtt->base.open_count = 1;
>
> ppgtt->base.vm.i915 = i915;
> ppgtt->base.vm.dma = &i915->drm.pdev->dev;
> @@ -2285,10 +2287,21 @@ i915_ppgtt_create(struct drm_i915_private *i915,
> return ppgtt;
> }
>
> -void i915_ppgtt_close(struct i915_address_space *vm)
> +void i915_ppgtt_open(struct i915_hw_ppgtt *ppgtt)
> {
> - GEM_BUG_ON(vm->closed);
> - vm->closed = true;
> + GEM_BUG_ON(ppgtt->vm.closed);
> +
> + ppgtt->open_count++;
> +}
> +
> +void i915_ppgtt_close(struct i915_hw_ppgtt *ppgtt)
> +{
> + GEM_BUG_ON(!ppgtt->open_count);
> + if (--ppgtt->open_count)
> + return;
> +
> + GEM_BUG_ON(ppgtt->vm.closed);
> + ppgtt->vm.closed = true;
> }
>
> static void ppgtt_destroy_vma(struct i915_address_space *vm)
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
> index 849a1f67b037..512a5a0ab820 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.h
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
> @@ -408,6 +408,8 @@ struct i915_hw_ppgtt {
> struct kref ref;
>
> unsigned long pd_dirty_rings;
> + unsigned int open_count;
> +
> union {
> struct i915_pml4 pml4; /* GEN8+ & 48b PPGTT */
> struct i915_page_directory_pointer pdp; /* GEN8+ */
> @@ -626,12 +628,16 @@ int i915_ppgtt_init_hw(struct drm_i915_private *dev_priv);
> void i915_ppgtt_release(struct kref *kref);
> struct i915_hw_ppgtt *i915_ppgtt_create(struct drm_i915_private *dev_priv,
> struct drm_i915_file_private *fpriv);
> -void i915_ppgtt_close(struct i915_address_space *vm);
> -static inline void i915_ppgtt_get(struct i915_hw_ppgtt *ppgtt)
> +
> +void i915_ppgtt_open(struct i915_hw_ppgtt *ppgtt);
> +void i915_ppgtt_close(struct i915_hw_ppgtt *ppgtt);
> +
> +static inline struct i915_hw_ppgtt *i915_ppgtt_get(struct i915_hw_ppgtt *ppgtt)
> {
> - if (ppgtt)
> - kref_get(&ppgtt->ref);
> + kref_get(&ppgtt->ref);
> + return ppgtt;
> }
> +
> static inline void i915_ppgtt_put(struct i915_hw_ppgtt *ppgtt)
> {
> if (ppgtt)
> diff --git a/drivers/gpu/drm/i915/selftests/huge_pages.c b/drivers/gpu/drm/i915/selftests/huge_pages.c
> index 4ab98db946c8..ad25860a3336 100644
> --- a/drivers/gpu/drm/i915/selftests/huge_pages.c
> +++ b/drivers/gpu/drm/i915/selftests/huge_pages.c
> @@ -1724,7 +1724,6 @@ int i915_gem_huge_page_mock_selftests(void)
> err = i915_subtests(tests, ppgtt);
>
> out_close:
> - i915_ppgtt_close(&ppgtt->vm);
> i915_ppgtt_put(ppgtt);
>
> out_unlock:
> diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/selftests/i915_gem_context.c
> index c7c891a287f5..7ef3f9a3b727 100644
> --- a/drivers/gpu/drm/i915/selftests/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/selftests/i915_gem_context.c
> @@ -131,7 +131,9 @@ static int live_nop_switch(void *arg)
> }
>
> for (n = 0; n < nctx; n++) {
> - ctx[n] = i915_gem_create_context(i915, file->driver_priv);
> + ctx[n] = i915_gem_create_context(i915,
> + file->driver_priv,
> + CREATE_VM);
> if (IS_ERR(ctx[n])) {
> err = PTR_ERR(ctx[n]);
> goto out_unlock;
> @@ -317,10 +319,6 @@ static int gpu_fill(struct drm_i915_gem_object *obj,
> if (IS_ERR(vma))
> return PTR_ERR(vma);
>
> - err = i915_gem_object_set_to_gtt_domain(obj, false);
> - if (err)
> - return err;
> -
Unrelated hunk?
> err = i915_vma_pin(vma, 0, 0, PIN_HIGH | PIN_USER);
> if (err)
> return err;
> @@ -415,7 +413,8 @@ static int cpu_fill(struct drm_i915_gem_object *obj, u32 value)
> return 0;
> }
>
> -static int cpu_check(struct drm_i915_gem_object *obj, unsigned int max)
> +static noinline int cpu_check(struct drm_i915_gem_object *obj,
> + unsigned int idx, unsigned int max)
> {
> unsigned int n, m, needs_flush;
> int err;
> @@ -433,8 +432,8 @@ static int cpu_check(struct drm_i915_gem_object *obj, unsigned int max)
>
> for (m = 0; m < max; m++) {
> if (map[m] != m) {
> - pr_err("Invalid value at page %d, offset %d: found %x expected %x\n",
> - n, m, map[m], m);
> + pr_err("%pS: Invalid value at object %d page %d, offset %d: found %x expected %x\n",
> + __builtin_return_address(0), idx, n, m, map[m], m);
> err = -EINVAL;
> goto out_unmap;
> }
> @@ -442,8 +441,9 @@ static int cpu_check(struct drm_i915_gem_object *obj, unsigned int max)
>
> for (; m < DW_PER_PAGE; m++) {
> if (map[m] != STACK_MAGIC) {
> - pr_err("Invalid value at page %d, offset %d: found %x expected %x\n",
> - n, m, map[m], STACK_MAGIC);
> + pr_err("%pS: Invalid value at object %d page %d, offset %d: found %x expected %x\n",
> + __builtin_return_address(0), idx, n, m,
> + map[m], STACK_MAGIC);
> err = -EINVAL;
> goto out_unmap;
> }
> @@ -506,6 +506,10 @@ create_test_object(struct i915_gem_context *ctx,
> return ERR_PTR(err);
> }
>
> + err = i915_gem_object_set_to_gtt_domain(obj, false);
> + if (err)
> + return ERR_PTR(err);
> +
And these ones unrelated as well?
> list_add_tail(&obj->st_link, objects);
> return obj;
> }
> @@ -521,12 +525,8 @@ static unsigned long max_dwords(struct drm_i915_gem_object *obj)
> static int igt_ctx_exec(void *arg)
> {
> struct drm_i915_private *i915 = arg;
> - struct drm_i915_gem_object *obj = NULL;
> - struct drm_file *file;
> - IGT_TIMEOUT(end_time);
> - LIST_HEAD(objects);
> - unsigned long ncontexts, ndwords, dw;
> - bool first_shared_gtt = true;
> + struct intel_engine_cs *engine;
> + enum intel_engine_id id;
> int err = -ENODEV;
>
> /*
> @@ -538,42 +538,169 @@ static int igt_ctx_exec(void *arg)
> if (!DRIVER_CAPS(i915)->has_logical_contexts)
> return 0;
>
> - file = mock_file(i915);
> - if (IS_ERR(file))
> - return PTR_ERR(file);
> + for_each_engine(engine, i915, id) {
> + struct drm_i915_gem_object *obj = NULL;
> + struct drm_file *file;
> + IGT_TIMEOUT(end_time);
> + LIST_HEAD(objects);
> + unsigned long ncontexts, ndwords, dw;
> + bool first_shared_gtt = true;
> +
> + if (!intel_engine_can_store_dword(engine))
> + continue;
>
> - mutex_lock(&i915->drm.struct_mutex);
> + if (!engine->context_size)
> + continue; /* No logical context support in HW */
>
> - ncontexts = 0;
> - ndwords = 0;
> - dw = 0;
> - while (!time_after(jiffies, end_time)) {
> - struct intel_engine_cs *engine;
> - struct i915_gem_context *ctx;
> - unsigned int id;
>
> - if (first_shared_gtt) {
> - ctx = __create_hw_context(i915, file->driver_priv);
> - first_shared_gtt = false;
> - } else {
> - ctx = i915_gem_create_context(i915, file->driver_priv);
> + file = mock_file(i915);
> + if (IS_ERR(file))
> + return PTR_ERR(file);
> +
> + mutex_lock(&i915->drm.struct_mutex);
> +
> + ncontexts = 0;
> + ndwords = 0;
> + dw = 0;
> + while (!time_after(jiffies, end_time)) {
> + struct i915_gem_context *ctx;
> + intel_wakeref_t wakeref;
> +
> + if (first_shared_gtt) {
> + ctx = __create_hw_context(i915, file->driver_priv);
> + first_shared_gtt = false;
> + } else {
> + ctx = i915_gem_create_context(i915,
> + file->driver_priv,
> + CREATE_VM);
> + }
> + if (IS_ERR(ctx)) {
> + err = PTR_ERR(ctx);
> + goto out_unlock;
> + }
> +
> + if (!obj) {
> + obj = create_test_object(ctx, file, &objects);
> + if (IS_ERR(obj)) {
> + err = PTR_ERR(obj);
> + goto out_unlock;
> + }
> + }
> +
> + wakeref = intel_runtime_pm_get(i915);
> + err = gpu_fill(obj, ctx, engine, dw);
> + intel_runtime_pm_put(i915, wakeref);
> + if (err) {
> + pr_err("Failed to fill dword %lu [%lu/%lu] with gpu (%s) in ctx %u [full-ppgtt? %s], err=%d\n",
> + ndwords, dw, max_dwords(obj),
> + engine->name, ctx->hw_id,
> + yesno(!!ctx->ppgtt), err);
> + goto out_unlock;
> + }
> +
> + if (++dw == max_dwords(obj)) {
> + obj = NULL;
> + dw = 0;
> + }
> +
> + ndwords++;
> + ncontexts++;
> }
> - if (IS_ERR(ctx)) {
> - err = PTR_ERR(ctx);
> +
> + pr_info("Submitted %lu contexts to %s, filling %lu dwords\n",
> + ncontexts, engine->name, ndwords);
> +
> + ncontexts = dw = 0;
> + list_for_each_entry(obj, &objects, st_link) {
> + unsigned int rem =
> + min_t(unsigned int, ndwords - dw, max_dwords(obj));
> +
> + err = cpu_check(obj, ncontexts++, rem);
> + if (err)
> + break;
> +
> + dw += rem;
> + }
> +
> +out_unlock:
> + i915_gem_wait_for_idle(i915,
> + I915_WAIT_LOCKED,
> + MAX_SCHEDULE_TIMEOUT);
> + mutex_unlock(&i915->drm.struct_mutex);
> +
> + mock_file_free(i915, file);
> + if (err)
> + return err;
> + }
> +
> + return 0;
> +}
> +
> +static int igt_shared_ctx_exec(void *arg)
> +{
> + struct drm_i915_private *i915 = arg;
> + struct intel_engine_cs *engine;
> + enum intel_engine_id id;
> + int err = -ENODEV;
> +
> + /*
> + * Create a few different contexts with the same mm and write
> + * through each ctx using the GPU making sure those writes end
> + * up in the expected pages of our obj.
> + */
> +
> + for_each_engine(engine, i915, id) {
> + IGT_TIMEOUT(end_time);
> + LIST_HEAD(objects);
> + unsigned long ncontexts, ndwords, dw;
> + struct drm_i915_gem_object *obj = NULL;
> + struct drm_file *file;
> + struct i915_gem_context *parent;
> +
> + if (!intel_engine_can_store_dword(engine))
> + continue;
> +
> + file = mock_file(i915);
> + if (IS_ERR(file))
> + return PTR_ERR(file);
> +
> + mutex_lock(&i915->drm.struct_mutex);
> +
> + parent = i915_gem_create_context(i915, file->driver_priv,
> + CREATE_VM);
> + if (IS_ERR(parent)) {
> + err = PTR_ERR(parent);
> + if (err == -ENODEV) /* no logical ctx support */
> + err = 0;
> goto out_unlock;
> }
>
> - for_each_engine(engine, i915, id) {
> + if (!parent->ppgtt) {
> + err = 0;
> + goto out_unlock;
> + }
> +
> + ncontexts = 0;
> + ndwords = 0;
> + dw = 0;
> + while (!time_after(jiffies, end_time)) {
> + struct i915_gem_context *ctx;
> intel_wakeref_t wakeref;
>
> - if (!engine->context_size)
> - continue; /* No logical context support in HW */
> + ctx = i915_gem_create_context(i915,
> + file->driver_priv,
> + 0);
> + if (IS_ERR(ctx)) {
> + err = PTR_ERR(ctx);
> + goto out_unlock;
> + }
>
> - if (!intel_engine_can_store_dword(engine))
> - continue;
> + i915_ppgtt_open(parent->ppgtt);
> + ctx->ppgtt = i915_ppgtt_get(parent->ppgtt);
> + ctx->desc_template = parent->desc_template;
>
> if (!obj) {
> - obj = create_test_object(ctx, file, &objects);
> + obj = create_test_object(parent, file, &objects);
> if (IS_ERR(obj)) {
> err = PTR_ERR(obj);
> goto out_unlock;
> @@ -595,32 +722,36 @@ static int igt_ctx_exec(void *arg)
> obj = NULL;
> dw = 0;
> }
> +
> ndwords++;
> + ncontexts++;
> }
> - ncontexts++;
> - }
> - pr_info("Submitted %lu contexts (across %u engines), filling %lu dwords\n",
> - ncontexts, INTEL_INFO(i915)->num_rings, ndwords);
> + pr_info("Submitted %lu contexts to %s, filling %lu dwords\n",
> + ncontexts, engine->name, ndwords);
>
> - dw = 0;
> - list_for_each_entry(obj, &objects, st_link) {
> - unsigned int rem =
> - min_t(unsigned int, ndwords - dw, max_dwords(obj));
> + ncontexts = dw = 0;
> + list_for_each_entry(obj, &objects, st_link) {
> + unsigned int rem =
> + min_t(unsigned int, ndwords - dw, max_dwords(obj));
>
> - err = cpu_check(obj, rem);
> - if (err)
> - break;
> + err = cpu_check(obj, ncontexts++, rem);
> + if (err)
> + break;
>
> - dw += rem;
> - }
> + dw += rem;
> + }
>
> out_unlock:
> - if (igt_flush_test(i915, I915_WAIT_LOCKED))
> - err = -EIO;
> - mutex_unlock(&i915->drm.struct_mutex);
> + if (igt_flush_test(i915, I915_WAIT_LOCKED))
> + err = -EIO;
> + mutex_unlock(&i915->drm.struct_mutex);
>
> - mock_file_free(i915, file);
> - return err;
> + mock_file_free(i915, file);
> + if (err)
> + return err;
> + }
> +
> + return 0;
> }
>
> static int igt_ctx_readonly(void *arg)
> @@ -648,7 +779,7 @@ static int igt_ctx_readonly(void *arg)
>
> mutex_lock(&i915->drm.struct_mutex);
>
> - ctx = i915_gem_create_context(i915, file->driver_priv);
> + ctx = i915_gem_create_context(i915, file->driver_priv, 0);
> if (IS_ERR(ctx)) {
> err = PTR_ERR(ctx);
> goto out_unlock;
> @@ -714,7 +845,7 @@ static int igt_ctx_readonly(void *arg)
> if (i915_gem_object_is_readonly(obj))
> num_writes = 0;
>
> - err = cpu_check(obj, num_writes);
> + err = cpu_check(obj, 0, num_writes);
> if (err)
> break;
>
> @@ -913,6 +1044,7 @@ int i915_gem_context_live_selftests(struct drm_i915_private *dev_priv)
> SUBTEST(live_nop_switch),
> SUBTEST(igt_ctx_exec),
> SUBTEST(igt_ctx_readonly),
> + SUBTEST(igt_shared_ctx_exec),
> };
> bool fake_alias = false;
> int err;
> diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
> index 38414558e18b..0e0fc7eedba3 100644
> --- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
> @@ -1020,7 +1020,6 @@ static int exercise_ppgtt(struct drm_i915_private *dev_priv,
>
> err = func(dev_priv, &ppgtt->vm, 0, ppgtt->vm.total, end_time);
>
> - i915_ppgtt_close(&ppgtt->vm);
> i915_ppgtt_put(ppgtt);
> out_unlock:
> mutex_unlock(&dev_priv->drm.struct_mutex);
> diff --git a/drivers/gpu/drm/i915/selftests/mock_context.c b/drivers/gpu/drm/i915/selftests/mock_context.c
> index d937bdff26f9..a7511ba98342 100644
> --- a/drivers/gpu/drm/i915/selftests/mock_context.c
> +++ b/drivers/gpu/drm/i915/selftests/mock_context.c
> @@ -92,7 +92,7 @@ live_context(struct drm_i915_private *i915, struct drm_file *file)
> {
> lockdep_assert_held(&i915->drm.struct_mutex);
>
> - return i915_gem_create_context(i915, file->driver_priv);
> + return i915_gem_create_context(i915, file->driver_priv, CREATE_VM);
> }
>
> struct i915_gem_context *
> diff --git a/drivers/gpu/drm/i915/selftests/mock_gtt.c b/drivers/gpu/drm/i915/selftests/mock_gtt.c
> index 976c862b3842..e0880d2c498a 100644
> --- a/drivers/gpu/drm/i915/selftests/mock_gtt.c
> +++ b/drivers/gpu/drm/i915/selftests/mock_gtt.c
> @@ -66,6 +66,8 @@ mock_ppgtt(struct drm_i915_private *i915,
> return NULL;
>
> kref_init(&ppgtt->ref);
> + ppgtt->open_count = 1;
> +
> ppgtt->vm.i915 = i915;
> ppgtt->vm.total = round_down(U64_MAX, PAGE_SIZE);
> ppgtt->vm.file = ERR_PTR(-ENODEV);
> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> index 4fa7e54501cc..dc1c52f95cab 100644
> --- a/include/uapi/drm/i915_drm.h
> +++ b/include/uapi/drm/i915_drm.h
> @@ -386,7 +386,7 @@ typedef struct _drm_i915_sarea {
> #define DRM_IOCTL_I915_SET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey)
> #define DRM_IOCTL_I915_GET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey)
> #define DRM_IOCTL_I915_GEM_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_WAIT, struct drm_i915_gem_wait)
> -#define DRM_IOCTL_I915_GEM_CONTEXT_CREATE DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_CREATE, struct drm_i915_gem_context_create)
> +#define DRM_IOCTL_I915_GEM_CONTEXT_CREATE DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_CREATE, struct drm_i915_gem_context_create_v2)
> #define DRM_IOCTL_I915_GEM_CONTEXT_DESTROY DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_DESTROY, struct drm_i915_gem_context_destroy)
> #define DRM_IOCTL_I915_REG_READ DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_REG_READ, struct drm_i915_reg_read)
> #define DRM_IOCTL_I915_GET_RESET_STATS DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GET_RESET_STATS, struct drm_i915_reset_stats)
> @@ -1429,6 +1429,15 @@ struct drm_i915_gem_context_create {
> __u32 pad;
> };
>
> +struct drm_i915_gem_context_create_v2 {
> + /* output: id of new context*/
> + __u32 ctx_id;
> + __u32 flags;
> +#define I915_GEM_CONTEXT_SHARE_GTT 0x1
> + __u32 share_ctx;
> + __u32 pad;
> +};
Or
__u32 ctx_id;
__u32 share_ctx;
__u64 flags;
for no padding needed and double amount of flags? :)
Regards,
Tvrtko
> +
> struct drm_i915_gem_context_destroy {
> __u32 ctx_id;
> __u32 pad;
>
More information about the Intel-gfx
mailing list