From patchwork Wed Oct 11 15:14:20 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Crouse X-Patchwork-Id: 9999893 X-Patchwork-Delegate: agross@codeaurora.org Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 29EA360244 for ; Wed, 11 Oct 2017 15:14:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 12F982897E for ; Wed, 11 Oct 2017 15:14:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 07C82289D0; Wed, 11 Oct 2017 15:14:37 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 903F52897E for ; Wed, 11 Oct 2017 15:14:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751913AbdJKPOf (ORCPT ); Wed, 11 Oct 2017 11:14:35 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:60820 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751459AbdJKPOe (ORCPT ); Wed, 11 Oct 2017 11:14:34 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 2518360D06; Wed, 11 Oct 2017 15:14:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1507734874; bh=mHZiLp7NR+TfGBJmZJz79CfegMwX6fFsknAEqaNdykw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Gd0Vy9s1AiR9uaKl8I0G0RFYqFThekcg0wqqxJEUCJ3hbSg8NAsiIqY5t0XCcs2L7 eRRPn6uxN0A3XbmadjizZ5wq94B7b9BBVyOEYefcj58C9vI1qo1sGoSjubwC0vX1vp eDvxpp3xImgFDrgGPowqOexxuubz1a5K2XXdUVQc= Received: from jcrouse-lnx.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: jcrouse@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id CB2BC60CDD; Wed, 11 Oct 2017 15:14:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1507734873; bh=mHZiLp7NR+TfGBJmZJz79CfegMwX6fFsknAEqaNdykw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Zp07eww167aOUiHsNt9Yim10nOvjz4FAqeCP82cwUFYz/XEpTnyl1Hwer+WC7ofyL D7J6L2HbwKIZx9rxtktYrwtLJQuaoidRuWCS3Pl0heQrEFbAAYYvuMtEjoGIrW/jd8 gdiWSvdpeXK3wHpnq56tVPIbvVJJlXoZ5ELjVjSI= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org CB2BC60CDD Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=jcrouse@codeaurora.org From: Jordan Crouse To: freedreno@lists.freedesktop.org Cc: linux-arm-msm@vger.kernel.org Subject: [PATCH 5/9] drm/msm: Shadow current pointer in the ring until command is complete Date: Wed, 11 Oct 2017 09:14:20 -0600 Message-Id: <1507734864-25069-6-git-send-email-jcrouse@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1507734864-25069-1-git-send-email-jcrouse@codeaurora.org> References: <1507734864-25069-1-git-send-email-jcrouse@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add a shadow pointer to track the current command being written into the ring. Don't commit it as 'cur' until the command is submitted. Because 'cur' is used to construct the software copy of the wptr this ensures that somebody peeking in on the ring doesn't assume that a command is inflight while it is being written. This isn't a huge deal with a single ring (though technically the hangcheck could assume the system is prematurely busy when it isn't) but it will be rather important for preemption where the decision to preempt is based on a non-empty ringbuffer. Without a shadow an aggressive preemption scheme could assume that the ringbuffer is non empty and switch to it before the CPU is done writing the command and boom. Even though preemption won't be supported for all targets because of the way the code is organized it is simpler to make this generic for all targets. The extra load for non-preemption targets should be minimal. Signed-off-by: Jordan Crouse --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 9 +++++++-- drivers/gpu/drm/msm/msm_ringbuffer.c | 1 + drivers/gpu/drm/msm/msm_ringbuffer.h | 12 ++++++++---- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index cf91840..77eaa46 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -89,6 +89,7 @@ int adreno_hw_init(struct msm_gpu *gpu) } ring->cur = ring->start; + ring->next = ring->start; /* reset completed fence seqno: */ ring->memptrs->fence = ring->seqno; @@ -233,12 +234,15 @@ void adreno_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring) struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); uint32_t wptr; + /* Copy the shadow to the actual register */ + ring->cur = ring->next; + /* * Mask wptr value that we calculate to fit in the HW range. This is * to account for the possibility that the last command fit exactly into * the ringbuffer and rb->next hasn't wrapped to zero yet */ - wptr = get_wptr(ring) % (MSM_GPU_RINGBUFFER_SZ >> 2); + wptr = (ring->cur - ring->start) % (MSM_GPU_RINGBUFFER_SZ >> 2); /* ensure writes to ringbuffer have hit system memory: */ mb(); @@ -350,7 +354,8 @@ static uint32_t ring_freewords(struct msm_ringbuffer *ring) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(ring->gpu); uint32_t size = MSM_GPU_RINGBUFFER_SZ >> 2; - uint32_t wptr = get_wptr(ring); + /* Use ring->next to calculate free size */ + uint32_t wptr = ring->next - ring->start; uint32_t rptr = get_rptr(adreno_gpu, ring); return (rptr + (size - 1) - wptr) % size; } diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c index febf2541..6015959 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.c +++ b/drivers/gpu/drm/msm/msm_ringbuffer.c @@ -46,6 +46,7 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id, goto fail; } ring->end = ring->start + (MSM_GPU_RINGBUFFER_SZ >> 2); + ring->next = ring->start; ring->cur = ring->start; ring->memptrs = memptrs; diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.h b/drivers/gpu/drm/msm/msm_ringbuffer.h index ec44251..3749764 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.h +++ b/drivers/gpu/drm/msm/msm_ringbuffer.h @@ -32,7 +32,7 @@ struct msm_ringbuffer { struct msm_gpu *gpu; int id; struct drm_gem_object *bo; - uint32_t *start, *end, *cur; + uint32_t *start, *end, *cur, *next; struct list_head submits; uint64_t iova; uint32_t seqno; @@ -51,9 +51,13 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id, static inline void OUT_RING(struct msm_ringbuffer *ring, uint32_t data) { - if (ring->cur == ring->end) - ring->cur = ring->start; - *(ring->cur++) = data; + /* + * ring->next points to the current command being written - it won't be + * committed as ring->cur until the flush + */ + if (ring->next == ring->end) + ring->next = ring->start; + *(ring->next++) = data; } #endif /* __MSM_RINGBUFFER_H__ */