From: Jesse Barnes <jbarnes@xxxxxxxxxxxxxxxx> Add i915_gem_context_create2_ioctl for passing flags (e.g. SVM) when creating a context. v2: check the pad on create_context v3: rebase v4: i915_dma is no more. create_gvt needs flags Cc: Daniel Vetter <daniel.vetter@xxxxxxxx> Cc: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Cc: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx> Signed-off-by: Jesse Barnes <jbarnes@xxxxxxxxxxxxxxxx> (v1) Signed-off-by: Mika Kuoppala <mika.kuoppala@xxxxxxxxx> --- drivers/gpu/drm/i915/i915_drv.c | 1 + drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_gem_context.c | 70 +++++++++++++++++++++++++++------ include/uapi/drm/i915_drm.h | 18 +++++++++ 4 files changed, 78 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 13ae340ef1f3..9fb6de90eac0 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -2566,6 +2566,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = { DRM_IOCTL_DEF_DRV(I915_GEM_USERPTR, i915_gem_userptr_ioctl, DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_GETPARAM, i915_gem_context_getparam_ioctl, DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_SETPARAM, i915_gem_context_setparam_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE2, i915_gem_context_create2_ioctl, DRM_UNLOCKED), }; static struct drm_driver driver = { diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 35caa9b2f36a..598e078418e3 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3399,6 +3399,8 @@ static inline bool i915_gem_context_is_default(const struct i915_gem_context *c) int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file); +int i915_gem_context_create2_ioctl(struct drm_device *dev, void *data, + struct drm_file *file); int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file *file); int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data, diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 35950ee46a1d..189a6c018b72 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -341,17 +341,21 @@ err_out: */ static struct i915_gem_context * i915_gem_create_context(struct drm_device *dev, - struct drm_i915_file_private *file_priv) + struct drm_i915_file_private *file_priv, u32 flags) { struct i915_gem_context *ctx; + bool create_vm = false; lockdep_assert_held(&dev->struct_mutex); + if (flags & (I915_GEM_CONTEXT_FULL_PPGTT | I915_GEM_CONTEXT_ENABLE_SVM)) + create_vm = true; + ctx = __create_hw_context(dev, file_priv); if (IS_ERR(ctx)) return ctx; - if (USES_FULL_PPGTT(dev)) { + if (create_vm) { struct i915_hw_ppgtt *ppgtt = i915_ppgtt_create(to_i915(dev), file_priv); @@ -394,7 +398,8 @@ i915_gem_context_create_gvt(struct drm_device *dev) if (ret) return ERR_PTR(ret); - ctx = i915_gem_create_context(dev, NULL); + ctx = i915_gem_create_context(dev, NULL, USES_FULL_PPGTT(dev) ? + I915_GEM_CONTEXT_FULL_PPGTT : 0); if (IS_ERR(ctx)) goto out; @@ -440,6 +445,7 @@ int i915_gem_context_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); struct i915_gem_context *ctx; + u32 flags = 0; /* Init should only be called once per module load. Eventually the * restriction on the context_disabled check can be loosened. */ @@ -472,7 +478,10 @@ int i915_gem_context_init(struct drm_device *dev) } } - ctx = i915_gem_create_context(dev, NULL); + if (USES_FULL_PPGTT(dev)) + flags |= I915_GEM_CONTEXT_FULL_PPGTT; + + ctx = i915_gem_create_context(dev, NULL, flags); if (IS_ERR(ctx)) { DRM_ERROR("Failed to create default global context (error %ld)\n", PTR_ERR(ctx)); @@ -552,7 +561,8 @@ int i915_gem_context_open(struct drm_device *dev, struct drm_file *file) idr_init(&file_priv->context_idr); mutex_lock(&dev->struct_mutex); - ctx = i915_gem_create_context(dev, file_priv); + ctx = i915_gem_create_context(dev, file_priv, USES_FULL_PPGTT(dev) ? + I915_GEM_CONTEXT_FULL_PPGTT : 0); mutex_unlock(&dev->struct_mutex); if (IS_ERR(ctx)) { @@ -974,32 +984,66 @@ static bool contexts_enabled(struct drm_device *dev) return i915.enable_execlists || to_i915(dev)->hw_context_size; } -int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) +int i915_gem_context_create2_ioctl(struct drm_device *dev, void *data, + struct drm_file *file) { - struct drm_i915_gem_context_create *args = data; + struct drm_i915_gem_context_create2 *args = data; struct drm_i915_file_private *file_priv = file->driver_priv; struct i915_gem_context *ctx; + u32 flags = args->flags; int ret; if (!contexts_enabled(dev)) return -ENODEV; - if (args->pad != 0) + if (flags & ~(I915_GEM_CONTEXT_FULL_PPGTT | + I915_GEM_CONTEXT_ENABLE_SVM)) return -EINVAL; ret = i915_mutex_lock_interruptible(dev); if (ret) return ret; - ctx = i915_gem_create_context(dev, file_priv); - mutex_unlock(&dev->struct_mutex); - if (IS_ERR(ctx)) - return PTR_ERR(ctx); + if (USES_FULL_PPGTT(dev)) + flags |= I915_GEM_CONTEXT_FULL_PPGTT; + + if (flags & I915_GEM_CONTEXT_ENABLE_SVM) { + ret = -ENODEV; + goto unlock; + } + + ctx = i915_gem_create_context(dev, file_priv, flags); + if (IS_ERR(ctx)) { + ret = PTR_ERR(ctx); + goto unlock; + } args->ctx_id = ctx->user_handle; DRM_DEBUG_DRIVER("HW context %d created\n", args->ctx_id); +unlock: + mutex_unlock(&dev->struct_mutex); + return ret; +} + +int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, + struct drm_file *file) +{ + struct drm_i915_gem_context_create *args = data; + struct drm_i915_gem_context_create2 tmp; + int ret; + + if (args->pad != 0) + return -EINVAL; + + tmp.flags = 0; + + ret = i915_gem_context_create2_ioctl(dev, &tmp, file); + if (ret) + return ret; + + args->ctx_id = tmp.ctx_id; + return 0; } diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index 452629de7a57..639ef5b0e2c9 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -258,6 +258,7 @@ typedef struct _drm_i915_sarea { #define DRM_I915_GEM_USERPTR 0x33 #define DRM_I915_GEM_CONTEXT_GETPARAM 0x34 #define DRM_I915_GEM_CONTEXT_SETPARAM 0x35 +#define DRM_I915_GEM_CONTEXT_CREATE2 0x36 #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) @@ -311,6 +312,7 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_GEM_USERPTR DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_USERPTR, struct drm_i915_gem_userptr) #define DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_GETPARAM, struct drm_i915_gem_context_param) #define DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_SETPARAM, struct drm_i915_gem_context_param) +#define DRM_IOCTL_I915_GEM_CONTEXT_CREATE2 DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_CREATE2, struct drm_i915_gem_context_create2) /* Allow drivers to submit batchbuffers directly to hardware, relying * on the security mechanisms provided by hardware. @@ -1142,6 +1144,22 @@ struct drm_i915_gem_context_create { __u32 pad; }; +/* + * SVM handling + * + * A context can opt in to SVM support (thereby using its CPU page tables + * when accessing data from the GPU) by using the %I915_ENABLE_SVM flag + * and passing an existing context id. This is a one way transition; SVM + * contexts can not be downgraded into PPGTT contexts once converted. + */ +#define I915_GEM_CONTEXT_ENABLE_SVM (1<<0) +#define I915_GEM_CONTEXT_FULL_PPGTT (1<<1) +struct drm_i915_gem_context_create2 { + /* output: id of new context*/ + __u32 ctx_id; + __u32 flags; +}; + struct drm_i915_gem_context_destroy { __u32 ctx_id; __u32 pad; -- 2.7.4 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx