[PATCH 74/98] set-engines
Chris Wilson
chris at chris-wilson.co.uk
Fri Apr 27 11:10:57 UTC 2018
---
drivers/gpu/drm/i915/i915_gem_context.c | 85 +++++++++++++++++++++++++
drivers/gpu/drm/i915/i915_gem_context.h | 4 ++
include/uapi/drm/i915_drm.h | 2 +
3 files changed, 91 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 75fe20bbfb27..7fdce68decc0 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -836,6 +836,87 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
return ret;
}
+static struct intel_engine_cs *lookup_engine(struct drm_i915_private *i915,
+ unsigned int class,
+ unsigned int instance)
+{
+ return NULL;
+}
+
+static int set_engines(struct i915_gem_context *ctx,
+ struct drm_i915_gem_context_param *args)
+{
+ u64 __user *uengine;
+ struct intel_engine_cs **engines;
+ int nengine, n;
+
+ /*
+ * For single timeline queues, we allow the user to trim the set
+ * of engines, and to ask the kernel to load balance across the set.
+ */
+ if (!ctx->timeline)
+ return -EINVAL;
+
+ if (args->size == 0)
+ return -EINVAL;
+
+ if (args->size % sizeof(*uengine))
+ return -EINVAL;
+
+ if (args->size >= 64 * sizeof(*uengine))
+ return -EINVAL;
+
+ nengine = args->size / sizeof(*uengine);
+ uengine = u64_to_user_ptr(args->value);
+
+ engines = kmalloc_array(nengine, sizeof(*engines), GFP_KERNEL);
+ if (!engines)
+ return -ENOMEM;
+
+ for (n = 0; n < nengine; n++) {
+ u64 uabi_class_instance;
+
+ if (get_user(uabi_class_instance, &uengine[n])) {
+ kfree(engines);
+ return -EFAULT;
+ }
+
+ engines[n] = lookup_engine(ctx->i915,
+ upper_32_bits(uabi_class_instance),
+ lower_32_bits(uabi_class_instance));
+ if (!engines[n]) {
+ kfree(engines);
+ return -ENOENT;
+ }
+ }
+
+ kfree(ctx->engines);
+ ctx->engines = engines;
+ ctx->nengine = nengine;
+
+ /*
+ * Then in execbuf
+ *
+ * if (ctx->engine) {
+ * int id = args->flags & 63;
+ *
+ * // load balance by default
+ *
+ * if (id) {
+ * if (id >= ctx->nengine)
+ * return -EINVAL;
+ *
+ * engine = ctx->engines[id - 1];
+ * } else {
+ * engine = load_balance(ctx->engines, ctx->nengine);
+ * }
+ * }
+ *
+ */
+
+ return 0;
+}
+
int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
struct drm_file *file)
{
@@ -952,6 +1033,10 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
ctx->preempt_timeout = args->value;
break;
+ case I915_CONTEXT_PARAM_ENGINES:
+ ret = set_engines(ctx, args);
+ break;
+
default:
ret = -EINVAL;
break;
diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h
index b4f60c918e19..78d451f9d44d 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/i915_gem_context.h
@@ -64,6 +64,8 @@ struct i915_gem_context {
/** file_priv: owning file descriptor */
struct drm_i915_file_private *file_priv;
+ struct intel_engine_cs **engines;
+
struct i915_timeline *timeline;
/**
@@ -127,6 +129,8 @@ struct i915_gem_context {
#define CONTEXT_BANNED 4
#define CONTEXT_FORCE_SINGLE_SUBMISSION 5
+ unsigned int nengine;
+
/**
* @hw_id: - unique identifier for the context
*
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 9110295a8ebc..fa568a2f6fe3 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -1499,6 +1499,8 @@ struct drm_i915_gem_context_param {
#define I915_CONTEXT_MAX_FREQUENCY(x) ((x) >> 32)
#define I915_CONTEXT_SET_FREQUENCY(min, max) ((__u64)(max) << 32 | (min))
+#define I915_CONTEXT_PARAM_ENGINES 0x9
+
__u64 value;
};
--
2.17.0
More information about the Intel-gfx-trybot
mailing list