Linux-Fsdevel Archive on lore.kernel.org
help / color / mirror / Atom feed
From: Matthew Wilcox <willy@infradead.org>
To: linux-fsdevel@vger.kernel.org
Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org
Subject: [PATCH v6 18/51] mm: Support THPs in zero_user_segments
Date: Wed, 10 Jun 2020 13:13:12 -0700	[thread overview]
Message-ID: <20200610201345.13273-19-willy@infradead.org> (raw)
In-Reply-To: <20200610201345.13273-1-willy@infradead.org>

From: "Matthew Wilcox (Oracle)" <willy@infradead.org>

We can only kmap() one subpage of a THP at a time, so loop over all
relevant subpages, skipping ones which don't need to be zeroed.  This is
too large to inline when THPs are enabled and we actually need highmem,
so put it in highmem.c.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
 include/linux/highmem.h | 11 ++++++--
 mm/highmem.c            | 62 +++++++++++++++++++++++++++++++++++++++--
 2 files changed, 68 insertions(+), 5 deletions(-)

diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index d6e82e3de027..f05589513103 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -284,13 +284,17 @@ static inline void clear_highpage(struct page *page)
 	kunmap_atomic(kaddr);
 }
 
+#if defined(CONFIG_HIGHMEM) && defined(CONFIG_TRANSPARENT_HUGEPAGE)
+void zero_user_segments(struct page *page, unsigned start1, unsigned end1,
+		unsigned start2, unsigned end2);
+#else /* !HIGHMEM || !TRANSPARENT_HUGEPAGE */
 static inline void zero_user_segments(struct page *page,
-	unsigned start1, unsigned end1,
-	unsigned start2, unsigned end2)
+		unsigned start1, unsigned end1,
+		unsigned start2, unsigned end2)
 {
 	void *kaddr = kmap_atomic(page);
 
-	BUG_ON(end1 > PAGE_SIZE || end2 > PAGE_SIZE);
+	BUG_ON(end1 > thp_size(page) || end2 > thp_size(page));
 
 	if (end1 > start1)
 		memset(kaddr + start1, 0, end1 - start1);
@@ -301,6 +305,7 @@ static inline void zero_user_segments(struct page *page,
 	kunmap_atomic(kaddr);
 	flush_dcache_page(page);
 }
+#endif /* !HIGHMEM || !TRANSPARENT_HUGEPAGE */
 
 static inline void zero_user_segment(struct page *page,
 	unsigned start, unsigned end)
diff --git a/mm/highmem.c b/mm/highmem.c
index 64d8dea47dd1..686cae2f1ba5 100644
--- a/mm/highmem.c
+++ b/mm/highmem.c
@@ -367,9 +367,67 @@ void kunmap_high(struct page *page)
 	if (need_wakeup)
 		wake_up(pkmap_map_wait);
 }
-
 EXPORT_SYMBOL(kunmap_high);
-#endif
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+void zero_user_segments(struct page *page, unsigned start1, unsigned end1,
+		unsigned start2, unsigned end2)
+{
+	unsigned int i;
+
+	BUG_ON(end1 > thp_size(page) || end2 > thp_size(page));
+
+	for (i = 0; i < thp_nr_pages(page); i++) {
+		void *kaddr;
+		unsigned this_end;
+
+		if (end1 == 0 && start2 >= PAGE_SIZE) {
+			start2 -= PAGE_SIZE;
+			end2 -= PAGE_SIZE;
+			continue;
+		}
+
+		if (start1 >= PAGE_SIZE) {
+			start1 -= PAGE_SIZE;
+			end1 -= PAGE_SIZE;
+			if (start2) {
+				start2 -= PAGE_SIZE;
+				end2 -= PAGE_SIZE;
+			}
+			continue;
+		}
+
+		kaddr = kmap_atomic(page + i);
+
+		this_end = min_t(unsigned, end1, PAGE_SIZE);
+		if (end1 > start1)
+			memset(kaddr + start1, 0, this_end - start1);
+		end1 -= this_end;
+		start1 = 0;
+
+		if (start2 >= PAGE_SIZE) {
+			start2 -= PAGE_SIZE;
+			end2 -= PAGE_SIZE;
+		} else {
+			this_end = min_t(unsigned, end2, PAGE_SIZE);
+			if (end2 > start2)
+				memset(kaddr + start2, 0, this_end - start2);
+			end2 -= this_end;
+			start2 = 0;
+		}
+
+		kunmap_atomic(kaddr);
+
+		if (!end1 && !end2)
+			break;
+	}
+	flush_dcache_page(page);
+
+	BUG_ON((start1 | start2 | end1 | end2) != 0);
+}
+EXPORT_SYMBOL(zero_user_segments);
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+#endif /* CONFIG_HIGHMEM */
 
 #if defined(HASHED_PAGE_VIRTUAL)
 
