[PATCH 57/87] set-engines
Chris Wilson
chris at chris-wilson.co.uk
Sat Mar 24 11:41:33 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 8e678ef7e551..7d0fa0199586 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -826,6 +826,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)
{
@@ -928,6 +1009,10 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
}
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 1ad19a39466f..36d6eb781120 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/i915_gem_context.h
@@ -59,6 +59,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;
/**
@@ -122,6 +124,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 43aa078003ff..5a80e9cfee3f 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -1486,6 +1486,8 @@ struct drm_i915_gem_context_param {
#define I915_CONTEXT_MIN_FREQUENCY(x) ((x) & 0xffffffff)
#define I915_CONTEXT_MAX_FREQUENCY(x) ((x) >> 32)
#define I915_CONTEXT_SET_FREQUENCY(min, max) ((__u64)(max) << 32 | (min))
+
+#define I915_CONTEXT_PARAM_ENGINES 0x8
__u64 value;
};
--
2.16.3
More information about the Intel-gfx-trybot
mailing list