From a3b4dac8c77e436bbdc129e208efc6eff21ec979 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 13 Jun 2024 09:33:05 +0200 Subject: [PATCH] 6.6-stable patches added patches: filemap-add-helper-mapping_max_folio_size.patch iomap-fault-in-smaller-chunks-for-non-large-folio-mappings.patch --- ...ap-add-helper-mapping_max_folio_size.patch | 83 +++++++++++++++++++ ...-chunks-for-non-large-folio-mappings.patch | 81 ++++++++++++++++++ queue-6.6/series | 2 + 3 files changed, 166 insertions(+) create mode 100644 queue-6.6/filemap-add-helper-mapping_max_folio_size.patch create mode 100644 queue-6.6/iomap-fault-in-smaller-chunks-for-non-large-folio-mappings.patch diff --git a/queue-6.6/filemap-add-helper-mapping_max_folio_size.patch b/queue-6.6/filemap-add-helper-mapping_max_folio_size.patch new file mode 100644 index 00000000000..bdfc08f8a40 --- /dev/null +++ b/queue-6.6/filemap-add-helper-mapping_max_folio_size.patch @@ -0,0 +1,83 @@ +From 79c137454815ba5554caa8eeb4ad5c94e96e45ce Mon Sep 17 00:00:00 2001 +From: Xu Yang +Date: Tue, 21 May 2024 19:49:38 +0800 +Subject: filemap: add helper mapping_max_folio_size() + +From: Xu Yang + +commit 79c137454815ba5554caa8eeb4ad5c94e96e45ce upstream. + +Add mapping_max_folio_size() to get the maximum folio size for this +pagecache mapping. + +Fixes: 5d8edfb900d5 ("iomap: Copy larger chunks from userspace") +Cc: stable@vger.kernel.org +Reviewed-by: Darrick J. Wong +Signed-off-by: Xu Yang +Link: https://lore.kernel.org/r/20240521114939.2541461-1-xu.yang_2@nxp.com +Reviewed-by: Ritesh Harjani (IBM) +Reviewed-by: Christoph Hellwig +Reviewed-by: Matthew Wilcox (Oracle) +Signed-off-by: Christian Brauner +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/pagemap.h | 34 +++++++++++++++++++++------------- + 1 file changed, 21 insertions(+), 13 deletions(-) + +--- a/include/linux/pagemap.h ++++ b/include/linux/pagemap.h +@@ -327,6 +327,19 @@ static inline void mapping_set_gfp_mask( + m->gfp_mask = mask; + } + ++/* ++ * There are some parts of the kernel which assume that PMD entries ++ * are exactly HPAGE_PMD_ORDER. Those should be fixed, but until then, ++ * limit the maximum allocation order to PMD size. I'm not aware of any ++ * assumptions about maximum order if THP are disabled, but 8 seems like ++ * a good order (that's 1MB if you're using 4kB pages) ++ */ ++#ifdef CONFIG_TRANSPARENT_HUGEPAGE ++#define MAX_PAGECACHE_ORDER HPAGE_PMD_ORDER ++#else ++#define MAX_PAGECACHE_ORDER 8 ++#endif ++ + /** + * mapping_set_large_folios() - Indicate the file supports large folios. + * @mapping: The file. +@@ -353,6 +366,14 @@ static inline bool mapping_large_folio_s + test_bit(AS_LARGE_FOLIO_SUPPORT, &mapping->flags); + } + ++/* Return the maximum folio size for this pagecache mapping, in bytes. */ ++static inline size_t mapping_max_folio_size(struct address_space *mapping) ++{ ++ if (mapping_large_folio_support(mapping)) ++ return PAGE_SIZE << MAX_PAGECACHE_ORDER; ++ return PAGE_SIZE; ++} ++ + static inline int filemap_nr_thps(struct address_space *mapping) + { + #ifdef CONFIG_READ_ONLY_THP_FOR_FS +@@ -511,19 +532,6 @@ static inline void *detach_page_private( + return folio_detach_private(page_folio(page)); + } + +-/* +- * There are some parts of the kernel which assume that PMD entries +- * are exactly HPAGE_PMD_ORDER. Those should be fixed, but until then, +- * limit the maximum allocation order to PMD size. I'm not aware of any +- * assumptions about maximum order if THP are disabled, but 8 seems like +- * a good order (that's 1MB if you're using 4kB pages) +- */ +-#ifdef CONFIG_TRANSPARENT_HUGEPAGE +-#define MAX_PAGECACHE_ORDER HPAGE_PMD_ORDER +-#else +-#define MAX_PAGECACHE_ORDER 8 +-#endif +- + #ifdef CONFIG_NUMA + struct folio *filemap_alloc_folio(gfp_t gfp, unsigned int order); + #else diff --git a/queue-6.6/iomap-fault-in-smaller-chunks-for-non-large-folio-mappings.patch b/queue-6.6/iomap-fault-in-smaller-chunks-for-non-large-folio-mappings.patch new file mode 100644 index 00000000000..cd07f8d32d2 --- /dev/null +++ b/queue-6.6/iomap-fault-in-smaller-chunks-for-non-large-folio-mappings.patch @@ -0,0 +1,81 @@ +From 4e527d5841e24623181edc7fd6f6598ffa810e10 Mon Sep 17 00:00:00 2001 +From: Xu Yang +Date: Tue, 21 May 2024 19:49:39 +0800 +Subject: iomap: fault in smaller chunks for non-large folio mappings + +From: Xu Yang + +commit 4e527d5841e24623181edc7fd6f6598ffa810e10 upstream. + +Since commit (5d8edfb900d5 "iomap: Copy larger chunks from userspace"), +iomap will try to copy in larger chunks than PAGE_SIZE. However, if the +mapping doesn't support large folio, only one page of maximum 4KB will +be created and 4KB data will be writen to pagecache each time. Then, +next 4KB will be handled in next iteration. This will cause potential +write performance problem. + +If chunk is 2MB, total 512 pages need to be handled finally. During this +period, fault_in_iov_iter_readable() is called to check iov_iter readable +validity. Since only 4KB will be handled each time, below address space +will be checked over and over again: + +start end +- +buf, buf+2MB +buf+4KB, buf+2MB +buf+8KB, buf+2MB +... +buf+2044KB buf+2MB + +Obviously the checking size is wrong since only 4KB will be handled each +time. So this will get a correct chunk to let iomap work well in non-large +folio case. + +With this change, the write speed will be stable. Tested on ARM64 device. + +Before: + + - dd if=/dev/zero of=/dev/sda bs=400K count=10485 (334 MB/s) + - dd if=/dev/zero of=/dev/sda bs=800K count=5242 (278 MB/s) + - dd if=/dev/zero of=/dev/sda bs=1600K count=2621 (204 MB/s) + - dd if=/dev/zero of=/dev/sda bs=2200K count=1906 (170 MB/s) + - dd if=/dev/zero of=/dev/sda bs=3000K count=1398 (150 MB/s) + - dd if=/dev/zero of=/dev/sda bs=4500K count=932 (139 MB/s) + +After: + + - dd if=/dev/zero of=/dev/sda bs=400K count=10485 (339 MB/s) + - dd if=/dev/zero of=/dev/sda bs=800K count=5242 (330 MB/s) + - dd if=/dev/zero of=/dev/sda bs=1600K count=2621 (332 MB/s) + - dd if=/dev/zero of=/dev/sda bs=2200K count=1906 (333 MB/s) + - dd if=/dev/zero of=/dev/sda bs=3000K count=1398 (333 MB/s) + - dd if=/dev/zero of=/dev/sda bs=4500K count=932 (333 MB/s) + +Fixes: 5d8edfb900d5 ("iomap: Copy larger chunks from userspace") +Cc: stable@vger.kernel.org +Reviewed-by: Darrick J. Wong +Signed-off-by: Xu Yang +Link: https://lore.kernel.org/r/20240521114939.2541461-2-xu.yang_2@nxp.com +Reviewed-by: Christoph Hellwig +Reviewed-by: Matthew Wilcox (Oracle) +Signed-off-by: Christian Brauner +Signed-off-by: Greg Kroah-Hartman +--- + fs/iomap/buffered-io.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/iomap/buffered-io.c ++++ b/fs/iomap/buffered-io.c +@@ -868,11 +868,11 @@ static size_t iomap_write_end(struct iom + static loff_t iomap_write_iter(struct iomap_iter *iter, struct iov_iter *i) + { + loff_t length = iomap_length(iter); +- size_t chunk = PAGE_SIZE << MAX_PAGECACHE_ORDER; + loff_t pos = iter->pos; + ssize_t written = 0; + long status = 0; + struct address_space *mapping = iter->inode->i_mapping; ++ size_t chunk = mapping_max_folio_size(mapping); + unsigned int bdp_flags = (iter->flags & IOMAP_NOWAIT) ? BDP_ASYNC : 0; + + do { diff --git a/queue-6.6/series b/queue-6.6/series index f38307aa980..6fa0a35be15 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -71,3 +71,5 @@ crypto-ecrdsa-fix-module-auto-load-on-add_key.patch crypto-qat-fix-adf_dev_reset_sync-memory-leak.patch kbuild-remove-support-for-clang-s-thinlto-caching.patch mm-fix-race-between-__split_huge_pmd_locked-and-gup-fast.patch +filemap-add-helper-mapping_max_folio_size.patch +iomap-fault-in-smaller-chunks-for-non-large-folio-mappings.patch -- 2.47.3