From nobody Thu Nov 14 04:33:44 2024 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 094DAC05027 for ; Tue, 14 Feb 2023 17:16:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232014AbjBNRQM (ORCPT ); Tue, 14 Feb 2023 12:16:12 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41588 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232106AbjBNRPP (ORCPT ); Tue, 14 Feb 2023 12:15:15 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D108B274BD for ; Tue, 14 Feb 2023 09:14:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1676394860; 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=Q5bJAUy0Yf/xIkHbL0gYjIax658ix+8tiANnbR9foj4=; b=Tui+ndrQCX+jhiLls7YdprYH7VbpNEBjKwA8mHPuK+nNt1lxWBm7myryx5yYeaRlVxI+1s 6QZebQ5Q4hpivYVNo3szCKWTHgpvPSnk3xNHf1jdBbhhsc7DV5uUAq8luGLH1IaaZcbZog ENhYI9gSYzzXdl5WcqWOgYzC2SVC5PA= 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-411-XEGHYl5VN7igzLHfz7WV0g-1; Tue, 14 Feb 2023 12:14:14 -0500 X-MC-Unique: XEGHYl5VN7igzLHfz7WV0g-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 9EDA5800050; Tue, 14 Feb 2023 17:14:13 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.33.36.24]) by smtp.corp.redhat.com (Postfix) with ESMTP id A9D902026D4B; Tue, 14 Feb 2023 17:14:11 +0000 (UTC) From: David Howells To: Jens Axboe , Al Viro , Christoph Hellwig Cc: David Howells , Matthew Wilcox , Jan Kara , Jeff Layton , David Hildenbrand , Jason Gunthorpe , Logan Gunthorpe , Hillf Danton , 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 v14 10/17] iov_iter: Define flags to qualify page extraction. Date: Tue, 14 Feb 2023 17:13:23 +0000 Message-Id: <20230214171330.2722188-11-dhowells@redhat.com> In-Reply-To: <20230214171330.2722188-1-dhowells@redhat.com> References: <20230214171330.2722188-1-dhowells@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.1 on 10.11.54.4 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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 #12) - Use __bitwise for the extraction flags typedef. =20 ver #11) - Use __bitwise for the extraction flags. =20 ver #9) - Change extract_flags to extraction_flags. =20 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 =3D 0; unsigned short nr_pages =3D bio->bi_max_vecs - bio->bi_vcnt; unsigned short entries_left =3D bio->bi_max_vecs - bio->bi_vcnt; struct bio_vec *bv =3D bio->bi_io_vec + bio->bi_vcnt; struct page **pages =3D (struct page **)bv; - unsigned int gup_flags =3D 0; ssize_t size, left; unsigned len, i =3D 0; size_t offset, trim; @@ -1264,7 +1264,7 @@ static int __bio_iov_iter_get_pages(struct bio *bio, = struct iov_iter *iter) pages +=3D entries_left * (PAGE_PTRS_PER_BVEC - 1); =20 if (bio->bi_bdev && blk_queue_pci_p2pdma(bio->bi_bdev->bd_disk->queue)) - gup_flags |=3D FOLL_PCI_P2PDMA; + extraction_flags |=3D ITER_ALLOW_P2PDMA; =20 /* * 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 =3D 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 <=3D 0)) return size ? size : -EFAULT; =20 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 =3D 0; unsigned int max_sectors =3D queue_max_hw_sectors(rq->q); unsigned int nr_vecs =3D iov_iter_npages(iter, BIO_MAX_VECS); - unsigned int gup_flags =3D 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; =20 if (blk_queue_pci_p2pdma(rq->q)) - gup_flags |=3D FOLL_PCI_P2PDMA; + extraction_flags |=3D ITER_ALLOW_P2PDMA; =20 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, struc= t iov_iter *iter, if (nr_vecs <=3D ARRAY_SIZE(stack_pages)) { pages =3D stack_pages; bytes =3D iov_iter_get_pages(iter, pages, LONG_MAX, - nr_vecs, &offs, gup_flags); + nr_vecs, &offs, extraction_flags); } else { bytes =3D iov_iter_get_pages_alloc(iter, &pages, - LONG_MAX, &offs, gup_flags); + LONG_MAX, &offs, extraction_flags); } if (unlikely(bytes <=3D 0)) { ret =3D bytes ? bytes : -EFAULT; diff --git a/include/linux/uio.h b/include/linux/uio.h index dcc0ca5ef491..af70e4c9ea27 100644 --- a/include/linux/uio.h +++ b/include/linux/uio.h @@ -12,6 +12,8 @@ =20 struct page; =20 +typedef unsigned int __bitwise iov_iter_extraction_t; + struct kvec { void *iov_base; /* and that should *never* hold a userland pointer */ size_t iov_len; @@ -238,12 +240,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); @@ -346,4 +348,8 @@ static inline void iov_iter_ubuf(struct iov_iter *i, un= signed int direction, }; } =20 +/* 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 adc5e8aa8ae8..34ee3764d0fa 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -1020,9 +1020,9 @@ static struct page *first_bvec_segment(const struct i= ov_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 =3D 0; =20 if (maxsize > i->count) maxsize =3D i->count; @@ -1030,6 +1030,8 @@ static ssize_t __iov_iter_get_pages_alloc(struct iov_= iter *i, return 0; if (maxsize > MAX_RW_COUNT) maxsize =3D MAX_RW_COUNT; + if (extraction_flags & ITER_ALLOW_P2PDMA) + gup_flags |=3D FOLL_PCI_P2PDMA; =20 if (likely(user_backed_iter(i))) { unsigned long addr; @@ -1081,14 +1083,14 @@ static ssize_t __iov_iter_get_pages_alloc(struct io= v_iter *i, =20 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); =20 return __iov_iter_get_pages_alloc(i, &pages, maxsize, maxpages, - start, gup_flags); + start, extraction_flags); } EXPORT_SYMBOL_GPL(iov_iter_get_pages); =20 @@ -1101,14 +1103,14 @@ EXPORT_SYMBOL(iov_iter_get_pages2); =20 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; =20 *pages =3D NULL; =20 len =3D __iov_iter_get_pages_alloc(i, pages, maxsize, ~0U, start, - gup_flags); + extraction_flags); if (len <=3D 0) { kvfree(*pages); *pages =3D NULL;