Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp1362153pxf; Fri, 12 Mar 2021 07:55:36 -0800 (PST) X-Google-Smtp-Source: ABdhPJxhvxewrWO3YoF/9UaytR79cmOOJle2iCeLWj+oNcFyLuQOftZk1H6oeeRNTPJSyLAuV8Mv X-Received: by 2002:a17:907:2716:: with SMTP id w22mr9269452ejk.328.1615564535905; Fri, 12 Mar 2021 07:55:35 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1615564535; cv=none; d=google.com; s=arc-20160816; b=JqqhY8XjjEVm4dIDsDSdV6j+4UdR1cwHXACMyBS5MCDVgQjxfo3sDLYWB5BwNTE4Qh cvrKgco2QczsmgEPzbkAc7kNQje6hRZxx2EJj9S+ljTVmIKhLlD501PkBioBaFZkHe7Q 2bL0fI51LFbAeP8nBugL8gYpeE40vb8k4dxRCvNwaI7xbiUWhaoX8hK0ygJ5KC8/o8YX VSwXuO7YZptNLEPuF28vg+eHxkRsJa3ssyJpdwzuDISupLU20o6lU70zWIwkxhGDI0I4 ie+7LvGijsjAugw+44YzK/WwCMsYi5z/FVQJ9NJHm1Cc4CzHT27sIZda6o7cOO1M5Khu hmtA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:content-language :in-reply-to:mime-version:user-agent:date:message-id:from:references :cc:to:subject; bh=fJyRtgFS+8CcW2owyW1kHWyqHllgpbr60xK2hZwlyMA=; b=RUpmsIsW6g+yexD1LTxGBKh0wjNYTJXXLtNTkD15wsUqHNIx78d+7rAKr7uJcstStA YPOHtdgxTRzFebAJMhyf1EwLYnK2DUzJNewrK+g2cJvbY0Cr0ZQhxfCsBeiRCw1LAci/ y26w9VOWR8M/+ypZehDWZ3k1IWnGpd79lWDDhUZ/AJjpgyNo3uAqoPpzAM/ig3LQRoEq r2JkNFEfJBvHG1H/3xatMo7dUiB6nPMnX0c8RFO2C9vhNAyjzeXUepB9pST3gWPiQhmD 9SZ4kvRMrddbD9uoTP5MyUJEVPdjkPjB3gSjgd4J7FaxfnvCYMe1CteZlbrxUU3D01kr wazw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id d5si4441748eja.499.2021.03.12.07.55.12; Fri, 12 Mar 2021 07:55:35 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232105AbhCLPyL (ORCPT + 99 others); Fri, 12 Mar 2021 10:54:11 -0500 Received: from foss.arm.com ([217.140.110.172]:56294 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232553AbhCLPwI (ORCPT ); Fri, 12 Mar 2021 10:52:08 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id E8D0211B3; Fri, 12 Mar 2021 07:52:07 -0800 (PST) Received: from [10.57.52.136] (unknown [10.57.52.136]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 9DA3A3F7D7; Fri, 12 Mar 2021 07:52:04 -0800 (PST) Subject: Re: [RFC PATCH v2 06/11] dma-direct: Support PCI P2PDMA pages in dma-direct map_sg To: Logan Gunthorpe , linux-kernel@vger.kernel.org, linux-nvme@lists.infradead.org, linux-block@vger.kernel.org, linux-pci@vger.kernel.org, linux-mm@kvack.org, iommu@lists.linux-foundation.org Cc: Minturn Dave B , John Hubbard , Dave Hansen , Ira Weiny , Matthew Wilcox , =?UTF-8?Q?Christian_K=c3=b6nig?= , Jason Gunthorpe , Jason Ekstrand , Daniel Vetter , Dan Williams , Stephen Bates , Jakowski Andrzej , Christoph Hellwig , Xiong Jianxin References: <20210311233142.7900-1-logang@deltatee.com> <20210311233142.7900-7-logang@deltatee.com> From: Robin Murphy Message-ID: <215e1472-5294-d20a-a43a-ff6dfe8cd66e@arm.com> Date: Fri, 12 Mar 2021 15:52:02 +0000 User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Thunderbird/78.7.1 MIME-Version: 1.0 In-Reply-To: <20210311233142.7900-7-logang@deltatee.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-GB Content-Transfer-Encoding: 7bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 2021-03-11 23:31, Logan Gunthorpe wrote: > Add PCI P2PDMA support for dma_direct_map_sg() so that it can map > PCI P2PDMA pages directly without a hack in the callers. This allows > for heterogeneous SGLs that contain both P2PDMA and regular pages. > > SGL segments that contain PCI bus addresses are marked with > sg_mark_pci_p2pdma() and are ignored when unmapped. > > Signed-off-by: Logan Gunthorpe > --- > kernel/dma/direct.c | 35 ++++++++++++++++++++++++++++++++--- > kernel/dma/mapping.c | 13 ++++++++++--- > 2 files changed, 42 insertions(+), 6 deletions(-) > > diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c > index 002268262c9a..f326d32062dd 100644 > --- a/kernel/dma/direct.c > +++ b/kernel/dma/direct.c > @@ -13,6 +13,7 @@ > #include > #include > #include > +#include > #include "direct.h" > > /* > @@ -387,19 +388,47 @@ void dma_direct_unmap_sg(struct device *dev, struct scatterlist *sgl, > struct scatterlist *sg; > int i; > > - for_each_sg(sgl, sg, nents, i) > + for_each_sg(sgl, sg, nents, i) { > + if (sg_is_pci_p2pdma(sg)) > + continue; > + > dma_direct_unmap_page(dev, sg->dma_address, sg_dma_len(sg), dir, > attrs); > + } > } > #endif > > int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, int nents, > enum dma_data_direction dir, unsigned long attrs) > { > - int i; > + struct dev_pagemap *pgmap = NULL; > + int i, map = -1, ret = 0; > struct scatterlist *sg; > + u64 bus_off; > > for_each_sg(sgl, sg, nents, i) { > + if (is_pci_p2pdma_page(sg_page(sg))) { > + if (sg_page(sg)->pgmap != pgmap) { > + pgmap = sg_page(sg)->pgmap; > + map = pci_p2pdma_dma_map_type(dev, pgmap); > + bus_off = pci_p2pdma_bus_offset(sg_page(sg)); > + } > + > + if (map < 0) { > + sg->dma_address = DMA_MAPPING_ERROR; > + ret = -EREMOTEIO; > + goto out_unmap; > + } > + > + if (map) { > + sg->dma_address = sg_phys(sg) + sg->offset - > + bus_off; > + sg_dma_len(sg) = sg->length; > + sg_mark_pci_p2pdma(sg); > + continue; > + } > + } > + > sg->dma_address = dma_direct_map_page(dev, sg_page(sg), > sg->offset, sg->length, dir, attrs); > if (sg->dma_address == DMA_MAPPING_ERROR) > @@ -411,7 +440,7 @@ int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, int nents, > > out_unmap: > dma_direct_unmap_sg(dev, sgl, i, dir, attrs | DMA_ATTR_SKIP_CPU_SYNC); > - return 0; > + return ret; > } > > dma_addr_t dma_direct_map_resource(struct device *dev, phys_addr_t paddr, > diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c > index b6a633679933..adc1a83950be 100644 > --- a/kernel/dma/mapping.c > +++ b/kernel/dma/mapping.c > @@ -178,8 +178,15 @@ void dma_unmap_page_attrs(struct device *dev, dma_addr_t addr, size_t size, > EXPORT_SYMBOL(dma_unmap_page_attrs); > > /* > - * dma_maps_sg_attrs returns 0 on error and > 0 on success. > - * It should never return a value < 0. > + * dma_maps_sg_attrs returns 0 on any resource error and > 0 on success. > + * > + * If 0 is returned, the mapping can be retried and will succeed once > + * sufficient resources are available. That's not a guarantee we can uphold. Retrying forever in the vain hope that a device might evolve some extra address bits, or a bounce buffer might magically grow big enough for a gigantic mapping, isn't necessarily the best idea. > + * > + * If there are P2PDMA pages in the scatterlist then this function may > + * return -EREMOTEIO to indicate that the pages are not mappable by the > + * device. In this case, an error should be returned for the IO as it > + * will never be successfully retried. > */ > int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, > enum dma_data_direction dir, unsigned long attrs) > @@ -197,7 +204,7 @@ int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, > ents = dma_direct_map_sg(dev, sg, nents, dir, attrs); > else > ents = ops->map_sg(dev, sg, nents, dir, attrs); > - BUG_ON(ents < 0); > + This scares me - I hesitate to imagine the amount of driver/subsystem code out there that will see nonzero and merrily set off iterating a negative number of segments, if we open the floodgates of allowing implementations to return error codes here. Robin. > debug_dma_map_sg(dev, sg, nents, ents, dir); > > return ents; >