From patchwork Tue Oct 6 14:52:02 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nick Hoath X-Patchwork-Id: 7335421 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 43BB6BEEA4 for ; Tue, 6 Oct 2015 14:52:39 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 24DA320723 for ; Tue, 6 Oct 2015 14:52:37 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id D99812071A for ; Tue, 6 Oct 2015 14:52:35 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C2B326EA17; Tue, 6 Oct 2015 07:52:34 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTP id 9336F6E1FE for ; Tue, 6 Oct 2015 07:52:33 -0700 (PDT) Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP; 06 Oct 2015 07:52:30 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,644,1437462000"; d="scan'208";a="658896845" Received: from nthoath-linux2.isw.intel.com ([10.102.226.45]) by orsmga003.jf.intel.com with ESMTP; 06 Oct 2015 07:52:29 -0700 From: Nick Hoath To: intel-gfx@lists.freedesktop.org Date: Tue, 6 Oct 2015 15:52:02 +0100 Message-Id: <1444143124-16030-3-git-send-email-nicholas.hoath@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1444143124-16030-1-git-send-email-nicholas.hoath@intel.com> References: <1444143124-16030-1-git-send-email-nicholas.hoath@intel.com> Subject: [Intel-gfx] [PATCH 2/4] drm/i915: Improve dynamic management/eviction of lrc backing objects 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.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_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 Shovel all context related objects through the active queue and obj management. - Added callback in vma_(un)bind to add CPU (un)mapping at same time if desired - Inserted LRC hw context & ringbuf to vma active list Issue: VIZ-4277 Signed-off-by: Nick Hoath --- drivers/gpu/drm/i915/i915_drv.h | 4 ++ drivers/gpu/drm/i915/i915_gem.c | 3 ++ drivers/gpu/drm/i915/i915_gem_gtt.c | 8 ++++ drivers/gpu/drm/i915/intel_lrc.c | 28 +++++++++++-- drivers/gpu/drm/i915/intel_ringbuffer.c | 71 ++++++++++++++++++--------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 3 -- 6 files changed, 79 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 3d217f9..d660ee3 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2169,6 +2169,10 @@ struct drm_i915_gem_object { struct work_struct *work; } userptr; }; + + /** Support for automatic CPU side mapping of object */ + int (*mmap)(struct drm_i915_gem_object *obj, bool unmap); + void *mappable; }; #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index fc82171..56e0e00 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3262,6 +3262,9 @@ static int __i915_vma_unbind(struct i915_vma *vma, bool wait) if (vma->pin_count) return -EBUSY; + if (obj->mmap) + obj->mmap(obj, true); + BUG_ON(obj->pages == NULL); if (wait) { diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 620d57e..786ec4b 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -3495,6 +3495,14 @@ int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level, vma->bound |= bind_flags; + if (vma->obj->mmap) { + ret = vma->obj->mmap(vma->obj, false); + if (ret) { + i915_vma_unbind(vma); + return ret; + } + } + return 0; } diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index e8f5b6c..b807928 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -723,6 +723,18 @@ intel_logical_ring_advance_and_submit(struct drm_i915_gem_request *request) intel_logical_ring_advance(request->ringbuf); + /* Push the hw context on to the active list */ + i915_vma_move_to_active( + i915_gem_obj_to_ggtt( + request->ctx->engine[ring->id].state), + request); + + /* Push the ringbuf on to the active list */ + i915_vma_move_to_active( + i915_gem_obj_to_ggtt( + request->ctx->engine[ring->id].ringbuf->obj), + request); + request->tail = request->ringbuf->tail; if (intel_ring_stopped(ring)) @@ -1006,10 +1018,15 @@ static int intel_lr_context_do_pin(struct intel_engine_cs *ring, if (ret) return ret; - ret = intel_pin_and_map_ringbuffer_obj(ring->dev, ringbuf); + ret = i915_gem_obj_ggtt_pin(ringbuf->obj, PAGE_SIZE, + PIN_MAPPABLE); if (ret) goto unpin_ctx_obj; + ret = i915_gem_object_set_to_gtt_domain(ringbuf->obj, true); + if (ret) + goto unpin_rb_obj; + ctx_obj->dirty = true; /* Invalidate GuC TLB. */ @@ -1018,6 +1035,8 @@ static int intel_lr_context_do_pin(struct intel_engine_cs *ring, return ret; +unpin_rb_obj: + i915_gem_object_ggtt_unpin(ringbuf->obj); unpin_ctx_obj: i915_gem_object_ggtt_unpin(ctx_obj); @@ -1052,7 +1071,7 @@ void intel_lr_context_unpin(struct drm_i915_gem_request *rq) if (ctx_obj) { WARN_ON(!mutex_is_locked(&ring->dev->struct_mutex)); if (--rq->ctx->engine[ring->id].pin_count == 0) { - intel_unpin_ringbuffer_obj(ringbuf); + i915_gem_object_ggtt_unpin(ringbuf->obj); i915_gem_object_ggtt_unpin(ctx_obj); } } @@ -2369,7 +2388,7 @@ void intel_lr_context_free(struct intel_context *ctx) struct intel_engine_cs *ring = ringbuf->ring; if (ctx == ring->default_context) { - intel_unpin_ringbuffer_obj(ringbuf); + i915_gem_object_ggtt_unpin(ringbuf->obj); i915_gem_object_ggtt_unpin(ctx_obj); } WARN_ON(ctx->engine[ring->id].pin_count); @@ -2536,5 +2555,8 @@ void intel_lr_context_reset(struct drm_device *dev, ringbuf->head = 0; ringbuf->tail = 0; + + i915_gem_object_ggtt_unpin( + ctx->engine[ring->id].state); } } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index c82c74c..79df8ca 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1958,38 +1958,35 @@ static int init_phys_status_page(struct intel_engine_cs *ring) return 0; } -void intel_unpin_ringbuffer_obj(struct intel_ringbuffer *ringbuf) +static int intel_mmap_ringbuffer_obj(struct drm_i915_gem_object *obj, + bool unmap) { - iounmap(ringbuf->virtual_start); - ringbuf->virtual_start = NULL; - i915_gem_object_ggtt_unpin(ringbuf->obj); -} - -int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev, - struct intel_ringbuffer *ringbuf) -{ - struct drm_i915_private *dev_priv = to_i915(dev); - struct drm_i915_gem_object *obj = ringbuf->obj; - int ret; - - ret = i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, PIN_MAPPABLE); - if (ret) - return ret; - - ret = i915_gem_object_set_to_gtt_domain(obj, true); - if (ret) { - i915_gem_object_ggtt_unpin(obj); - return ret; - } - - ringbuf->virtual_start = ioremap_wc(dev_priv->gtt.mappable_base + - i915_gem_obj_ggtt_offset(obj), ringbuf->size); - if (ringbuf->virtual_start == NULL) { - i915_gem_object_ggtt_unpin(obj); - return -EINVAL; + int ret = 0; + struct intel_ringbuffer *ringbuf = + (struct intel_ringbuffer *)obj->mappable; + + if (!unmap) { + struct drm_device *dev = ringbuf->ring->dev; + struct drm_i915_private *dev_priv = to_i915(dev); + + WARN_ON(ringbuf->virtual_start != NULL); + if (ringbuf->virtual_start == NULL) { + ringbuf->virtual_start = ioremap_wc( + dev_priv->gtt.mappable_base + + i915_gem_obj_ggtt_offset(obj), + ringbuf->size); + if (ringbuf->virtual_start == NULL) { + i915_gem_object_ggtt_unpin(obj); + return -EINVAL; + } + } + } else { + if (!i915_gem_obj_is_pinned(ringbuf->obj)) { + iounmap(ringbuf->virtual_start); + ringbuf->virtual_start = NULL; + } } - - return 0; + return ret; } static void intel_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf) @@ -2016,6 +2013,9 @@ static int intel_alloc_ringbuffer_obj(struct drm_device *dev, ringbuf->obj = obj; + obj->mmap = intel_mmap_ringbuffer_obj; + obj->mappable = ringbuf; + return 0; } @@ -2094,7 +2094,7 @@ static int intel_init_ring_buffer(struct drm_device *dev, goto error; } - ret = intel_pin_and_map_ringbuffer_obj(dev, ringbuf); + ret = i915_gem_obj_ggtt_pin(ringbuf->obj, PAGE_SIZE, PIN_MAPPABLE); if (ret) { DRM_ERROR("Failed to pin and map ringbuffer %s: %d\n", ring->name, ret); @@ -2102,12 +2102,19 @@ static int intel_init_ring_buffer(struct drm_device *dev, goto error; } + ret = i915_gem_object_set_to_gtt_domain(ringbuf->obj, true); + if (ret) + goto error_unpin; + ret = i915_cmd_parser_init_ring(ring); if (ret) goto error; return 0; +error_unpin: + i915_gem_object_ggtt_unpin(ringbuf->obj); + intel_destroy_ringbuffer_obj(ringbuf); error: intel_ringbuffer_free(ringbuf); ring->buffer = NULL; @@ -2126,7 +2133,7 @@ void intel_cleanup_ring_buffer(struct intel_engine_cs *ring) intel_stop_ring_buffer(ring); WARN_ON(!IS_GEN2(ring->dev) && (I915_READ_MODE(ring) & MODE_IDLE) == 0); - intel_unpin_ringbuffer_obj(ring->buffer); + i915_gem_object_ggtt_unpin(ring->buffer->obj); intel_ringbuffer_free(ring->buffer); ring->buffer = NULL; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index d99b167..8daaf99 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -421,9 +421,6 @@ intel_write_status_page(struct intel_engine_cs *ring, struct intel_ringbuffer * intel_engine_create_ringbuffer(struct intel_engine_cs *engine, int size); -int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev, - struct intel_ringbuffer *ringbuf); -void intel_unpin_ringbuffer_obj(struct intel_ringbuffer *ringbuf); void intel_ringbuffer_free(struct intel_ringbuffer *ring); void intel_stop_ring_buffer(struct intel_engine_cs *ring);