From patchwork Tue Apr 17 18:22:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Robin Murphy X-Patchwork-Id: 10346429 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 3C43360216 for ; Tue, 17 Apr 2018 18:22:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2B79627F98 for ; Tue, 17 Apr 2018 18:22:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1FFA4285AB; Tue, 17 Apr 2018 18:22:54 +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 92D9E27F98 for ; Tue, 17 Apr 2018 18:22:53 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 032AE6E4BC; Tue, 17 Apr 2018 18:22:50 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from foss.arm.com (usa-sjc-mx-foss1.foss.arm.com [217.140.101.70]) by gabe.freedesktop.org (Postfix) with ESMTP id C74F46E2AD; Tue, 17 Apr 2018 18:22:48 +0000 (UTC) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 582F81435; Tue, 17 Apr 2018 11:22:48 -0700 (PDT) Received: from [10.1.210.88] (e110467-lin.cambridge.arm.com [10.1.210.88]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 6C00A3F587; Tue, 17 Apr 2018 11:22:47 -0700 (PDT) Subject: Re: [PATCH v2 1/3] drm/prime: Iterate SG DMA addresses separately To: christian.koenig@amd.com, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org References: <7552feb9-a512-eaee-103c-5f2367fcd9dd@gmail.com> From: Robin Murphy Message-ID: <73ac5c65-1dbd-8711-5770-75d79389bf44@arm.com> Date: Tue, 17 Apr 2018 19:22:46 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.7.0 MIME-Version: 1.0 In-Reply-To: <7552feb9-a512-eaee-103c-5f2367fcd9dd@gmail.com> Content-Language: en-US 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: okaya@codeaurora.org, alexander.deucher@amd.com Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP On 17/04/18 17:29, Christian König wrote: > Am 17.04.2018 um 17:58 schrieb Robin Murphy: >> For dma_map_sg(), DMA API implementations are free to merge consecutive >> segments into a single DMA mapping if conditions are suitable, thus the >> resulting DMA addresses which drm_prime_sg_to_page_addr_arrays() >> iterates may be packed into fewer entries than ttm->sg->nents implies. >> >> The current implementation does not account for this, meaning that its >> callers either have to reject the 0 < count < nents case or risk getting >> bogus DMA addresses beyond the first segment. Fortunately this is quite >> easy to handle without having to rejig structures to also store the >> mapped count, since the total DMA length should still be equal to the >> total buffer length. All we need is a second scatterlist cursor to >> iterate through the DMA addresses independently of the page addresses. >> >> Signed-off-by: Robin Murphy > > Reviewed-by: Christian König for the whole > series. Thanks Christian. FWIW, the following *completely untested* hack should in theory give the AMD IOMMU similar segment-merging behaviour to the arm64 IOMMU DMA ops, if that helps widen the scope for testing/investigation (I have neither an AMD/ATI graphics card nor a PCIe-capable arm64 box to hand just at the moment). Robin. ----->8----- domain = get_domain(dev); @@ -2535,7 +2535,28 @@ static int map_sg(struct device *dev, struct scatterlist *sglist, s->dma_length = s->length; } - return nelems; + d = sglist; + max_seg = dma_get_max_seg_size(dev); + count = 1; + nelems -= 1; + for_each_sg(sg_next(sglist), s, nelems, i) { + dma_addr_t s_dma_addr = s->dma_address; + unsigned int s_dma_len = s->dma_length; + + s->dma_address = 0; + s->dma_length = 0; + if (s_dma_addr == d->dma_address + d->dma_length && + d->dma_length + s_dma_len <= max_seg) { + d->dma_length += s_dma_len; + } else { + d = sg_next(d); + d->dma_address = s_dma_addr; + d->dma_length = s_dma_len; + count++; + } + } + + return count; out_unmap: pr_err("%s: IOMMU mapping error in map_sg (io-pages: %d)\n", diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 2a99f0f14795..60b0e495b567 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -2489,11 +2489,11 @@ static int map_sg(struct device *dev, struct scatterlist *sglist, int nelems, enum dma_data_direction direction, unsigned long attrs) { - int mapped_pages = 0, npages = 0, prot = 0, i; + int mapped_pages = 0, npages = 0, prot = 0, i, count; struct protection_domain *domain; struct dma_ops_domain *dma_dom; - struct scatterlist *s; - unsigned long address; + struct scatterlist *s, *d; + unsigned long address, max_seg; u64 dma_mask;