It can be useful to have a single ioctl to create a context with all
the initial parameters instead of a series of create + setparam + setparam
ioctls. This extension to create context allows any of the parameters
to be passed in as a linked list to be applied to the newly constructed
context.

Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_drv.c         |   2 +-
 drivers/gpu/drm/i915/i915_gem_context.c | 172 +++++++++++++++---------
 include/uapi/drm/i915_drm.h             |  50 ++++---
 3 files changed, 137 insertions(+), 87 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 56bd087f1c4e..bab0d45dd7ab 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2992,7 +2992,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
        DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_COLORKEY, 
intel_sprite_set_colorkey_ioctl, DRM_MASTER),
        DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_COLORKEY, drm_noop, DRM_MASTER),
        DRM_IOCTL_DEF_DRV(I915_GEM_WAIT, i915_gem_wait_ioctl, 
DRM_AUTH|DRM_RENDER_ALLOW),
-       DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE, 
i915_gem_context_create_ioctl, DRM_RENDER_ALLOW),
+       DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE_EXT, 
i915_gem_context_create_ioctl, DRM_RENDER_ALLOW),
        DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_DESTROY, 
i915_gem_context_destroy_ioctl, DRM_RENDER_ALLOW),
        DRM_IOCTL_DEF_DRV(I915_REG_READ, i915_reg_read_ioctl, DRM_RENDER_ALLOW),
        DRM_IOCTL_DEF_DRV(I915_GET_RESET_STATS, 
i915_gem_context_reset_stats_ioctl, DRM_RENDER_ALLOW),
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c 
b/drivers/gpu/drm/i915/i915_gem_context.c
index f707241dbc78..ec5e3e1c6402 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -86,9 +86,12 @@
  */
 
 #include <linux/log2.h>
+
 #include <drm/i915_drm.h>
+
 #include "i915_drv.h"
 #include "i915_trace.h"
+#include "i915_user_extensions.h"
 #include "intel_workarounds.h"
 
 #define ALL_L3_SLICES(dev) (1 << NUM_L3_SLICES(dev)) - 1
@@ -884,6 +887,94 @@ static int set_ppgtt(struct i915_gem_context *ctx, u32 id)
        return err;
 }
 
