[Intel-gfx] [PATCH 3/3] drm/i915: s/seqno/request/ tracking inside objects
Chris Wilson
chris at chris-wilson.co.uk
Mon Aug 25 09:43:52 CEST 2014
On Sun, Aug 24, 2014 at 04:54:22PM +0100, Chris Wilson wrote:
> +static void execlists_submit(struct intel_engine_cs *engine)
> {
> - struct drm_i915_gem_object *ctx_obj0;
> - struct drm_i915_gem_object *ctx_obj1 = NULL;
> -
> - ctx_obj0 = to0->ring[engine->id].state;
> - BUG_ON(!ctx_obj0);
> - WARN_ON(!i915_gem_obj_is_pinned(ctx_obj0));
> -
> - execlists_ctx_write_tail(ctx_obj0, tail0);
> -
> - if (to1) {
> - ctx_obj1 = to1->ring[engine->id].state;
> - BUG_ON(!ctx_obj1);
> - WARN_ON(!i915_gem_obj_is_pinned(ctx_obj1));
> -
> - execlists_ctx_write_tail(ctx_obj1, tail1);
> - }
> -
> - execlists_elsp_write(engine, ctx_obj0, ctx_obj1);
> -
> - return 0;
> -}
> -
> -static void execlists_context_unqueue(struct intel_engine_cs *engine)
> -{
> - struct intel_ctx_submit_request *req0 = NULL, *req1 = NULL;
> - struct intel_ctx_submit_request *cursor = NULL, *tmp = NULL;
> - struct drm_i915_private *dev_priv = engine->dev->dev_private;
> + struct i915_gem_request *rq[2] = {};
> + int i = 0;
>
> assert_spin_locked(&engine->execlist_lock);
>
> - if (list_empty(&engine->execlist_queue))
> - return;
> -
> /* Try to read in pairs */
> - list_for_each_entry_safe(cursor, tmp, &engine->execlist_queue,
> - execlist_link) {
> - if (!req0) {
> - req0 = cursor;
> - } else if (req0->ctx == cursor->ctx) {
> + while (!list_empty(&engine->pending)) {
> + struct i915_gem_request *next;
> +
> + next = list_first_entry(&engine->pending,
> + typeof(*next),
> + engine_list);
> +
> + if (rq[i] == NULL) {
> +new_slot:
> + rq[i] = next;
> + } else if (rq[i]->ctx == next->ctx) {
> /* Same ctx: ignore first request, as second request
> * will update tail past first request's workload */
> - cursor->elsp_submitted = req0->elsp_submitted;
> - list_del(&req0->execlist_link);
> - queue_work(dev_priv->wq, &req0->work);
> - req0 = cursor;
> + rq[i] = next;
> } else {
> - req1 = cursor;
> - break;
> - }
> - }
> + if (++i == ARRAY_SIZE(rq))
> + break;
>
> - WARN_ON(req1 && req1->elsp_submitted);
> -
> - WARN_ON(execlists_submit_context(engine, req0->ctx, req0->tail,
> - req1 ? req1->ctx : NULL,
> - req1 ? req1->tail : 0));
> -
> - req0->elsp_submitted++;
> - if (req1)
> - req1->elsp_submitted++;
> -}
> -
> -static bool execlists_check_remove_request(struct intel_engine_cs *engine,
> - u32 request_id)
> -{
> - struct drm_i915_private *dev_priv = engine->dev->dev_private;
> - struct intel_ctx_submit_request *head_req;
> -
> - assert_spin_locked(&engine->execlist_lock);
> -
> - head_req = list_first_entry_or_null(&engine->execlist_queue,
> - struct intel_ctx_submit_request,
> - execlist_link);
> -
> - if (head_req != NULL) {
> - struct drm_i915_gem_object *ctx_obj =
> - head_req->ctx->ring[engine->id].state;
> - if (intel_execlists_ctx_id(ctx_obj) == request_id) {
> - WARN(head_req->elsp_submitted == 0,
> - "Never submitted head request\n");
> -
> - if (--head_req->elsp_submitted <= 0) {
> - list_del(&head_req->execlist_link);
> - queue_work(dev_priv->wq, &head_req->work);
> - return true;
> - }
> + goto new_slot;
> }
> +
> + list_move_tail(&next->engine_list, &engine->requests);
> }
Drat, this touches engine->requests in the wrong locking context. Will
need to stage the update to requests through an intermediate list to get
the locking correct.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
More information about the Intel-gfx
mailing list