[PATCH] share-gtt
Chris Wilson
chris at chris-wilson.co.uk
Thu Dec 14 15:31:12 UTC 2017
---
drivers/gpu/drm/i915/i915_gem_context.c | 63 +++++++++++++++++------
drivers/gpu/drm/i915/i915_gem_gtt.c | 4 +-
drivers/gpu/drm/i915/i915_gem_gtt.h | 1 -
drivers/gpu/drm/i915/selftests/huge_pages.c | 1 -
drivers/gpu/drm/i915/selftests/i915_gem_context.c | 4 +-
drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 1 -
drivers/gpu/drm/i915/selftests/mock_context.c | 2 +-
include/uapi/drm/i915_drm.h | 11 +++-
8 files changed, 65 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 648e7536ff51..17506d0e9895 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -109,7 +109,10 @@ 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();
}
@@ -201,8 +204,6 @@ static void context_close(struct i915_gem_context *ctx)
* the ppgtt).
*/
lut_close(ctx);
- if (ctx->ppgtt)
- i915_ppgtt_close(&ctx->ppgtt->base);
ctx->file_priv = ERR_PTR(-EBADF);
i915_gem_context_put(ctx);
@@ -338,6 +339,8 @@ static void __destroy_hw_context(struct i915_gem_context *ctx,
context_close(ctx);
}
+#define CREATE_VM BIT(0)
+
/**
* The default context needs to exist per ring that uses contexts. It stores the
* context state of the GPU for applications that don't utilize HW contexts, as
@@ -345,7 +348,8 @@ static void __destroy_hw_context(struct i915_gem_context *ctx,
*/
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;
@@ -358,7 +362,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, ctx->name);
@@ -423,7 +427,7 @@ i915_gem_context_create_kernel(struct drm_i915_private *i915, int prio)
{
struct i915_gem_context *ctx;
- ctx = i915_gem_create_context(i915, NULL);
+ ctx = i915_gem_create_context(i915, NULL, CREATE_VM);
if (IS_ERR(ctx))
return ctx;
@@ -545,7 +549,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);
@@ -642,10 +646,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 (!dev_priv->engine[RCS]->context_size)
return -ENODEV;
@@ -653,6 +659,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,
@@ -661,21 +670,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)) {
+ i915_ppgtt_get(share->ppgtt);
+ ctx->ppgtt = share->ppgtt;
+ ctx->desc_template = share->desc_template;
+ }
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 c5f393870532..2c422eed1e28 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2207,7 +2207,7 @@ i915_ppgtt_create(struct drm_i915_private *dev_priv,
return ppgtt;
}
-void i915_ppgtt_close(struct i915_address_space *vm)
+static void ppgtt_close(struct i915_address_space *vm)
{
struct list_head *phases[] = {
&vm->active_list,
@@ -2235,6 +2235,8 @@ void i915_ppgtt_release(struct kref *kref)
trace_i915_ppgtt_release(&ppgtt->base);
+ ppgtt_close(&ppgtt->base);
+
/* vmas should already be unbound and destroyed */
WARN_ON(!list_empty(&ppgtt->base.active_list));
WARN_ON(!list_empty(&ppgtt->base.inactive_list));
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index a42890d9af38..7f46ceeae9a0 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -593,7 +593,6 @@ 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,
const char *name);
-void i915_ppgtt_close(struct i915_address_space *vm);
static inline void i915_ppgtt_get(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 e6b31041cc88..d8022794f86d 100644
--- a/drivers/gpu/drm/i915/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/selftests/huge_pages.c
@@ -1712,7 +1712,6 @@ int i915_gem_huge_page_mock_selftests(void)
err = i915_subtests(tests, ppgtt);
out_close:
- i915_ppgtt_close(&ppgtt->base);
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 56a803d11916..c3351e56684e 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_context.c
@@ -357,7 +357,9 @@ static int igt_ctx_exec(void *arg)
ctx = __create_hw_context(i915, file->driver_priv);
first_shared_gtt = false;
} else {
- ctx = i915_gem_create_context(i915, file->driver_priv);
+ ctx = i915_gem_create_context(i915,
+ file->driver_priv,
+ CREATE_VM);
}
if (IS_ERR(ctx)) {
err = PTR_ERR(ctx);
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
index 4a28d713a7d8..49e38c7ac76d 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
@@ -914,7 +914,6 @@ static int exercise_ppgtt(struct drm_i915_private *dev_priv,
err = func(dev_priv, &ppgtt->base, 0, ppgtt->base.total, end_time);
- i915_ppgtt_close(&ppgtt->base);
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 bbf80d42e793..1209e41ebedb 100644
--- a/drivers/gpu/drm/i915/selftests/mock_context.c
+++ b/drivers/gpu/drm/i915/selftests/mock_context.c
@@ -90,5 +90,5 @@ 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);
}
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 536ee4febd74..3f7c9702a913 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -365,7 +365,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)
@@ -1383,6 +1383,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;
+};
+
struct drm_i915_gem_context_destroy {
__u32 ctx_id;
__u32 pad;
--
2.15.1
More information about the Intel-gfx-trybot
mailing list