@@ -890,6 +890,7 @@ struct intel_context {
bool need_status_change_notification;
struct atomic_notifier_head notifier_head;
} engine[I915_NUM_RINGS];
+ bool single_submission;
bool root_pointer_dirty;
struct list_head link;
@@ -479,6 +479,40 @@ static void execlists_i915_pick_requests(struct intel_engine_cs *ring,
}
}
+static void execlists_gvt_pick_requests(struct intel_engine_cs *ring,
+ struct drm_i915_gem_request **req0,
+ struct drm_i915_gem_request **req1)
+{
+ struct drm_i915_gem_request *cursor, *tmp;
+
+ *req0 = *req1 = NULL;
+
+ /* Try to read in pairs */
+ list_for_each_entry_safe(cursor, tmp, &ring->execlist_queue,
+ execlist_link) {
+ if (!*req0) {
+ *req0 = cursor;
+ /* single submission */
+ if ((*req0)->ctx->single_submission)
+ break;
+ } else if ((*req0)->ctx == cursor->ctx) {
+ /*
+ * Same ctx: ignore first request, as second request
+ * will update tail past first request's workload
+ */
+ cursor->elsp_submitted = (*req0)->elsp_submitted;
+ list_move_tail(&(*req0)->execlist_link,
+ &ring->execlist_retired_req_list);
+ *req0 = cursor;
+ } else {
+ /* single submission */
+ if (!cursor->ctx->single_submission)
+ *req1 = cursor;
+ break;
+ }
+ }
+}
+
static void execlists_context_unqueue(struct intel_engine_cs *ring)
{
struct drm_i915_gem_request *req0, *req1;
@@ -494,7 +528,10 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring)
if (list_empty(&ring->execlist_queue))
return;
- execlists_i915_pick_requests(ring, &req0, &req1);
+ if (!intel_gvt_active(ring->dev))
+ execlists_i915_pick_requests(ring, &req0, &req1);
+ else
+ execlists_gvt_pick_requests(ring, &req0, &req1);
if (IS_GEN8(ring->dev) || IS_GEN9(ring->dev)) {
/*
@@ -2629,6 +2666,9 @@ int __intel_lr_context_deferred_alloc(struct intel_context *ctx,
&ctx->engine[ring->id].notifier_head);
}
+ if (params->ctx_needs_single_submission)
+ ctx->single_submission = true;
+
return 0;
error_ringbuf:
@@ -107,6 +107,7 @@ struct intel_lr_context_alloc_params {
u32 ringbuffer_size;
bool ctx_needs_init;
bool ctx_needs_status_change_notification;
+ bool ctx_needs_single_submission;
};
void intel_lr_context_free(struct intel_context *ctx);
This patch introduces a new request picking logic to support the single- submission context. As GVT context may comes from different guests, which requires different configuration of render registers configuration. It can't be combined in a dual ELSP submission combo. We make this function as a context feature in context creation service. Only GVT-g will create this kinds of GEM context currently, which only allows to be single submitted. Signed-off-by: Zhi Wang <zhi.a.wang@intel.com> --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_lrc.c | 42 +++++++++++++++++++++++++++++++++++++++- drivers/gpu/drm/i915/intel_lrc.h | 1 + 3 files changed, 43 insertions(+), 1 deletion(-)