[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