-- 
2.26.2


  parent reply	other threads:[~2020-06-10 20:17 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-10 20:12 [RFC v6 00/51] Large pages in the page cache Matthew Wilcox
2020-06-10 20:12 ` [PATCH v6 01/51] mm: Print head flags in dump_page Matthew Wilcox
2020-06-10 20:12 ` [PATCH v6 02/51] mm: Print the inode number " Matthew Wilcox
2020-06-10 20:12 ` [PATCH v6 03/51] mm: Print hashed address of struct page Matthew Wilcox
2020-06-10 20:12 ` [PATCH v6 04/51] mm: Move PageDoubleMap bit Matthew Wilcox
2020-06-11 15:03   ` Zi Yan
2020-06-10 20:12 ` [PATCH v6 05/51] mm: Simplify PageDoubleMap with PF_SECOND policy Matthew Wilcox
2020-06-11 15:14   ` Zi Yan
2020-06-10 20:13 ` [PATCH v6 06/51] mm: Store compound_nr as well as compound_order Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 07/51] mm: Move page-flags include to top of file Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 08/51] mm: Add thp_order Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 09/51] mm: Add thp_size Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 10/51] mm: Replace hpage_nr_pages with thp_nr_pages Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 11/51] mm: Add thp_head Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 12/51] mm: Introduce offset_in_thp Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 13/51] mm: Support arbitrary THP sizes Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 14/51] fs: Add a filesystem flag for THPs Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 15/51] fs: Do not update nr_thps for mappings which support THPs Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 16/51] fs: Introduce i_blocks_per_page Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 17/51] fs: Make page_mkwrite_check_truncate thp-aware Matthew Wilcox
2020-06-10 20:13 ` Matthew Wilcox [this message]
2020-06-10 20:13 ` [PATCH v6 19/51] mm: Zero the head page, not the tail page Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 20/51] block: Add bio_for_each_thp_segment_all Matthew Wilcox
2020-06-11 18:20   ` Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 21/51] block: Support THPs in page_is_mergeable Matthew Wilcox
2020-06-12 16:17   ` Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 22/51] iomap: Support arbitrarily many blocks per page Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 23/51] iomap: Support THPs in iomap_adjust_read_range Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 24/51] iomap: Support THPs in invalidatepage Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 25/51] iomap: Support THPs in read paths Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 26/51] iomap: Convert iomap_write_end types Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 27/51] iomap: Change calling convention for zeroing Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 28/51] iomap: Change iomap_write_begin calling convention Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 29/51] iomap: Support THPs in write paths Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 30/51] iomap: Inline data shouldn't see THPs Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 31/51] iomap: Handle tail pages in iomap_page_mkwrite Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 32/51] xfs: Support THPs Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 33/51] mm: Make prep_transhuge_page return its argument Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 34/51] mm: Add __page_cache_alloc_order Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 35/51] mm: Allow THPs to be added to the page cache Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 36/51] mm: Allow THPs to be removed from " Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 37/51] mm: Remove page fault assumption of compound page size Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 38/51] mm: Fix total_mapcount assumption of " Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 39/51] mm: Remove assumptions of THP size Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 40/51] mm: Avoid splitting THPs Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 41/51] mm: Fix truncation for pages of arbitrary size Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 42/51] mm: Handle truncates that split THPs Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 43/51] mm: Support storing shadow entries for THPs Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 44/51] mm: Support retrieving tail pages from the page cache Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 45/51] mm: Support tail pages in wait_for_stable_page Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 46/51] mm: Add DEFINE_READAHEAD Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 47/51] mm: Make page_cache_readahead_unbounded take a readahead_control Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 48/51] mm: Make __do_page_cache_readahead " Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 49/51] mm: Allow PageReadahead to be set on head pages Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 50/51] mm: Add THP readahead Matthew Wilcox
2020-06-10 20:13 ` [PATCH v6 51/51] mm: Align THP mappings for non-DAX Matthew Wilcox
2020-06-11  6:59 ` [RFC v6 00/51] Large pages in the page cache Christoph Hellwig
2020-06-11 11:24   ` Matthew Wilcox
2020-06-15 13:32     ` Christoph Hellwig
2020-06-14 16:26 ` Matthew Wilcox

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200610201345.13273-19-willy@infradead.org \
    --to=willy@infradead.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --subject='Re: [PATCH v6 18/51] mm: Support THPs in zero_user_segments' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).