[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250306074056.246582-1-s.suk@samsung.com>
Date: Thu, 6 Mar 2025 16:40:56 +0900
From: Sooyong Suk <s.suk@...sung.com>
To: viro@...iv.linux.org.uk, linux-kernel@...r.kernel.org,
akpm@...ux-foundation.org, linux-mm@...ck.org
Cc: jaewon31.kim@...il.com, spssyr@...il.com, Sooyong Suk
<s.suk@...sung.com>
Subject: [RFC PATCH] block, fs: use FOLL_LONGTERM as gup_flags for direct IO
There are GUP references to pages that are serving as direct IO buffers.
Those pages can be allocated from CMA pageblocks despite they can be
pinned until the DIO is completed.
Generally, pinning for each DIO might be considered as a transient
operation as described at the documentation. But if a large amount of
direct IO is requested constantly, this can make pages in CMA pageblocks
pinned and unable to migrate outside of the pageblock, which can result
in CMA allocation failure.
In Android devices, on first boot after OTA, snapuserd requests a huge
amount of direct IO reads which might occasionally disturb CMA
allocations.
To prevent this, use FOLL_LONGTERM as gup_flags for direct IO requests
via blkdev_direct_IO or __iomap_dio_rw by default not to allocate buffer
pages from CMA pageblocks.
Signed-off-by: Sooyong Suk <s.suk@...sung.com>
---
block/bio.c | 2 +-
include/linux/uio.h | 2 ++
lib/iov_iter.c | 2 ++
3 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/block/bio.c b/block/bio.c
index d5bdc31d88d3..683113b3e35a 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1247,7 +1247,7 @@ static unsigned int get_contig_folio_len(unsigned int *num_pages,
*/
static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
{
- iov_iter_extraction_t extraction_flags = 0;
+ iov_iter_extraction_t extraction_flags = ITER_ALLOW_LONGTERM;
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;
diff --git a/include/linux/uio.h b/include/linux/uio.h
index 853f9de5aa05..d1e9174ee29a 100644
--- a/include/linux/uio.h
+++ b/include/linux/uio.h
@@ -377,6 +377,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)
+/* Allow LONGTERM on the extracted pages */
+#define ITER_ALLOW_LONGTERM ((__force iov_iter_extraction_t)0x02)
ssize_t iov_iter_extract_pages(struct iov_iter *i, struct page ***pages,
size_t maxsize, unsigned int maxpages,
diff --git a/lib/iov_iter.c b/lib/iov_iter.c
index 9ec806f989f2..4b5c7c30cd4d 100644
--- a/lib/iov_iter.c
+++ b/lib/iov_iter.c
@@ -1832,6 +1832,8 @@ static ssize_t iov_iter_extract_user_pages(struct iov_iter *i,
gup_flags |= FOLL_WRITE;
if (extraction_flags & ITER_ALLOW_P2PDMA)
gup_flags |= FOLL_PCI_P2PDMA;
+ if (extraction_flags & ITER_ALLOW_LONGTERM)
+ gup_flags |= FOLL_LONGTERM;
if (i->nofault)
gup_flags |= FOLL_NOFAULT;
--
2.25.1
Powered by blists - more mailing lists