From patchwork Tue Apr 19 09:55:48 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 8878471 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 43E909F1D3 for ; Tue, 19 Apr 2016 09:56:02 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0969020211 for ; Tue, 19 Apr 2016 09:56:01 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id A278A20138 for ; Tue, 19 Apr 2016 09:55:59 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id DC9846E6EE; Tue, 19 Apr 2016 09:55:58 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-wm0-x243.google.com (mail-wm0-x243.google.com [IPv6:2a00:1450:400c:c09::243]) by gabe.freedesktop.org (Postfix) with ESMTPS id 62DF16E6EE for ; Tue, 19 Apr 2016 09:55:56 +0000 (UTC) Received: by mail-wm0-x243.google.com with SMTP id e201so1552647wme.2 for ; Tue, 19 Apr 2016 02:55:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=y3syu7YJ366vdfFg2bjWyw+Q2LjwH5ReOSP36ixffwg=; b=O8DyKtJ05HX3xHb3g3oGA5/ZaZIYYtgBTO0i62YMHbtaHeoDMIkZMf6w6w0g4eRQdh Ju65VXReM8UgkBx2dmRRyDfjgHG2H8JnLzsRp89lrNiR2V1XDw+oSzFLCnHnyIPrHbxL yfqqaRv9ebYJzYYCQTRF4P6hArE09mhdZGlO6oIVKS3Uu6hdNz6tNn/+EPILih6srSrh AyQsnp7zBZfhGcQXMoAboiHa8NHzO+JHf5zTgHIuFUczD6uRMnP+RkPRN88r5s5Ckfp9 c2Lng7+bsbmUAdvQYOybjFZJDTq07YnAyen95yra7CDq+XQYkZuC80aRrntpdK1fjWt/ S7Cw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=y3syu7YJ366vdfFg2bjWyw+Q2LjwH5ReOSP36ixffwg=; b=e/foGTF6xHTwcA9s7j56GFJMz03tJVou5XuWLHQuSN30MF1pKSEYRTElvv6HJ91iFf ZOks2D0wlTY0YDQfLx8wAgbIoIdXlsxkVHlgAv9bhtYfBnvOQkP02tpDqo1lrGpeyQLa Lifk5Yl/7riN7PeCUDXD9fYMFGeZnT5jJcTKAVGvQhxGsk346qi6DPLtURlHx0JaFfFF e6q9ZvE5MrUNeAZmaPHRxFusGPcaGKZfwXv0u+TqqdCdIBLXFHvaypcMbd3uthGihw1A 65f8sfuhoUoZH59e+kegxkvABTyUcFv7/VaTZweT+7l8L9S6etTHqsrd6qjHS6B4HTNw zhiw== X-Gm-Message-State: AOPr4FXaatn8fclMo7PK31Lw1Qaodvzx3ZCrSTdOUUFCTBMaA+GAH6IcbMx869isfNjHcw== X-Received: by 10.28.21.75 with SMTP id 72mr22437183wmv.64.1461059754818; Tue, 19 Apr 2016 02:55:54 -0700 (PDT) Received: from haswell.alporthouse.com ([78.156.65.138]) by smtp.gmail.com with ESMTPSA id b135sm3419912wmb.10.2016.04.19.02.55.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 19 Apr 2016 02:55:53 -0700 (PDT) From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Tue, 19 Apr 2016 10:55:48 +0100 Message-Id: <1461059748-27574-1-git-send-email-chris@chris-wilson.co.uk> X-Mailer: git-send-email 2.8.0.rc3 In-Reply-To: <5715F76D.4010002@linux.intel.com> References: <5715F76D.4010002@linux.intel.com> Subject: [Intel-gfx] [PATCH] drm/i915: Refactor execlists default context pinning X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-5.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Refactor pinning and unpinning of contexts, such that the default context for an engine is pinned during initialisation and unpinned during teardown (pinning of the context handles the reference counting). Thus we can eliminate the special case handling of the default context that was required to mask that it was not being pinned normally. v2: Rebalance context_queue after rebasing. v3: Rebase to -nightly (not 40 patches in) Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin --- drivers/gpu/drm/i915/i915_debugfs.c | 5 +- drivers/gpu/drm/i915/i915_gem.c | 2 +- drivers/gpu/drm/i915/intel_lrc.c | 107 ++++++++++++++---------------------- 3 files changed, 43 insertions(+), 71 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index f775451bd0b6..e81a7504656e 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2095,9 +2095,8 @@ static int i915_dump_lrc(struct seq_file *m, void *unused) return ret; list_for_each_entry(ctx, &dev_priv->context_list, link) - if (ctx != dev_priv->kernel_context) - for_each_engine(engine, dev_priv) - i915_dump_lrc_obj(m, ctx, engine); + for_each_engine(engine, dev_priv) + i915_dump_lrc_obj(m, ctx, engine); mutex_unlock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6ce2c31b9a81..9ff73bf0e4ea 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2719,7 +2719,7 @@ void i915_gem_request_free(struct kref *req_ref) i915_gem_request_remove_from_client(req); if (ctx) { - if (i915.enable_execlists && ctx != req->i915->kernel_context) + if (i915.enable_execlists) intel_lr_context_unpin(ctx, req->engine); i915_gem_context_unreference(ctx); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index dedd82aea386..e064a6ae2d97 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -588,9 +588,7 @@ static void execlists_context_queue(struct drm_i915_gem_request *request) struct drm_i915_gem_request *cursor; int num_elements = 0; - if (request->ctx != request->i915->kernel_context) - intel_lr_context_pin(request->ctx, engine); - + intel_lr_context_pin(request->ctx, request->engine); i915_gem_request_reference(request); spin_lock_bh(&engine->execlist_lock); @@ -691,10 +689,7 @@ int intel_logical_ring_alloc_request_extras(struct drm_i915_gem_request *request return ret; } - if (request->ctx != request->i915->kernel_context) - ret = intel_lr_context_pin(request->ctx, request->engine); - - return ret; + return intel_lr_context_pin(request->ctx, request->engine); } static int logical_ring_wait_for_space(struct drm_i915_gem_request *req, @@ -774,12 +769,8 @@ intel_logical_ring_advance_and_submit(struct drm_i915_gem_request *request) if (engine->last_context != request->ctx) { if (engine->last_context) intel_lr_context_unpin(engine->last_context, engine); - if (request->ctx != request->i915->kernel_context) { - intel_lr_context_pin(request->ctx, engine); - engine->last_context = request->ctx; - } else { - engine->last_context = NULL; - } + intel_lr_context_pin(request->ctx, engine); + engine->last_context = request->ctx; } if (dev_priv->guc.execbuf_client) @@ -1002,12 +993,7 @@ void intel_execlists_retire_requests(struct intel_engine_cs *engine) spin_unlock_bh(&engine->execlist_lock); list_for_each_entry_safe(req, tmp, &retired_list, execlist_link) { - struct intel_context *ctx = req->ctx; - struct drm_i915_gem_object *ctx_obj = - ctx->engine[engine->id].state; - - if (ctx_obj && (ctx != req->i915->kernel_context)) - intel_lr_context_unpin(ctx, engine); + intel_lr_context_unpin(req->ctx, engine); list_del(&req->execlist_link); i915_gem_request_unreference(req); @@ -1052,23 +1038,26 @@ int logical_ring_flush_all_caches(struct drm_i915_gem_request *req) return 0; } -static int intel_lr_context_do_pin(struct intel_context *ctx, - struct intel_engine_cs *engine) +static int intel_lr_context_pin(struct intel_context *ctx, + struct intel_engine_cs *engine) { - struct drm_device *dev = engine->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *ctx_obj = ctx->engine[engine->id].state; - struct intel_ringbuffer *ringbuf = ctx->engine[engine->id].ringbuf; + struct drm_i915_private *dev_priv = ctx->i915; + struct drm_i915_gem_object *ctx_obj; + struct intel_ringbuffer *ringbuf; void *vaddr; u32 *lrc_reg_state; int ret; - WARN_ON(!mutex_is_locked(&engine->dev->struct_mutex)); + lockdep_assert_held(&ctx->i915->dev->struct_mutex); + if (ctx->engine[engine->id].pin_count++) + return 0; + + ctx_obj = ctx->engine[engine->id].state; ret = i915_gem_obj_ggtt_pin(ctx_obj, GEN8_LR_CONTEXT_ALIGN, PIN_OFFSET_BIAS | GUC_WOPCM_TOP); if (ret) - return ret; + goto err; vaddr = i915_gem_object_pin_map(ctx_obj); if (IS_ERR(vaddr)) { @@ -1078,10 +1067,12 @@ static int intel_lr_context_do_pin(struct intel_context *ctx, lrc_reg_state = vaddr + LRC_STATE_PN * PAGE_SIZE; + ringbuf = ctx->engine[engine->id].ringbuf; ret = intel_pin_and_map_ringbuffer_obj(engine->dev, ringbuf); if (ret) goto unpin_map; + i915_gem_context_reference(ctx); ctx->engine[engine->id].lrc_vma = i915_gem_obj_to_ggtt(ctx_obj); intel_lr_context_descriptor_update(ctx, engine); lrc_reg_state[CTX_RING_BUFFER_START+1] = ringbuf->vma->node.start; @@ -1092,51 +1083,39 @@ static int intel_lr_context_do_pin(struct intel_context *ctx, if (i915.enable_guc_submission) I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE); - return ret; + return 0; unpin_map: i915_gem_object_unpin_map(ctx_obj); unpin_ctx_obj: i915_gem_object_ggtt_unpin(ctx_obj); - +err: + ctx->engine[engine->id].pin_count = 0; return ret; } -static int intel_lr_context_pin(struct intel_context *ctx, - struct intel_engine_cs *engine) +void intel_lr_context_unpin(struct intel_context *ctx, + struct intel_engine_cs *engine) { - int ret = 0; + struct drm_i915_gem_object *ctx_obj; - if (ctx->engine[engine->id].pin_count++ == 0) { - ret = intel_lr_context_do_pin(ctx, engine); - if (ret) - goto reset_pin_count; + lockdep_assert_held(&ctx->i915->dev->struct_mutex); + GEM_BUG_ON(ctx->engine[engine->id].pin_count == 0); - i915_gem_context_reference(ctx); - } - return ret; + if (--ctx->engine[engine->id].pin_count) + return; -reset_pin_count: - ctx->engine[engine->id].pin_count = 0; - return ret; -} + intel_unpin_ringbuffer_obj(ctx->engine[engine->id].ringbuf); -void intel_lr_context_unpin(struct intel_context *ctx, - struct intel_engine_cs *engine) -{ - struct drm_i915_gem_object *ctx_obj = ctx->engine[engine->id].state; + ctx_obj = ctx->engine[engine->id].state; + i915_gem_object_unpin_map(ctx_obj); + i915_gem_object_ggtt_unpin(ctx_obj); - WARN_ON(!mutex_is_locked(&ctx->i915->dev->struct_mutex)); - if (--ctx->engine[engine->id].pin_count == 0) { - i915_gem_object_unpin_map(ctx_obj); - intel_unpin_ringbuffer_obj(ctx->engine[engine->id].ringbuf); - i915_gem_object_ggtt_unpin(ctx_obj); - ctx->engine[engine->id].lrc_vma = NULL; - ctx->engine[engine->id].lrc_desc = 0; - ctx->engine[engine->id].lrc_reg_state = NULL; + ctx->engine[engine->id].lrc_vma = NULL; + ctx->engine[engine->id].lrc_desc = 0; + ctx->engine[engine->id].lrc_reg_state = NULL; - i915_gem_context_unreference(ctx); - } + i915_gem_context_unreference(ctx); } static int intel_logical_ring_workarounds_emit(struct drm_i915_gem_request *req) @@ -2034,6 +2013,7 @@ void intel_logical_ring_cleanup(struct intel_engine_cs *engine) i915_gem_object_unpin_map(engine->status_page.obj); engine->status_page.obj = NULL; } + intel_lr_context_unpin(dev_priv->kernel_context, engine); engine->idle_lite_restore_wa = 0; engine->disable_lite_restore_wa = false; @@ -2137,11 +2117,10 @@ logical_ring_init(struct drm_device *dev, struct intel_engine_cs *engine) goto error; /* As this is the default context, always pin it */ - ret = intel_lr_context_do_pin(dctx, engine); + ret = intel_lr_context_pin(dctx, engine); if (ret) { - DRM_ERROR( - "Failed to pin and map ringbuffer %s: %d\n", - engine->name, ret); + DRM_ERROR("Failed to pin context for %s: %d\n", + engine->name, ret); goto error; } @@ -2562,12 +2541,6 @@ void intel_lr_context_free(struct intel_context *ctx) if (!ctx_obj) continue; - if (ctx == ctx->i915->kernel_context) { - intel_unpin_ringbuffer_obj(ringbuf); - i915_gem_object_ggtt_unpin(ctx_obj); - i915_gem_object_unpin_map(ctx_obj); - } - WARN_ON(ctx->engine[i].pin_count); intel_ringbuffer_free(ringbuf); drm_gem_object_unreference(&ctx_obj->base);