From patchwork Mon Nov 9 16:18:20 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nick Hoath X-Patchwork-Id: 7584911 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 248209F2F7 for ; Mon, 9 Nov 2015 16:19:21 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 219B7204A0 for ; Mon, 9 Nov 2015 16:19:20 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id D17DF20414 for ; Mon, 9 Nov 2015 16:19:17 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id BBF876E5B8; Mon, 9 Nov 2015 08:19:16 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by gabe.freedesktop.org (Postfix) with ESMTP id 98F026E5B8 for ; Mon, 9 Nov 2015 08:19:13 -0800 (PST) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP; 09 Nov 2015 08:18:35 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,266,1444719600"; d="scan'208";a="846792437" Received: from nthoath-linux2.isw.intel.com ([10.102.226.57]) by fmsmga002.fm.intel.com with ESMTP; 09 Nov 2015 08:18:33 -0800 From: Nick Hoath To: intel-gfx@lists.freedesktop.org Date: Mon, 9 Nov 2015 16:18:20 +0000 Message-Id: <1447085900-29407-1-git-send-email-nicholas.hoath@intel.com> X-Mailer: git-send-email 1.9.1 Cc: Daniel Vetter Subject: [Intel-gfx] [PATCH] drm/i915: Change context lifecycle 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=-4.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable 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 Use the first retired request on a new context to unpin the old context. This ensures that the hw context remains bound until it has been saved. Now that the context is pinned until later in the request/context lifecycle, it no longer needs to be pinned from context_queue to retire_requests. The refcount on the context also has to be extended to cover this new longer period. Signed-off-by: Nick Hoath Issue: VIZ-4277 Cc: Daniel Vetter Cc: David Gordon Cc: Chris Wilson Cc: Alex Dai --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem.c | 7 +++++ drivers/gpu/drm/i915/intel_lrc.c | 58 +++++++++++++++++++++++++++++++++------- drivers/gpu/drm/i915/intel_lrc.h | 1 + 4 files changed, 57 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 20cd6d8..778b14a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -884,6 +884,7 @@ struct intel_context { struct { struct drm_i915_gem_object *state; struct intel_ringbuffer *ringbuf; + bool unsaved; int pin_count; } engine[I915_NUM_RINGS]; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index f1e3fde..273946d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1385,6 +1385,13 @@ __i915_gem_request_retire__upto(struct drm_i915_gem_request *req) tmp = list_first_entry(&engine->request_list, typeof(*tmp), list); + if (i915.enable_execlists) { + unsigned long flags; + + spin_lock_irqsave(&engine->execlist_lock, flags); + intel_lr_context_complete_check(tmp); + spin_unlock_irqrestore(&engine->execlist_lock, flags); + } i915_gem_request_retire(tmp); } while (tmp != req); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 06180dc..d82e903 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -566,13 +566,17 @@ static int execlists_context_queue(struct drm_i915_gem_request *request) struct drm_i915_gem_request *cursor; int num_elements = 0; - if (request->ctx != ring->default_context) - intel_lr_context_pin(request); - i915_gem_request_reference(request); spin_lock_irq(&ring->execlist_lock); + if (request->ctx != ring->default_context) { + if (!request->ctx->engine[ring->id].unsaved) { + intel_lr_context_pin(request); + request->ctx->engine[ring->id].unsaved = true; + } + } + list_for_each_entry(cursor, &ring->execlist_queue, execlist_link) if (++num_elements > 2) break; @@ -958,12 +962,6 @@ void intel_execlists_retire_requests(struct intel_engine_cs *ring) spin_unlock_irq(&ring->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[ring->id].state; - - if (ctx_obj && (ctx != ring->default_context)) - intel_lr_context_unpin(req); list_del(&req->execlist_link); i915_gem_request_unreference(req); } @@ -1073,6 +1071,31 @@ void intel_lr_context_unpin(struct drm_i915_gem_request *rq) } } +void intel_lr_context_complete_check(struct drm_i915_gem_request *req) +{ + struct intel_engine_cs *ring = req->ring; + + assert_spin_locked(&ring->execlist_lock); + + if (ring->last_context && ring->last_context != req->ctx) { + if (req->ctx != ring->default_context + && ring->last_context->engine[ring->id].unsaved) { + /* Create fake request for unpinning the old context */ + struct drm_i915_gem_request tmp; + + tmp.ring = ring; + tmp.ctx = ring->last_context; + tmp.ringbuf = + ring->last_context->engine[ring->id].ringbuf; + + intel_lr_context_unpin(&tmp); + ring->last_context->engine[ring->id].unsaved = false; + ring->last_context = NULL; + } + } + ring->last_context = req->ctx; +} + static int intel_logical_ring_workarounds_emit(struct drm_i915_gem_request *req) { int ret, i; @@ -2390,7 +2413,22 @@ void intel_lr_context_free(struct intel_context *ctx) intel_unpin_ringbuffer_obj(ringbuf); i915_gem_object_ggtt_unpin(ctx_obj); } - WARN_ON(ctx->engine[ring->id].pin_count); + + if (ctx->engine[ring->id].unsaved) { + /** + * Create fake request for unpinning the old + * context + */ + struct drm_i915_gem_request tmp; + + tmp.ring = ring; + tmp.ctx = ctx; + tmp.ringbuf = ringbuf; + intel_lr_context_unpin(&tmp); + ctx->engine[ring->id].unsaved = false; + } + + WARN_ON(ctx->engine[i].pin_count); intel_ringbuffer_free(ringbuf); drm_gem_object_unreference(&ctx_obj->base); } diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 4e60d54..cbc42b8 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -86,6 +86,7 @@ void intel_lr_context_reset(struct drm_device *dev, struct intel_context *ctx); uint64_t intel_lr_context_descriptor(struct intel_context *ctx, struct intel_engine_cs *ring); +void intel_lr_context_complete_check(struct drm_i915_gem_request *req); /* Execlists */ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists);