From patchwork Fri Jun 12 20:25:37 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Gordon X-Patchwork-Id: 6600791 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 C11509F1C1 for ; Fri, 12 Jun 2015 20:26:01 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 943352065E for ; Fri, 12 Jun 2015 20:26:00 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 023C320650 for ; Fri, 12 Jun 2015 20:25:58 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 638766E59C; Fri, 12 Jun 2015 13:25:57 -0700 (PDT) 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 9CD076E58F for ; Fri, 12 Jun 2015 13:25:55 -0700 (PDT) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga103.jf.intel.com with ESMTP; 12 Jun 2015 13:25:55 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,604,1427785200"; d="scan'208";a="745766756" Received: from dsgordon-linux.isw.intel.com ([10.102.226.51]) by orsmga002.jf.intel.com with ESMTP; 12 Jun 2015 13:25:54 -0700 From: Dave Gordon To: intel-gfx@lists.freedesktop.org Date: Fri, 12 Jun 2015 21:25:37 +0100 Message-Id: <1434140738-19521-2-git-send-email-david.s.gordon@intel.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1434140738-19521-1-git-send-email-david.s.gordon@intel.com> References: <1434128948-9221-3-git-send-email-david.s.gordon@intel.com> <1434140738-19521-1-git-send-email-david.s.gordon@intel.com> Subject: [Intel-gfx] [PATCH 1/2] drm/i915: Don't wait twice in {__intel, logical}_ring_prepare() 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 In the case that the ringbuffer was near-full AND 'tail' was near the end of the buffer, we could have ended up waiting twice: once to gain ownership of the space between TAIL and the end (which we just want to fill with padding, so as not to split a single command sequence across the end of the ringbuffer), and then again to get enough space for the new data that the caller wants to add. Now we just precalculate the total amount of space we'll need *including* any for padding at the end of the ringbuffer and wait for that much in one go. Signed-off-by: Dave Gordon --- drivers/gpu/drm/i915/intel_lrc.c | 52 +++++++++++++++---------------- drivers/gpu/drm/i915/intel_ringbuffer.c | 51 +++++++++++++++--------------- 2 files changed, 50 insertions(+), 53 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 454e836..a4bb5d3 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -740,39 +740,22 @@ intel_logical_ring_advance_and_submit(struct intel_ringbuffer *ringbuf, execlists_context_queue(ring, ctx, ringbuf->tail, request); } -static int logical_ring_wrap_buffer(struct intel_ringbuffer *ringbuf, - struct intel_context *ctx) -{ - uint32_t __iomem *virt; - int rem = ringbuf->size - ringbuf->tail; - - if (ringbuf->space < rem) { - int ret = logical_ring_wait_for_space(ringbuf, ctx, rem); - - if (ret) - return ret; - } - - virt = ringbuf->virtual_start + ringbuf->tail; - rem /= 4; - while (rem--) - iowrite32(MI_NOOP, virt++); - - ringbuf->tail = 0; - intel_ring_update_space(ringbuf); - - return 0; -} - static int logical_ring_prepare(struct intel_ringbuffer *ringbuf, struct intel_context *ctx, int bytes) { + int fill = 0; int ret; + /* + * If the request will not fit between 'tail' and the effective + * size of the ringbuffer, then we need to pad the end of the + * ringbuffer with NOOPs, then start the request at the top of + * the ring. This increases the total size that we need to check + * for by however much is left at the end of the ring ... + */ if (unlikely(ringbuf->tail + bytes > ringbuf->effective_size)) { - ret = logical_ring_wrap_buffer(ringbuf, ctx); - if (unlikely(ret)) - return ret; + fill = ringbuf->size - ringbuf->tail; + bytes += fill; } if (unlikely(ringbuf->space < bytes)) { @@ -781,6 +764,21 @@ static int logical_ring_prepare(struct intel_ringbuffer *ringbuf, return ret; } + if (unlikely(fill)) { + uint32_t __iomem *virt = ringbuf->virtual_start + ringbuf->tail; + + /* tail should not have moved */ + if (WARN_ON(fill != ringbuf->size - ringbuf->tail)) + fill = ringbuf->size - ringbuf->tail; + + do + iowrite32(MI_NOOP, virt++); + while ((fill -= 4) > 0); + + ringbuf->tail = 0; + intel_ring_update_space(ringbuf); + } + return 0; } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index a3406b2..5a1cd20 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2137,29 +2137,6 @@ static int ring_wait_for_space(struct intel_engine_cs *ring, int n) return 0; } -static int intel_wrap_ring_buffer(struct intel_engine_cs *ring) -{ - uint32_t __iomem *virt; - struct intel_ringbuffer *ringbuf = ring->buffer; - int rem = ringbuf->size - ringbuf->tail; - - if (ringbuf->space < rem) { - int ret = ring_wait_for_space(ring, rem); - if (ret) - return ret; - } - - virt = ringbuf->virtual_start + ringbuf->tail; - rem /= 4; - while (rem--) - iowrite32(MI_NOOP, virt++); - - ringbuf->tail = 0; - intel_ring_update_space(ringbuf); - - return 0; -} - int intel_ring_idle(struct intel_engine_cs *ring) { struct drm_i915_gem_request *req; @@ -2197,12 +2174,19 @@ static int __intel_ring_prepare(struct intel_engine_cs *ring, int bytes) { struct intel_ringbuffer *ringbuf = ring->buffer; + int fill = 0; int ret; + /* + * If the request will not fit between 'tail' and the effective + * size of the ringbuffer, then we need to pad the end of the + * ringbuffer with NOOPs, then start the request at the top of + * the ring. This increases the total size that we need to check + * for by however much is left at the end of the ring ... + */ if (unlikely(ringbuf->tail + bytes > ringbuf->effective_size)) { - ret = intel_wrap_ring_buffer(ring); - if (unlikely(ret)) - return ret; + fill = ringbuf->size - ringbuf->tail; + bytes += fill; } if (unlikely(ringbuf->space < bytes)) { @@ -2211,6 +2195,21 @@ static int __intel_ring_prepare(struct intel_engine_cs *ring, return ret; } + if (unlikely(fill)) { + uint32_t __iomem *virt = ringbuf->virtual_start + ringbuf->tail; + + /* tail should not have moved */ + if (WARN_ON(fill != ringbuf->size - ringbuf->tail)) + fill = ringbuf->size - ringbuf->tail; + + do + iowrite32(MI_NOOP, virt++); + while ((fill -= 4) > 0); + + ringbuf->tail = 0; + intel_ring_update_space(ringbuf); + } + return 0; }