From patchwork Fri Apr 20 17:13:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas Stach X-Patchwork-Id: 10353351 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 C7399602B1 for ; Fri, 20 Apr 2018 17:13:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 95C58287C1 for ; Fri, 20 Apr 2018 17:13:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8A32F28802; Fri, 20 Apr 2018 17:13:53 +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=-5.2 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 303C5287FE for ; Fri, 20 Apr 2018 17:13:53 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A964E6E6B7; Fri, 20 Apr 2018 17:13:47 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by gabe.freedesktop.org (Postfix) with ESMTPS id B676D6E6BB for ; Fri, 20 Apr 2018 17:13:45 +0000 (UTC) Received: from dude.hi.pengutronix.de ([2001:67c:670:100:1d::7] helo=dude.pengutronix.de.) by metis.ext.pengutronix.de with esmtp (Exim 4.89) (envelope-from ) id 1f9ZbT-0005UR-R3; Fri, 20 Apr 2018 19:13:43 +0200 From: Lucas Stach To: dri-devel@lists.freedesktop.org, etnaviv@lists.freedesktop.org Subject: [PATCH 2/2] drm/etnaviv: mmuv2: allocate 2nd level page tables on demand Date: Fri, 20 Apr 2018 19:13:42 +0200 Message-Id: <20180420171342.26432-2-l.stach@pengutronix.de> X-Mailer: git-send-email 2.16.3 In-Reply-To: <20180420171342.26432-1-l.stach@pengutronix.de> References: <20180420171342.26432-1-l.stach@pengutronix.de> X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::7 X-SA-Exim-Mail-From: l.stach@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: patchwork-lst@pengutronix.de, kernel@pengutronix.de, Russell King MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP With etnaviv not being tied into the IOMMU framework anymore, the MMU functions will only be called under sleeping locks. Thus we are able to allocate the memory for the 2nd level page tables on demand without having to deal with memory allocation in atomic context. This speeds up driver intitialization on MMUv2 GPU cores, as we don't need to preallocate all the page table memory and also reduces memory consumption for most workloads, as most of them won't use the full GPU virtual address space. Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c | 59 +++++++++++++++--------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c b/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c index 540962f24d0f..c0d7e5244102 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c @@ -49,6 +49,7 @@ struct etnaviv_iommuv2_domain { /* S(lave) TLB aka second level pagetable */ u32 *stlb_cpu[1024]; dma_addr_t stlb_dma[1024]; + DECLARE_BITMAP(stlb_allocated, 1024); }; static struct etnaviv_iommuv2_domain * @@ -57,13 +58,35 @@ to_etnaviv_domain(struct etnaviv_iommu_domain *domain) return container_of(domain, struct etnaviv_iommuv2_domain, base); } +static int +etnaviv_iommuv2_ensure_stlb(struct etnaviv_iommuv2_domain *etnaviv_domain, + int stlb) +{ + if (test_bit(stlb, etnaviv_domain->stlb_allocated)) + return 0; + + etnaviv_domain->stlb_cpu[stlb] = + dma_alloc_writecombine(etnaviv_domain->base.dev, + SZ_4K, + &etnaviv_domain->stlb_dma[stlb], + GFP_KERNEL); + + if (!etnaviv_domain->stlb_cpu[stlb]) + return -ENOMEM; + + __set_bit(stlb, etnaviv_domain->stlb_allocated); + etnaviv_domain->mtlb_cpu[stlb] = etnaviv_domain->stlb_dma[stlb] | + MMUv2_PTE_PRESENT; + return 0; +} + static int etnaviv_iommuv2_map(struct etnaviv_iommu_domain *domain, unsigned long iova, phys_addr_t paddr, size_t size, int prot) { struct etnaviv_iommuv2_domain *etnaviv_domain = to_etnaviv_domain(domain); - int mtlb_entry, stlb_entry; + int mtlb_entry, stlb_entry, ret; u32 entry = (u32)paddr | MMUv2_PTE_PRESENT; if (size != SZ_4K) @@ -75,6 +98,10 @@ static int etnaviv_iommuv2_map(struct etnaviv_iommu_domain *domain, mtlb_entry = (iova & MMUv2_MTLB_MASK) >> MMUv2_MTLB_SHIFT; stlb_entry = (iova & MMUv2_STLB_MASK) >> MMUv2_STLB_SHIFT; + ret = etnaviv_iommuv2_ensure_stlb(etnaviv_domain, mtlb_entry); + if (ret) + return ret; + etnaviv_domain->stlb_cpu[mtlb_entry][stlb_entry] = entry; return 0; @@ -101,7 +128,7 @@ static size_t etnaviv_iommuv2_unmap(struct etnaviv_iommu_domain *domain, static int etnaviv_iommuv2_init(struct etnaviv_iommuv2_domain *etnaviv_domain) { u32 *p; - int ret, i, j; + int ret, i; /* allocate scratch page */ etnaviv_domain->base.bad_page_cpu = dma_alloc_writecombine( @@ -135,25 +162,6 @@ static int etnaviv_iommuv2_init(struct etnaviv_iommuv2_domain *etnaviv_domain) goto fail_mem; } - /* pre-populate STLB pages (may want to switch to on-demand later) */ - for (i = 0; i < MMUv2_MAX_STLB_ENTRIES; i++) { - etnaviv_domain->stlb_cpu[i] = - dma_alloc_writecombine(etnaviv_domain->base.dev, - SZ_4K, - &etnaviv_domain->stlb_dma[i], - GFP_KERNEL); - if (!etnaviv_domain->stlb_cpu[i]) { - ret = -ENOMEM; - goto fail_mem; - } - p = etnaviv_domain->stlb_cpu[i]; - for (j = 0; j < SZ_4K / 4; j++) - *p++ = MMUv2_PTE_EXCEPTION; - - etnaviv_domain->mtlb_cpu[i] = etnaviv_domain->stlb_dma[i] | - MMUv2_PTE_PRESENT; - } - return 0; fail_mem: @@ -172,13 +180,6 @@ static int etnaviv_iommuv2_init(struct etnaviv_iommuv2_domain *etnaviv_domain) etnaviv_domain->mtlb_cpu, etnaviv_domain->mtlb_dma); - for (i = 0; i < MMUv2_MAX_STLB_ENTRIES; i++) { - if (etnaviv_domain->stlb_cpu[i]) - dma_free_writecombine(etnaviv_domain->base.dev, SZ_4K, - etnaviv_domain->stlb_cpu[i], - etnaviv_domain->stlb_dma[i]); - } - return ret; } @@ -201,7 +202,7 @@ static void etnaviv_iommuv2_domain_free(struct etnaviv_iommu_domain *domain) etnaviv_domain->mtlb_dma); for (i = 0; i < MMUv2_MAX_STLB_ENTRIES; i++) { - if (etnaviv_domain->stlb_cpu[i]) + if (test_bit(i, etnaviv_domain->stlb_allocated)) dma_free_writecombine(etnaviv_domain->base.dev, SZ_4K, etnaviv_domain->stlb_cpu[i], etnaviv_domain->stlb_dma[i]);