Received: by 2002:a05:6a11:4021:0:0:0:0 with SMTP id ky33csp4218113pxb; Mon, 27 Sep 2021 11:54:57 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzX+S1CgZoSe48uhnzyBFaJvFuGGj3lNDzuYpKsCSqncf42Sz9K2Ze0DpOhQbPb3GwPgKtA X-Received: by 2002:a17:90b:4f8a:: with SMTP id qe10mr690853pjb.5.1632768896887; Mon, 27 Sep 2021 11:54:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1632768896; cv=none; d=google.com; s=arc-20160816; b=D0TI7BGHDrosd5/w/UvTNggUQTblqpxZZ4s1bII2+ux+zUhBHU3p1O76n55SYooyEO 6JJJnziHa//1ZvBSMbTsX2uEYBwFS9i8hAaDVNskFhfgxRT4Rjbgx7VvFdURpkOAzSe8 OfZP9mQZPXL5lPOjO70nXtlO8+ZyLXCvt4wcjG6c+KZ17vbyyLEV10/hofJW0MtiVk2x QXHjGbaQliWNAB4UfFdTXvRGNPQrKsLkMlo5Mr7ixGLtfjF4hUMXJ7kGvb3DZ685n18+ 1F5G6UO3L1RnzIxC+S1bqHoasK4/20/NSHxJHUZfXbkOABdsogzymC/0dIGsvGdvr+WU pNDA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :message-id:subject:cc:to:from:date:dkim-signature; bh=J/19HjTpDb5xBp0hrYK2aautLqyfl0BszdX+mfNW14E=; b=YcJsBUkYELpqFh/U5Wt6Rusi7M1268AcjNw9VcmpHaA3h3fffQCpirMMvDVDsGLedg S0nPBAP9+NkEj4PLup5Bj7C1+xhrtP/c4iaOjEdaF2ksfhElkGunI3/HUq2Dsg7HkjLi AiYUs9BFTLjg09/iMoSixlPiMw+xtlYI8cPjUAAzATBPFKocVi6UIQkVG61c8bRXuwHe vKhzulM7ickMaI9IsEKyyabYsSp69b+V94E97QMPEFGYXFAd9J2XBnMm78pA23GazhJp mXJIxrE48hbptsWJ6TcIu+qavQ1RPg25NW0scYkpR6fUe8S694ezOkngC1xI3DbIB4Pe A0hg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=j+h82KEn; 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=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id rm6si510006pjb.86.2021.09.27.11.54.42; Mon, 27 Sep 2021 11:54:56 -0700 (PDT) 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; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=j+h82KEn; 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=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235732AbhI0Sz3 (ORCPT + 99 others); Mon, 27 Sep 2021 14:55:29 -0400 Received: from mail.kernel.org ([198.145.29.99]:33088 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234507AbhI0Sz2 (ORCPT ); Mon, 27 Sep 2021 14:55:28 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 9428960FD7; Mon, 27 Sep 2021 18:53:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1632768830; bh=WQXS4Y5fxYTqqCk1J2d4JT7fGZFmk/5NLpzr/2vNoXg=; h=Date:From:To:Cc:Subject:In-Reply-To:From; b=j+h82KEneKoIWmmfnU8bIarGfEsel7wnR0BgUFxYi+ROqggCWKJnSfSd4xp0oxArs 4VZ3GUIs2qvJ7umsIGdOIUVhWigEcUG6BYJSlBElcymvcmm6xrYw7j5G4DYvOaXKVv 6dsZLPWsl0rLoNrKwUAvPv0qEObRggFeNWlDYbFZcW5Fdh2/SXwRvmg2RelqMfK2xm 3TxFsNqMUL6jRiFjOXsLJtYmZgIJGtPeY2plkKXC9gyiSASDMWeU3hsWDDsbttu6fx OydU71hNxH55bR/qjyo/saP9MWkZNX264D5M9bEfYe9wPiAMA0JBosJDzbsQP19KUC en1lkEz7/wQUg== Date: Mon, 27 Sep 2021 13:53:48 -0500 From: Bjorn Helgaas To: Logan Gunthorpe Cc: 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, Stephen Bates , Christoph Hellwig , Dan Williams , Jason Gunthorpe , Christian =?iso-8859-1?Q?K=F6nig?= , John Hubbard , Don Dutile , Matthew Wilcox , Daniel Vetter , Jakowski Andrzej , Minturn Dave B , Jason Ekstrand , Dave Hansen , Xiong Jianxin , Ira Weiny , Robin Murphy , Martin Oliveira , Chaitanya Kulkarni Subject: Re: [PATCH v3 04/20] PCI/P2PDMA: introduce helpers for dma_map_sg implementations Message-ID: <20210927185348.GA668256@bhelgaas> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20210916234100.122368-5-logang@deltatee.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Sep 16, 2021 at 05:40:44PM -0600, Logan Gunthorpe wrote: > Add pci_p2pdma_map_segment() as a helper for simple dma_map_sg() > implementations. It takes an scatterlist segment that must point to a > pci_p2pdma struct page and will map it if the mapping requires a bus > address. > > The return value indicates whether the mapping required a bus address > or whether the caller still needs to map the segment normally. If the > segment should not be mapped, -EREMOTEIO is returned. > > This helper uses a state structure to track the changes to the > pgmap across calls and avoid needing to lookup into the xarray for > every page. > > Also add pci_p2pdma_map_bus_segment() which is useful for IOMMU > dma_map_sg() implementations where the sg segment containing the page > differs from the sg segment containing the DMA address. > > Signed-off-by: Logan Gunthorpe Acked-by: Bjorn Helgaas Ditto. > --- > drivers/pci/p2pdma.c | 59 ++++++++++++++++++++++++++++++++++++++ > include/linux/pci-p2pdma.h | 21 ++++++++++++++ > 2 files changed, 80 insertions(+) > > diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c > index b656d8c801a7..58c34f1f1473 100644 > --- a/drivers/pci/p2pdma.c > +++ b/drivers/pci/p2pdma.c > @@ -943,6 +943,65 @@ void pci_p2pdma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg, > } > EXPORT_SYMBOL_GPL(pci_p2pdma_unmap_sg_attrs); > > +/** > + * pci_p2pdma_map_segment - map an sg segment determining the mapping type > + * @state: State structure that should be declared outside of the for_each_sg() > + * loop and initialized to zero. > + * @dev: DMA device that's doing the mapping operation > + * @sg: scatterlist segment to map > + * > + * This is a helper to be used by non-iommu dma_map_sg() implementations where > + * the sg segment is the same for the page_link and the dma_address. s/non-iommu/non-IOMMU/ > + * > + * Attempt to map a single segment in an SGL with the PCI bus address. > + * The segment must point to a PCI P2PDMA page and thus must be > + * wrapped in a is_pci_p2pdma_page(sg_page(sg)) check. > + * > + * Returns the type of mapping used and maps the page if the type is > + * PCI_P2PDMA_MAP_BUS_ADDR. > + */ > +enum pci_p2pdma_map_type > +pci_p2pdma_map_segment(struct pci_p2pdma_map_state *state, struct device *dev, > + struct scatterlist *sg) > +{ > + if (state->pgmap != sg_page(sg)->pgmap) { > + state->pgmap = sg_page(sg)->pgmap; > + state->map = pci_p2pdma_map_type(state->pgmap, dev); > + state->bus_off = to_p2p_pgmap(state->pgmap)->bus_offset; > + } > + > + if (state->map == PCI_P2PDMA_MAP_BUS_ADDR) { > + sg->dma_address = sg_phys(sg) + state->bus_off; > + sg_dma_len(sg) = sg->length; > + sg_dma_mark_pci_p2pdma(sg); > + } > + > + return state->map; > +} > + > +/** > + * pci_p2pdma_map_bus_segment - map an sg segment pre determined to > + * be mapped with PCI_P2PDMA_MAP_BUS_ADDR > + * @pg_sg: scatterlist segment with the page to map > + * @dma_sg: scatterlist segment to assign a dma address to s/dma address/DMA address/, also below > + * > + * This is a helper for iommu dma_map_sg() implementations when the > + * segment for the dma address differs from the segment containing the > + * source page. > + * > + * pci_p2pdma_map_type() must have already been called on the pg_sg and > + * returned PCI_P2PDMA_MAP_BUS_ADDR. > + */ > +void pci_p2pdma_map_bus_segment(struct scatterlist *pg_sg, > + struct scatterlist *dma_sg) > +{ > + struct pci_p2pdma_pagemap *pgmap = to_p2p_pgmap(sg_page(pg_sg)->pgmap); > + > + dma_sg->dma_address = sg_phys(pg_sg) + pgmap->bus_offset; > + sg_dma_len(dma_sg) = pg_sg->length; > + sg_dma_mark_pci_p2pdma(dma_sg); > +} > + > /** > * pci_p2pdma_enable_store - parse a configfs/sysfs attribute store > * to enable p2pdma > diff --git a/include/linux/pci-p2pdma.h b/include/linux/pci-p2pdma.h > index caac2d023f8f..e5a8d5bc0f51 100644 > --- a/include/linux/pci-p2pdma.h > +++ b/include/linux/pci-p2pdma.h > @@ -13,6 +13,12 @@ > > #include > > +struct pci_p2pdma_map_state { > + struct dev_pagemap *pgmap; > + int map; > + u64 bus_off; > +}; > + > struct block_device; > struct scatterlist; > > @@ -70,6 +76,11 @@ int pci_p2pdma_map_sg_attrs(struct device *dev, struct scatterlist *sg, > int nents, enum dma_data_direction dir, unsigned long attrs); > void pci_p2pdma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg, > int nents, enum dma_data_direction dir, unsigned long attrs); > +enum pci_p2pdma_map_type > +pci_p2pdma_map_segment(struct pci_p2pdma_map_state *state, struct device *dev, > + struct scatterlist *sg); > +void pci_p2pdma_map_bus_segment(struct scatterlist *pg_sg, > + struct scatterlist *dma_sg); > int pci_p2pdma_enable_store(const char *page, struct pci_dev **p2p_dev, > bool *use_p2pdma); > ssize_t pci_p2pdma_enable_show(char *page, struct pci_dev *p2p_dev, > @@ -135,6 +146,16 @@ static inline void pci_p2pdma_unmap_sg_attrs(struct device *dev, > unsigned long attrs) > { > } > +static inline enum pci_p2pdma_map_type > +pci_p2pdma_map_segment(struct pci_p2pdma_map_state *state, struct device *dev, > + struct scatterlist *sg) > +{ > + return PCI_P2PDMA_MAP_NOT_SUPPORTED; > +} > +static inline void pci_p2pdma_map_bus_segment(struct scatterlist *pg_sg, > + struct scatterlist *dma_sg) > +{ > +} > static inline int pci_p2pdma_enable_store(const char *page, > struct pci_dev **p2p_dev, bool *use_p2pdma) > { > -- > 2.30.2 >