+static int ctx_setparam(struct i915_gem_context *ctx,
+                       const struct drm_i915_gem_context_param *args)
+{
+       int ret = 0;
+
+       switch (args->param) {
+       case I915_CONTEXT_PARAM_NO_ZEROMAP:
+               if (args->size)
+                       ret = -EINVAL;
+               else if (args->value)
+                       set_bit(UCONTEXT_NO_ZEROMAP, &ctx->user_flags);
+               else
+                       clear_bit(UCONTEXT_NO_ZEROMAP, &ctx->user_flags);
+               break;
+
+       case I915_CONTEXT_PARAM_NO_ERROR_CAPTURE:
+               if (args->size)
+                       ret = -EINVAL;
+               else if (args->value)
+                       i915_gem_context_set_no_error_capture(ctx);
+               else
+                       i915_gem_context_clear_no_error_capture(ctx);
+               break;
+
+       case I915_CONTEXT_PARAM_BANNABLE:
+               if (args->size)
+                       ret = -EINVAL;
+               else if (!capable(CAP_SYS_ADMIN) && !args->value)
+                       ret = -EPERM;
+               else if (args->value)
+                       i915_gem_context_set_bannable(ctx);
+               else
+                       i915_gem_context_clear_bannable(ctx);
+               break;
+
+       case I915_CONTEXT_PARAM_PRIORITY:
+               {
+                       s64 priority = args->value;
+
+                       if (args->size)
+                               ret = -EINVAL;
+                       else if (!(ctx->i915->caps.scheduler & 
I915_SCHEDULER_CAP_PRIORITY))
+                               ret = -ENODEV;
+                       else if (priority > I915_CONTEXT_MAX_USER_PRIORITY ||
+                                priority < I915_CONTEXT_MIN_USER_PRIORITY)
+                               ret = -EINVAL;
+                       else if (priority > I915_CONTEXT_DEFAULT_PRIORITY &&
+                                !capable(CAP_SYS_NICE))
+                               ret = -EPERM;
+                       else
+                               ctx->sched.priority =
+                                       I915_USER_PRIORITY(priority);
+               }
+               break;
+
+       case I915_CONTEXT_PARAM_VM:
+               if (args->size)
+                       ret = -EINVAL;
+               else if (upper_32_bits(args->value))
+                       ret = -EINVAL;
+               else
+                       ret = set_ppgtt(ctx, lower_32_bits(args->value));
+               break;
+
+       case I915_CONTEXT_PARAM_BAN_PERIOD:
+       default:
+               ret = -EINVAL;
+               break;
+       }
+
+       return ret;
+}
+
+static int create_setparam(struct i915_user_extension *ext, void *data)
+{
+       const struct drm_i915_gem_context_create_ext_setparam *args =
+               container_of(ext, typeof(*args), base);
+
+       if (args->setparam.ctx_id)
+               return -EINVAL;
+
+       return ctx_setparam(data, &args->setparam);
+}
+
+static const i915_user_extension_fn create_extensions[] = {
+       [I915_CONTEXT_CREATE_EXT_SETPARAM] = create_setparam,
+};
+
 static bool client_is_banned(struct drm_i915_file_private *file_priv)
 {
        return atomic_read(&file_priv->ban_score) >= I915_CLIENT_SCORE_BANNED;
@@ -893,7 +984,7 @@ 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_ext *args = data;
        struct drm_i915_file_private *file_priv = file->driver_priv;
        struct i915_gem_context *ctx;
        int ret;
@@ -901,7 +992,7 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, 
void *data,
        if (!DRIVER_CAPS(dev_priv)->has_logical_contexts)
                return -ENODEV;
 
-       if (args->pad != 0)
+       if (args->flags)
                return -EINVAL;
 
        if (client_is_banned(file_priv)) {
@@ -923,6 +1014,16 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, 
void *data,
 
        GEM_BUG_ON(i915_gem_context_is_kernel(ctx));
 
+       ret = i915_user_extensions(u64_to_user_ptr(args->extensions),
+                                  create_extensions,
+                                  ARRAY_SIZE(create_extensions),
+                                  ctx);
+       if (ret) {
+               idr_remove(&file_priv->context_idr, ctx->user_handle);
+               context_close(ctx);
+               return ret;
+       }
+
        args->ctx_id = ctx->user_handle;
        DRM_DEBUG("HW context %d created\n", args->ctx_id);
 
@@ -1014,76 +1115,13 @@ int i915_gem_context_setparam_ioctl(struct drm_device 
*dev, void *data,
        struct drm_i915_file_private *file_priv = file->driver_priv;
        struct drm_i915_gem_context_param *args = data;
        struct i915_gem_context *ctx;
-       int ret = 0;
+       int ret;
 
        ctx = i915_gem_context_lookup(file_priv, args->ctx_id);
        if (!ctx)
                return -ENOENT;
 
-       switch (args->param) {
-       case I915_CONTEXT_PARAM_BAN_PERIOD:
-               ret = -EINVAL;
-               break;
-       case I915_CONTEXT_PARAM_NO_ZEROMAP:
-               if (args->size)
-                       ret = -EINVAL;
-               else if (args->value)
-                       set_bit(UCONTEXT_NO_ZEROMAP, &ctx->user_flags);
-               else
-                       clear_bit(UCONTEXT_NO_ZEROMAP, &ctx->user_flags);
-               break;
-       case I915_CONTEXT_PARAM_NO_ERROR_CAPTURE:
-               if (args->size)
-                       ret = -EINVAL;
-               else if (args->value)
-                       i915_gem_context_set_no_error_capture(ctx);
-               else
-                       i915_gem_context_clear_no_error_capture(ctx);
-               break;
-       case I915_CONTEXT_PARAM_BANNABLE:
-               if (args->size)
-                       ret = -EINVAL;
-               else if (!capable(CAP_SYS_ADMIN) && !args->value)
-                       ret = -EPERM;
-               else if (args->value)
-                       i915_gem_context_set_bannable(ctx);
-               else
-                       i915_gem_context_clear_bannable(ctx);
-               break;
-
-       case I915_CONTEXT_PARAM_PRIORITY:
-               {
-                       s64 priority = args->value;
-
-                       if (args->size)
-                               ret = -EINVAL;
-                       else if (!(to_i915(dev)->caps.scheduler & 
I915_SCHEDULER_CAP_PRIORITY))
-                               ret = -ENODEV;
-                       else if (priority > I915_CONTEXT_MAX_USER_PRIORITY ||
-                                priority < I915_CONTEXT_MIN_USER_PRIORITY)
-                               ret = -EINVAL;
-                       else if (priority > I915_CONTEXT_DEFAULT_PRIORITY &&
-                                !capable(CAP_SYS_NICE))
-                               ret = -EPERM;
-                       else
-                               ctx->sched.priority =
-                                       I915_USER_PRIORITY(priority);
-               }
-               break;
-
-       case I915_CONTEXT_PARAM_VM:
-               if (args->size)
-                       ret = -EINVAL;
-               else if (upper_32_bits(args->value))
-                       ret = -EINVAL;
-               else
-                       ret = set_ppgtt(ctx, lower_32_bits(args->value));
-               break;
-
-       default:
-               ret = -EINVAL;
-               break;
-       }
+       ret = ctx_setparam(ctx, args);
 
        i915_gem_context_put(ctx);
        return ret;
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index eb19cf8a77ef..704e9d2fe2d6 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -389,6 +389,7 @@ typedef struct _drm_i915_sarea {
 #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_EXT  DRM_IOWR (DRM_COMMAND_BASE + 
DRM_I915_GEM_CONTEXT_CREATE, struct drm_i915_gem_context_create_ext)
 #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)
@@ -1436,11 +1437,39 @@ struct drm_i915_gem_wait {
 };
 
 struct drm_i915_gem_context_create {
-       /*  output: id of new context*/
-       __u32 ctx_id;
+       __u32 ctx_id; /* output: id of new context*/
        __u32 pad;
 };
 
+struct drm_i915_gem_context_create_ext {
+       __u32 ctx_id; /* output: id of new context*/
+       __u32 flags;
+       __u64 extensions;
+};
+
+struct drm_i915_gem_context_param {
+       __u32 ctx_id;
+       __u32 size;
+       __u64 param;
+#define I915_CONTEXT_PARAM_BAN_PERIOD  0x1
+#define I915_CONTEXT_PARAM_NO_ZEROMAP  0x2
+#define I915_CONTEXT_PARAM_GTT_SIZE    0x3
+#define I915_CONTEXT_PARAM_NO_ERROR_CAPTURE    0x4
+#define I915_CONTEXT_PARAM_BANNABLE    0x5
+#define I915_CONTEXT_PARAM_PRIORITY    0x6
+#define   I915_CONTEXT_MAX_USER_PRIORITY       1023 /* inclusive */
+#define   I915_CONTEXT_DEFAULT_PRIORITY                0
+#define   I915_CONTEXT_MIN_USER_PRIORITY       -1023 /* inclusive */
+#define I915_CONTEXT_PARAM_VM          0x7
+       __u64 value;
+};
+
+struct drm_i915_gem_context_create_ext_setparam {
+#define I915_CONTEXT_CREATE_EXT_SETPARAM 0
+       struct i915_user_extension base;
+       struct drm_i915_gem_context_param setparam;
+};
+
 struct drm_i915_gem_context_destroy {
        __u32 ctx_id;
        __u32 pad;
@@ -1503,23 +1532,6 @@ struct drm_i915_gem_userptr {
        __u32 handle;
 };
 
-struct drm_i915_gem_context_param {
-       __u32 ctx_id;
-       __u32 size;
-       __u64 param;
-#define I915_CONTEXT_PARAM_BAN_PERIOD  0x1
-#define I915_CONTEXT_PARAM_NO_ZEROMAP  0x2
-#define I915_CONTEXT_PARAM_GTT_SIZE    0x3
-#define I915_CONTEXT_PARAM_NO_ERROR_CAPTURE    0x4
-#define I915_CONTEXT_PARAM_BANNABLE    0x5
-#define I915_CONTEXT_PARAM_PRIORITY    0x6
-#define   I915_CONTEXT_MAX_USER_PRIORITY       1023 /* inclusive */
-#define   I915_CONTEXT_DEFAULT_PRIORITY                0
-#define   I915_CONTEXT_MIN_USER_PRIORITY       -1023 /* inclusive */
-#define I915_CONTEXT_PARAM_VM          0x7
-       __u64 value;
-};
-
 enum drm_i915_oa_format {
        I915_OA_FORMAT_A13 = 1,     /* HSW only */
        I915_OA_FORMAT_A29,         /* HSW only */
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to