Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp818727pxj; Thu, 13 May 2021 18:35:08 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyw19uO2Xc7iLmAOqEwtg3GC8yYFJw4tz4UdmQwXQksM3VmQUKlww9xgdmpuZYxwutwevOr X-Received: by 2002:a92:d80f:: with SMTP id y15mr37406778ilm.305.1620956108568; Thu, 13 May 2021 18:35:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1620956108; cv=none; d=google.com; s=arc-20160816; b=CxCFr+Bp1NOxzMLJtc1V0jsDxthVASRcc70fA5XTK5yqNOJ3XS8nsWDLkZ3+O6AjvO NO6VdvP38ak38u8rWlc/Gn770VDZ97gJ7ErTtDA0z51gwlbZ7DJaDfZwHJSnJhssij73 GINSRIn1dwDIlyVp72rsJji8X1qtAfIYJ8kOux+46gTeDGhW5+iAveJhGFVMLn8a/J4/ aNzY6hWpDxzRMzE8iI0PtJNuaLoEMbDDP3XA7/rND2R6myv5F1rty/jpvDVChUN9uo0L XL6kBj35/QpmbxxJq8px7qmrquoLjG3D0vprjuozes+B6VyOckgPGDomR6uYz3T+KOnu vvEQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:subject:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:cc:to:from:dkim-signature; bh=/1W3j2Rqe8fHNrWCW7Ouw3jhOc5qpB9v4K7ma+z5lU0=; b=on4MpNr+maudtiwB6jaDsVn/5UwNJK+8CKglTRVQd9YfRCTUe8PJs3RWS2yTwK/iWW EClYzo2NBSxIILKc/r8KxwEZolArT6syvU7BN/X5BLa31SRpFt7EunG33aw61nCMp+34 V1FiNrI8H7iLU+2UK7aPCx8UKFhmOXRQ4uHgCzXHTSv3PhZPaMJP0plNQbhX1Wb2sstB EVVyzbKJ02gVIuTruQJ5BILTBT4CefsU0XiwrQPf6We7UrZyqaVWvKX8Nqgf0WL9yIn8 MFnDZN764R6c1xRzk+AIq657dCLPucM2gbCt6JsAHwitiQqlEzouwUtEoD128zX8oGQ6 UEOg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@deltatee.com header.s=20200525 header.b=Ys4pV10m; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id f11si6235674ila.138.2021.05.13.18.34.54; Thu, 13 May 2021 18:35:08 -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=@deltatee.com header.s=20200525 header.b=Ys4pV10m; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233821AbhEMWeG (ORCPT + 99 others); Thu, 13 May 2021 18:34:06 -0400 Received: from ale.deltatee.com ([204.191.154.188]:59318 "EHLO ale.deltatee.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233699AbhEMWdh (ORCPT ); Thu, 13 May 2021 18:33:37 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=deltatee.com; s=20200525; h=Subject:MIME-Version:References:In-Reply-To: Message-Id:Date:Cc:To:From:content-disposition; bh=/1W3j2Rqe8fHNrWCW7Ouw3jhOc5qpB9v4K7ma+z5lU0=; b=Ys4pV10me/1xi7s30rq3o0HcrG aB4TcV8fdKr8P9FqdAXnC+uJWH4g/DCkVcdltpeEHo7vrxZvLuyJYS04WujHSdisVJ9z+X8xfnm89 nPV6mTDTu7U4R3qCwPPWuVu3Ibr7lluZ+T65TQI2WIzDrri4qiOGtC+/i4ccdOwm9KM5BAwIiU6/M HO3PD6J3YEYP3YgDsDigux3bvRjHMEc2WpNd6x16pgnoatpjC88tIxgg+sOCuGsGDFUGKq0GBVzIM lBOyhE/5f/QD05itfMHhj7v6z9HN4yKV9i+A7RCLLLktp4zHRL+aH/LVbMAvpJTa1c8yLFs6KV/zf GdvxmdxQ==; Received: from cgy1-donard.priv.deltatee.com ([172.16.1.31]) by ale.deltatee.com with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lhJsX-0000nB-BA; Thu, 13 May 2021 16:32:26 -0600 Received: from gunthorp by cgy1-donard.priv.deltatee.com with local (Exim 4.92) (envelope-from ) id 1lhJsG-0001Sq-O9; Thu, 13 May 2021 16:32:08 -0600 From: Logan Gunthorpe To: 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: Stephen Bates , Christoph Hellwig , Dan Williams , Jason Gunthorpe , =?UTF-8?q?Christian=20K=C3=B6nig?= , John Hubbard , Don Dutile , Matthew Wilcox , Daniel Vetter , Jakowski Andrzej , Minturn Dave B , Jason Ekstrand , Dave Hansen , Xiong Jianxin , Bjorn Helgaas , Ira Weiny , Robin Murphy , Logan Gunthorpe Date: Thu, 13 May 2021 16:31:49 -0600 Message-Id: <20210513223203.5542-9-logang@deltatee.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210513223203.5542-1-logang@deltatee.com> References: <20210513223203.5542-1-logang@deltatee.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SA-Exim-Connect-IP: 172.16.1.31 X-SA-Exim-Rcpt-To: linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org, linux-block@vger.kernel.org, linux-pci@vger.kernel.org, linux-mm@kvack.org, iommu@lists.linux-foundation.org, sbates@raithlin.com, hch@lst.de, jgg@ziepe.ca, christian.koenig@amd.com, jhubbard@nvidia.com, ddutile@redhat.com, willy@infradead.org, daniel.vetter@ffwll.ch, jason@jlekstrand.net, dave.hansen@linux.intel.com, helgaas@kernel.org, dan.j.williams@intel.com, andrzej.jakowski@intel.com, dave.b.minturn@intel.com, jianxin.xiong@intel.com, ira.weiny@intel.com, robin.murphy@arm.com, logang@deltatee.com X-SA-Exim-Mail-From: gunthorp@deltatee.com X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on ale.deltatee.com X-Spam-Level: X-Spam-Status: No, score=-6.7 required=5.0 tests=ALL_TRUSTED,BAYES_00, MYRULES_NO_TEXT autolearn=no autolearn_force=no version=3.4.2 Subject: [PATCH v2 08/22] dma-mapping: Allow map_sg() ops to return negative error codes X-SA-Exim-Version: 4.2.1 (built Wed, 08 May 2019 21:11:16 +0000) X-SA-Exim-Scanned: Yes (on ale.deltatee.com) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Allow dma_map_sgtable() to pass errors from the map_sg() ops. This will be required for returning appropriate error codes when mapping P2PDMA memory. Introduce __dma_map_sg_attrs() which will return the raw error code from the map_sg operation (whether it be negative or zero). Then add a dma_map_sg_attrs() wrapper to convert any negative errors to zero to satisfy the existing calling convention. dma_map_sgtable() will convert a zero error return for old map_sg() ops into a -EINVAL return and return any negative errors as reported. This allows map_sg implementations to start returning multiple negative error codes. Legacy map_sg implementations can continue to return zero until they are all converted. Signed-off-by: Logan Gunthorpe --- include/linux/dma-map-ops.h | 8 ++++++-- include/linux/dma-mapping.h | 41 ++++++++++++++++++++++++++++++++----- kernel/dma/mapping.c | 13 +++++------- 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h index 0d53a96a3d64..eaa969be8284 100644 --- a/include/linux/dma-map-ops.h +++ b/include/linux/dma-map-ops.h @@ -41,8 +41,12 @@ struct dma_map_ops { size_t size, enum dma_data_direction dir, unsigned long attrs); /* - * map_sg returns 0 on error and a value > 0 on success. - * It should never return a value < 0. + * map_sg should return a negative error code on error. + * dma_map_sgtable() will return the error code returned and convert + * a zero return (for legacy implementations) into -EINVAL. + * + * dma_map_sg() will always return zero on any negative or zero + * return to satisfy its own calling convention. */ int (*map_sg)(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, unsigned long attrs); diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 183e7103a66d..2b0ecf0aa4df 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -105,7 +105,7 @@ dma_addr_t dma_map_page_attrs(struct device *dev, struct page *page, unsigned long attrs); void dma_unmap_page_attrs(struct device *dev, dma_addr_t addr, size_t size, enum dma_data_direction dir, unsigned long attrs); -int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, +int __dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, unsigned long attrs); void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, @@ -164,7 +164,7 @@ static inline void dma_unmap_page_attrs(struct device *dev, dma_addr_t addr, size_t size, enum dma_data_direction dir, unsigned long attrs) { } -static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, +static inline int __dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, unsigned long attrs) { return 0; @@ -343,6 +343,34 @@ static inline void dma_sync_single_range_for_device(struct device *dev, return dma_sync_single_for_device(dev, addr + offset, size, dir); } +/** + * dma_map_sg_attrs - Map the given buffer for DMA + * @dev: The device for which to perform the DMA operation + * @sg: The sg_table object describing the buffer + * @dir: DMA direction + * @attrs: Optional DMA attributes for the map operation + * + * Maps a buffer described by a scatterlist passed in the sg argument with + * nents segments for the @dir DMA operation by the @dev device. + * + * Returns the number of mapped entries (which can be less than nents) + * on success. Zero is returned for any error. + * + * dma_unmap_sg_attrs() should be used to unmap the buffer with the + * original sg and original nents (not the value returned by this funciton). + */ +static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir, unsigned long attrs) +{ + int ret; + + ret = __dma_map_sg_attrs(dev, sg, nents, dir, attrs); + if (ret < 0) + ret = 0; + + return ret; +} + /** * dma_map_sgtable - Map the given buffer for DMA * @dev: The device for which to perform the DMA operation @@ -357,16 +385,19 @@ static inline void dma_sync_single_range_for_device(struct device *dev, * ownership of the buffer back to the CPU domain before touching the * buffer by the CPU. * - * Returns 0 on success or -EINVAL on error during mapping the buffer. + * Returns 0 on success or a negative error code on error */ static inline int dma_map_sgtable(struct device *dev, struct sg_table *sgt, enum dma_data_direction dir, unsigned long attrs) { int nents; - nents = dma_map_sg_attrs(dev, sgt->sgl, sgt->orig_nents, dir, attrs); - if (nents <= 0) + nents = __dma_map_sg_attrs(dev, sgt->sgl, sgt->orig_nents, dir, attrs); + if (nents == 0) return -EINVAL; + else if (nents < 0) + return nents; + sgt->nents = nents; return 0; } diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c index 2b06a809d0b9..700a2bb7cc9e 100644 --- a/kernel/dma/mapping.c +++ b/kernel/dma/mapping.c @@ -177,11 +177,7 @@ 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. - */ -int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, +int __dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, unsigned long attrs) { const struct dma_map_ops *ops = get_dma_ops(dev); @@ -197,12 +193,13 @@ 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); - debug_dma_map_sg(dev, sg, nents, ents, dir); + + if (ents > 0) + debug_dma_map_sg(dev, sg, nents, ents, dir); return ents; } -EXPORT_SYMBOL(dma_map_sg_attrs); +EXPORT_SYMBOL(__dma_map_sg_attrs); void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, -- 2.20.1