From patchwork Thu Jan 26 14:16:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 13117192 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id A5088C05027 for ; Thu, 26 Jan 2023 14:16:44 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 2FC3C6B0072; Thu, 26 Jan 2023 09:16:44 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 284166B0073; Thu, 26 Jan 2023 09:16:44 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 0FE388E0001; Thu, 26 Jan 2023 09:16:44 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0012.hostedemail.com [216.40.44.12]) by kanga.kvack.org (Postfix) with ESMTP id 01D446B0072 for ; Thu, 26 Jan 2023 09:16:43 -0500 (EST) Received: from smtpin26.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id BE86FAB2A3 for ; Thu, 26 Jan 2023 14:16:43 +0000 (UTC) X-FDA: 80397151086.26.D724A17 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by imf01.hostedemail.com (Postfix) with ESMTP id 72F614002C for ; Thu, 26 Jan 2023 14:16:40 +0000 (UTC) Authentication-Results: imf01.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=iQnq7a5M; spf=pass (imf01.hostedemail.com: domain of dhowells@redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=dhowells@redhat.com; dmarc=pass (policy=none) header.from=redhat.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1674742600; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=E9Jt6FaYFdS1OFI4/wM9JLR5TBUxMH/4qOao0tXSDe4=; b=yhwHc7reNqrS4JdeR/VOGVrYYAFvtzsLiGY3KVTtC1pWpug4jcVYyfQCv4tEh9+F1pLa6x gZ/HaQ6M4jXKIa2bcU/HRUX4DM7spi2THvnqFtI/u5/fsdw0NOl07whe1oJkXIN59LMNTg fZz+gcKALdK4FInBnm2yQKXs8Ugxl7Y= ARC-Authentication-Results: i=1; imf01.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=iQnq7a5M; spf=pass (imf01.hostedemail.com: domain of dhowells@redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=dhowells@redhat.com; dmarc=pass (policy=none) header.from=redhat.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1674742600; a=rsa-sha256; cv=none; b=kAtn4wSHVCeTCG4zGHac/KDvrvOSlxbAtUC/YuK1F0s6r+n7dAZ2sesQ1FxDZccDmy/fh3 hLYrM655jW0j27zKehh/+ePFeewVd/gsh1rSKO6Rn95+ye/+QCBp6HT3mLEEcl8kAqOY55 INgYYhi3cYKtvayG1shMqJkxJdpmi/0= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1674742599; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=E9Jt6FaYFdS1OFI4/wM9JLR5TBUxMH/4qOao0tXSDe4=; b=iQnq7a5MjRdC8ulKtVRgk5PTV4F3wVNHdmMNYttKsfsqe9jRLuNmFAbNRzXQjP6HYsITn+ virXM7QSkSz2DD7oq7mVb0SE2hflXwRoz42PNbvv5qE7wIue7hr6San/bcz+W2VeHvmDp9 8awtpJseiC+dwo0Fmk6p76IIRIe5mho= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-20-ZJTJgo9oNrO2PTfmKjBjXw-1; Thu, 26 Jan 2023 09:16:36 -0500 X-MC-Unique: ZJTJgo9oNrO2PTfmKjBjXw-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 7C84E18E0923; Thu, 26 Jan 2023 14:16:35 +0000 (UTC) Received: from warthog.procyon.org.uk.com (unknown [10.33.36.97]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7288DC15BA0; Thu, 26 Jan 2023 14:16:33 +0000 (UTC) From: David Howells To: Al Viro , Christoph Hellwig Cc: David Howells , Matthew Wilcox , Jens Axboe , Jan Kara , Jeff Layton , David Hildenbrand , Jason Gunthorpe , Logan Gunthorpe , linux-fsdevel@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Christoph Hellwig , John Hubbard Subject: [PATCH v11 1/8] iov_iter: Define flags to qualify page extraction. Date: Thu, 26 Jan 2023 14:16:19 +0000 Message-Id: <20230126141626.2809643-2-dhowells@redhat.com> In-Reply-To: <20230126141626.2809643-1-dhowells@redhat.com> References: <20230126141626.2809643-1-dhowells@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.8 X-Rspamd-Server: rspam05 X-Rspamd-Queue-Id: 72F614002C X-Stat-Signature: ez6p8p1xshg5fua9yyg447fun8q9j3uy X-Rspam-User: X-HE-Tag: 1674742600-110134 X-HE-Meta: U2FsdGVkX186+TIv7tNz/la1ABxWzkb0QqnwOYdGRfOfA/gL9+0Po9/gkWpPub91NjdGXLVJ5OGZGxT44qSu2E7Jv0hcILS86yQxgiw+ETFOY2zssqp58fQXM8X/U65bEybMkdn2bdQArxqLJsPrMFlWLfabUr0xFmxJXc5CqE0nmw5MJ99R6+lRzHGZ0CDAFOASJ81oGSSA+kV91Lsn04aOoldROMFK1qcG1la8/WjyoN9mWMVzKF2MOD2yO1NMTyA3qNfCsBOWu8o72QNmiHbQFEENQkT81pJ+eSpfUUGLlk8zShHiTyXHIhUDe1lrLa6BfLQtDqZDPDDSNC/TrWg9UlBmRPwyOvcLfIN0Tll0qsHfp9Wbvpb+W5s/0hQsYmkahztRUYjw/DD1eUFdvlvIcex8gY/vlqGjUVd2cyu18m/VgMklvNyDkyoAVPnH3RWbKvgd3q94supnUyXcoujVLJApx3Po8MQY531FdqS8c8appVv6by2nTHq37pWL4/paINdrIGozcvJdvZUXVJM3ejcIcucxsZTyy/wqDp+9jH0ipgsDLeHcmNs0qmZGijAdwdDfOp+3mh5ty/U5a/mcDefxU63T1bl8VOhPwwDH7jubMrI3+QnCjQyluJnaQadrWyT5ULCFKw2ktC/WQS4eJy+UiCMPBPRljU3fcD6zJBJ1HgUQG1+o7GxEsRkSHU5DaSj+MKvE+NN5HgQyD1OlIvA9F3eKnFBqJc0yw8dDSCOcLbGxTjz4NAi5tuqcuuF3TlN4jUvCaEL0Tbztgu5H1tkm57I+i3KzR9OXiF4fyU/nSzOcqhnWElfXzbdXMDCZlbvasPRDY4I/LEujH6UW7l0jCOC4JzyyCHftgqrylE/W5RHI7fCw1N25mOI3Y38VX0i2jxUL1dYHg/PJaAUNXOXy0agQl9vafJJJFAHm+HwlxHh7AtbUo8/4o3QYUmHAOnWLBi+Zgrqw6vJ ei37YrzP H31wslI7qMH5hXP6PjnBnKEdMiZS/dSlrAO//vezO8YLoFddD80JkPNSZ8/c8O8mhmbWtZWuQD4PQu+CzMR7H/EBZeljdZao+iHfb5M6zmy6fzva+UceOUk8pKtFb4joRJR3pSsZnZ9zhwt+px92btYpIM0vfvFUIJ3SrxSoXQBkHYYHHL0gejSiQ3DP9EPjeqsBFgqF4DE6mlNSj+7GUcRzs+SUPqphsYD54GtrYQc0ju70ALnA7T1NVBanFsRE85sLkXZBceDaEyge4E891rbifJw1HsMQduzicW5ZqhgwuTiJzg6xo0rYhDrizvbAtZZouMUg0liB6IjpZyZ4UIYV3w5wdgLFRQVrp+qtPP0np5utBVlYX6BHmy5WTmQ6wo3nZ9vlKYj26OI8qGD41vrBHkvd+xipfjS94k6CZt2vTVOxJTQm2+ndUnWVbzuggfgJl X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Define flags to qualify page extraction to pass into iov_iter_*_pages*() rather than passing in FOLL_* flags. For now only a flag to allow peer-to-peer DMA is supported. Signed-off-by: David Howells Reviewed-by: Christoph Hellwig Reviewed-by: John Hubbard cc: Al Viro cc: Jens Axboe cc: Logan Gunthorpe cc: linux-fsdevel@vger.kernel.org cc: linux-block@vger.kernel.org --- Notes: ver #11) - Use __bitwise for the extraction flags ver #9) - Change extract_flags to extraction_flags. ver #7) - Don't use FOLL_* as a parameter, but rather define constants specifically to use with iov_iter_*_pages*(). - Drop the I/O direction constants for now. block/bio.c | 6 +++--- block/blk-map.c | 8 ++++---- include/linux/uio.h | 10 ++++++++-- lib/iov_iter.c | 14 ++++++++------ 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/block/bio.c b/block/bio.c index ab59a491a883..b97f3991c904 100644 --- a/block/bio.c +++ b/block/bio.c @@ -1245,11 +1245,11 @@ static int bio_iov_add_zone_append_page(struct bio *bio, struct page *page, */ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter) { + iov_iter_extraction_t extraction_flags = 0; unsigned short nr_pages = bio->bi_max_vecs - bio->bi_vcnt; unsigned short entries_left = bio->bi_max_vecs - bio->bi_vcnt; struct bio_vec *bv = bio->bi_io_vec + bio->bi_vcnt; struct page **pages = (struct page **)bv; - unsigned int gup_flags = 0; ssize_t size, left; unsigned len, i = 0; size_t offset, trim; @@ -1264,7 +1264,7 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter) pages += entries_left * (PAGE_PTRS_PER_BVEC - 1); if (bio->bi_bdev && blk_queue_pci_p2pdma(bio->bi_bdev->bd_disk->queue)) - gup_flags |= FOLL_PCI_P2PDMA; + extraction_flags |= ITER_ALLOW_P2PDMA; /* * Each segment in the iov is required to be a block size multiple. @@ -1275,7 +1275,7 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter) */ size = iov_iter_get_pages(iter, pages, UINT_MAX - bio->bi_iter.bi_size, - nr_pages, &offset, gup_flags); + nr_pages, &offset, extraction_flags); if (unlikely(size <= 0)) return size ? size : -EFAULT; diff --git a/block/blk-map.c b/block/blk-map.c index 19940c978c73..080dd60485be 100644 --- a/block/blk-map.c +++ b/block/blk-map.c @@ -265,9 +265,9 @@ static struct bio *blk_rq_map_bio_alloc(struct request *rq, static int bio_map_user_iov(struct request *rq, struct iov_iter *iter, gfp_t gfp_mask) { + iov_iter_extraction_t extraction_flags = 0; unsigned int max_sectors = queue_max_hw_sectors(rq->q); unsigned int nr_vecs = iov_iter_npages(iter, BIO_MAX_VECS); - unsigned int gup_flags = 0; struct bio *bio; int ret; int j; @@ -280,7 +280,7 @@ static int bio_map_user_iov(struct request *rq, struct iov_iter *iter, return -ENOMEM; if (blk_queue_pci_p2pdma(rq->q)) - gup_flags |= FOLL_PCI_P2PDMA; + extraction_flags |= ITER_ALLOW_P2PDMA; while (iov_iter_count(iter)) { struct page **pages, *stack_pages[UIO_FASTIOV]; @@ -291,10 +291,10 @@ static int bio_map_user_iov(struct request *rq, struct iov_iter *iter, if (nr_vecs <= ARRAY_SIZE(stack_pages)) { pages = stack_pages; bytes = iov_iter_get_pages(iter, pages, LONG_MAX, - nr_vecs, &offs, gup_flags); + nr_vecs, &offs, extraction_flags); } else { bytes = iov_iter_get_pages_alloc(iter, &pages, - LONG_MAX, &offs, gup_flags); + LONG_MAX, &offs, extraction_flags); } if (unlikely(bytes <= 0)) { ret = bytes ? bytes : -EFAULT; diff --git a/include/linux/uio.h b/include/linux/uio.h index 9f158238edba..bf77cd3d5fb1 100644 --- a/include/linux/uio.h +++ b/include/linux/uio.h @@ -13,6 +13,8 @@ struct page; struct pipe_inode_info; +typedef unsigned int iov_iter_extraction_t; + struct kvec { void *iov_base; /* and that should *never* hold a userland pointer */ size_t iov_len; @@ -252,12 +254,12 @@ void iov_iter_xarray(struct iov_iter *i, unsigned int direction, struct xarray * loff_t start, size_t count); ssize_t iov_iter_get_pages(struct iov_iter *i, struct page **pages, size_t maxsize, unsigned maxpages, size_t *start, - unsigned gup_flags); + iov_iter_extraction_t extraction_flags); ssize_t iov_iter_get_pages2(struct iov_iter *i, struct page **pages, size_t maxsize, unsigned maxpages, size_t *start); ssize_t iov_iter_get_pages_alloc(struct iov_iter *i, struct page ***pages, size_t maxsize, size_t *start, - unsigned gup_flags); + iov_iter_extraction_t extraction_flags); ssize_t iov_iter_get_pages_alloc2(struct iov_iter *i, struct page ***pages, size_t maxsize, size_t *start); int iov_iter_npages(const struct iov_iter *i, int maxpages); @@ -360,4 +362,8 @@ static inline void iov_iter_ubuf(struct iov_iter *i, unsigned int direction, }; } +/* Flags for iov_iter_get/extract_pages*() */ +/* Allow P2PDMA on the extracted pages */ +#define ITER_ALLOW_P2PDMA ((__force iov_iter_extraction_t)0x01) + #endif diff --git a/lib/iov_iter.c b/lib/iov_iter.c index f9a3ff37ecd1..553afc870866 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -1432,9 +1432,9 @@ static struct page *first_bvec_segment(const struct iov_iter *i, static ssize_t __iov_iter_get_pages_alloc(struct iov_iter *i, struct page ***pages, size_t maxsize, unsigned int maxpages, size_t *start, - unsigned int gup_flags) + iov_iter_extraction_t extraction_flags) { - unsigned int n; + unsigned int n, gup_flags = 0; if (maxsize > i->count) maxsize = i->count; @@ -1442,6 +1442,8 @@ static ssize_t __iov_iter_get_pages_alloc(struct iov_iter *i, return 0; if (maxsize > MAX_RW_COUNT) maxsize = MAX_RW_COUNT; + if (extraction_flags & ITER_ALLOW_P2PDMA) + gup_flags |= FOLL_PCI_P2PDMA; if (likely(user_backed_iter(i))) { unsigned long addr; @@ -1495,14 +1497,14 @@ static ssize_t __iov_iter_get_pages_alloc(struct iov_iter *i, ssize_t iov_iter_get_pages(struct iov_iter *i, struct page **pages, size_t maxsize, unsigned maxpages, - size_t *start, unsigned gup_flags) + size_t *start, iov_iter_extraction_t extraction_flags) { if (!maxpages) return 0; BUG_ON(!pages); return __iov_iter_get_pages_alloc(i, &pages, maxsize, maxpages, - start, gup_flags); + start, extraction_flags); } EXPORT_SYMBOL_GPL(iov_iter_get_pages); @@ -1515,14 +1517,14 @@ EXPORT_SYMBOL(iov_iter_get_pages2); ssize_t iov_iter_get_pages_alloc(struct iov_iter *i, struct page ***pages, size_t maxsize, - size_t *start, unsigned gup_flags) + size_t *start, iov_iter_extraction_t extraction_flags) { ssize_t len; *pages = NULL; len = __iov_iter_get_pages_alloc(i, pages, maxsize, ~0U, start, - gup_flags); + extraction_flags); if (len <= 0) { kvfree(*pages); *pages = NULL;