From: Ryan Roberts <ryan.roberts@arm.com>
To: Andrew Morton <akpm@linux-foundation.org>,
"Matthew Wilcox (Oracle)" <willy@infradead.org>,
"Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>,
Yin Fengwei <fengwei.yin@intel.com>,
David Hildenbrand <david@redhat.com>, Yu Zhao <yuzhao@google.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>,
Geert Uytterhoeven <geert@linux-m68k.org>,
Christian Borntraeger <borntraeger@linux.ibm.com>,
Sven Schnelle <svens@linux.ibm.com>,
Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
Dave Hansen <dave.hansen@linux.intel.com>,
"H. Peter Anvin" <hpa@zytor.com>
Cc: Ryan Roberts <ryan.roberts@arm.com>,
linux-kernel@vger.kernel.org, linux-mm@kvack.org,
linux-alpha@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, linux-ia64@vger.kernel.org,
linux-m68k@lists.linux-m68k.org, linux-s390@vger.kernel.org
Subject: [PATCH v1 05/10] mm: Implement folio_remove_rmap_range()
Date: Mon, 26 Jun 2023 18:14:25 +0100 [thread overview]
Message-ID: <20230626171430.3167004-6-ryan.roberts@arm.com> (raw)
In-Reply-To: <20230626171430.3167004-1-ryan.roberts@arm.com>
Like page_remove_rmap() but batch-removes the rmap for a range of pages
belonging to a folio, for effciency savings. All pages are accounted as
small pages.
Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
---
include/linux/rmap.h | 2 ++
mm/rmap.c | 62 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 64 insertions(+)
diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index 15433a3d0cbf..50f50e4cb0f8 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -204,6 +204,8 @@ void folio_add_file_rmap_range(struct folio *, struct page *, unsigned int nr,
struct vm_area_struct *, bool compound);
void page_remove_rmap(struct page *, struct vm_area_struct *,
bool compound);
+void folio_remove_rmap_range(struct folio *folio, struct page *page,
+ int nr, struct vm_area_struct *vma);
void hugepage_add_anon_rmap(struct page *, struct vm_area_struct *,
unsigned long address, rmap_t flags);
diff --git a/mm/rmap.c b/mm/rmap.c
index 4050bcea7ae7..ac1d93d43f2b 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1434,6 +1434,68 @@ void page_add_file_rmap(struct page *page, struct vm_area_struct *vma,
folio_add_file_rmap_range(folio, page, nr_pages, vma, compound);
}
+/*
+ * folio_remove_rmap_range - take down pte mappings from a range of pages
+ * belonging to a folio. All pages are accounted as small pages.
+ * @folio: folio that all pages belong to
+ * @page: first page in range to remove mapping from
+ * @nr: number of pages in range to remove mapping from
+ * @vma: the vm area from which the mapping is removed
+ *
+ * The caller needs to hold the pte lock.
+ */
+void folio_remove_rmap_range(struct folio *folio, struct page *page,
+ int nr, struct vm_area_struct *vma)
+{
+ atomic_t *mapped = &folio->_nr_pages_mapped;
+ int nr_unmapped = 0;
+ int nr_mapped;
+ bool last;
+ enum node_stat_item idx;
+
+ VM_BUG_ON_FOLIO(folio_test_hugetlb(folio), folio);
+
+ if (!folio_test_large(folio)) {
+ /* Is this the page's last map to be removed? */
+ last = atomic_add_negative(-1, &page->_mapcount);
+ nr_unmapped = last;
+ } else {
+ for (; nr != 0; nr--, page++) {
+ /* Is this the page's last map to be removed? */
+ last = atomic_add_negative(-1, &page->_mapcount);
+ if (last) {
+ /* Page still mapped if folio mapped entirely */
+ nr_mapped = atomic_dec_return_relaxed(mapped);
+ if (nr_mapped < COMPOUND_MAPPED)
+ nr_unmapped++;
+ }
+ }
+ }
+
+ if (nr_unmapped) {
+ idx = folio_test_anon(folio) ? NR_ANON_MAPPED : NR_FILE_MAPPED;
+ __lruvec_stat_mod_folio(folio, idx, -nr_unmapped);
+
+ /*
+ * Queue anon THP for deferred split if we have just unmapped at
+ * least 1 page, while at least 1 page remains mapped.
+ */
+ if (folio_test_large(folio) && folio_test_anon(folio))
+ if (nr_mapped)
+ deferred_split_folio(folio);
+ }
+
+ /*
+ * It would be tidy to reset folio_test_anon mapping when fully
+ * unmapped, but that might overwrite a racing page_add_anon_rmap
+ * which increments mapcount after us but sets mapping before us:
+ * so leave the reset to free_pages_prepare, and remember that
+ * it's only reliable while mapped.
+ */
+
+ munlock_vma_folio(folio, vma, false);
+}
+
/**
* page_remove_rmap - take down pte mapping from a page
* @page: page to remove mapping from
--
2.25.1
WARNING: multiple messages have this Message-ID (diff)
From: Ryan Roberts <ryan.roberts@arm.com>
To: Andrew Morton <akpm@linux-foundation.org>,
"Matthew Wilcox (Oracle)" <willy@infradead.org>,
"Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>,
Yin Fengwei <fengwei.yin@intel.com>,
David Hildenbrand <david@redhat.com>, Yu Zhao <yuzhao@google.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>,
Geert Uytterhoeven <geert@linux-m68k.org>,
Christian Borntraeger <borntraeger@linux.ibm.com>,
Sven Schnelle <svens@linux.ibm.com>,
Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
Dave Hansen <dave.hansen@linux.intel.com>,
"H. Peter Anvin" <hpa@zytor.com>
Cc: Ryan Roberts <ryan.roberts@arm.com>,
linux-kernel@vger.kernel.org, linux-mm@kvack.org,
linux-alpha@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, linux-ia64@vger.kernel.org,
linux-m68k@lists.linux-m68k.org, linux-s390@vger.kernel.org
Subject: [PATCH v1 05/10] mm: Implement folio_remove_rmap_range()
Date: Mon, 26 Jun 2023 18:14:25 +0100 [thread overview]
Message-ID: <20230626171430.3167004-6-ryan.roberts@arm.com> (raw)
In-Reply-To: <20230626171430.3167004-1-ryan.roberts@arm.com>
Like page_remove_rmap() but batch-removes the rmap for a range of pages
belonging to a folio, for effciency savings. All pages are accounted as
small pages.
Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
---
include/linux/rmap.h | 2 ++
mm/rmap.c | 62 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 64 insertions(+)
diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index 15433a3d0cbf..50f50e4cb0f8 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -204,6 +204,8 @@ void folio_add_file_rmap_range(struct folio *, struct page *, unsigned int nr,
struct vm_area_struct *, bool compound);
void page_remove_rmap(struct page *, struct vm_area_struct *,
bool compound);
+void folio_remove_rmap_range(struct folio *folio, struct page *page,
+ int nr, struct vm_area_struct *vma);
void hugepage_add_anon_rmap(struct page *, struct vm_area_struct *,
unsigned long address, rmap_t flags);
diff --git a/mm/rmap.c b/mm/rmap.c
index 4050bcea7ae7..ac1d93d43f2b 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1434,6 +1434,68 @@ void page_add_file_rmap(struct page *page, struct vm_area_struct *vma,
folio_add_file_rmap_range(folio, page, nr_pages, vma, compound);
}
+/*
+ * folio_remove_rmap_range - take down pte mappings from a range of pages
+ * belonging to a folio. All pages are accounted as small pages.
+ * @folio: folio that all pages belong to
+ * @page: first page in range to remove mapping from
+ * @nr: number of pages in range to remove mapping from
+ * @vma: the vm area from which the mapping is removed
+ *
+ * The caller needs to hold the pte lock.
+ */
+void folio_remove_rmap_range(struct folio *folio, struct page *page,
+ int nr, struct vm_area_struct *vma)
+{
+ atomic_t *mapped = &folio->_nr_pages_mapped;
+ int nr_unmapped = 0;
+ int nr_mapped;
+ bool last;
+ enum node_stat_item idx;
+
+ VM_BUG_ON_FOLIO(folio_test_hugetlb(folio), folio);
+
+ if (!folio_test_large(folio)) {
+ /* Is this the page's last map to be removed? */
+ last = atomic_add_negative(-1, &page->_mapcount);
+ nr_unmapped = last;
+ } else {
+ for (; nr != 0; nr--, page++) {
+ /* Is this the page's last map to be removed? */
+ last = atomic_add_negative(-1, &page->_mapcount);
+ if (last) {
+ /* Page still mapped if folio mapped entirely */
+ nr_mapped = atomic_dec_return_relaxed(mapped);
+ if (nr_mapped < COMPOUND_MAPPED)
+ nr_unmapped++;
+ }
+ }
+ }
+
+ if (nr_unmapped) {
+ idx = folio_test_anon(folio) ? NR_ANON_MAPPED : NR_FILE_MAPPED;
+ __lruvec_stat_mod_folio(folio, idx, -nr_unmapped);
+
+ /*
+ * Queue anon THP for deferred split if we have just unmapped at
+ * least 1 page, while at least 1 page remains mapped.
+ */
+ if (folio_test_large(folio) && folio_test_anon(folio))
+ if (nr_mapped)
+ deferred_split_folio(folio);
+ }
+
+ /*
+ * It would be tidy to reset folio_test_anon mapping when fully
+ * unmapped, but that might overwrite a racing page_add_anon_rmap
+ * which increments mapcount after us but sets mapping before us:
+ * so leave the reset to free_pages_prepare, and remember that
+ * it's only reliable while mapped.
+ */
+
+ munlock_vma_folio(folio, vma, false);
+}
+
/**
* page_remove_rmap - take down pte mapping from a page
* @page: page to remove mapping from
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2023-06-26 17:14 UTC|newest]
Thread overview: 148+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-26 17:14 [PATCH v1 00/10] variable-order, large folios for anonymous memory Ryan Roberts
2023-06-26 17:14 ` Ryan Roberts
2023-06-26 17:14 ` [PATCH v1 01/10] mm: Expose clear_huge_page() unconditionally Ryan Roberts
2023-06-26 17:14 ` Ryan Roberts
2023-06-27 1:55 ` Yu Zhao
2023-06-27 1:55 ` Yu Zhao
2023-06-27 1:55 ` Yu Zhao
2023-06-27 7:21 ` Ryan Roberts
2023-06-27 7:21 ` Ryan Roberts
2023-06-27 7:21 ` Ryan Roberts
2023-06-27 8:29 ` Yu Zhao
2023-06-27 8:29 ` Yu Zhao
2023-06-27 8:29 ` Yu Zhao
2023-06-27 9:41 ` Ryan Roberts
2023-06-27 9:41 ` Ryan Roberts
2023-06-27 9:41 ` Ryan Roberts
2023-06-27 18:26 ` Yu Zhao
2023-06-27 18:26 ` Yu Zhao
2023-06-27 18:26 ` Yu Zhao
2023-06-28 10:56 ` Ryan Roberts
2023-06-28 10:56 ` Ryan Roberts
2023-06-28 10:56 ` Ryan Roberts
2023-06-26 17:14 ` [PATCH v1 02/10] mm: pass gfp flags and order to vma_alloc_zeroed_movable_folio() Ryan Roberts
2023-06-26 17:14 ` Ryan Roberts
2023-06-27 2:27 ` Yu Zhao
2023-06-27 2:27 ` Yu Zhao
2023-06-27 2:27 ` Yu Zhao
2023-06-27 7:27 ` Ryan Roberts
2023-06-27 7:27 ` Ryan Roberts
2023-06-27 7:27 ` Ryan Roberts
2023-06-26 17:14 ` [PATCH v1 03/10] mm: Introduce try_vma_alloc_movable_folio() Ryan Roberts
2023-06-26 17:14 ` Ryan Roberts
2023-06-27 2:34 ` Yu Zhao
2023-06-27 2:34 ` Yu Zhao
2023-06-27 2:34 ` Yu Zhao
2023-06-27 5:29 ` Yu Zhao
2023-06-27 5:29 ` Yu Zhao
2023-06-27 5:29 ` Yu Zhao
2023-06-27 7:56 ` Ryan Roberts
2023-06-27 7:56 ` Ryan Roberts
2023-06-27 7:56 ` Ryan Roberts
2023-06-28 2:32 ` Yin Fengwei
2023-06-28 2:32 ` Yin Fengwei
2023-06-28 2:32 ` Yin Fengwei
2023-06-28 11:06 ` Ryan Roberts
2023-06-28 11:06 ` Ryan Roberts
2023-06-26 17:14 ` [PATCH v1 04/10] mm: Implement folio_add_new_anon_rmap_range() Ryan Roberts
2023-06-26 17:14 ` Ryan Roberts
2023-06-27 7:08 ` Yu Zhao
2023-06-27 7:08 ` Yu Zhao
2023-06-27 7:08 ` Yu Zhao
2023-06-27 8:09 ` Ryan Roberts
2023-06-27 8:09 ` Ryan Roberts
2023-06-27 8:09 ` Ryan Roberts
2023-06-28 2:20 ` Yin Fengwei
2023-06-28 2:20 ` Yin Fengwei
2023-06-28 2:20 ` Yin Fengwei
2023-06-28 11:09 ` Ryan Roberts
2023-06-28 11:09 ` Ryan Roberts
2023-06-28 11:09 ` Ryan Roberts
2023-06-28 2:17 ` Yin Fengwei
2023-06-28 2:17 ` Yin Fengwei
2023-06-28 2:17 ` Yin Fengwei
2023-06-26 17:14 ` Ryan Roberts [this message]
2023-06-26 17:14 ` [PATCH v1 05/10] mm: Implement folio_remove_rmap_range() Ryan Roberts
2023-06-27 3:06 ` Yu Zhao
2023-06-27 3:06 ` Yu Zhao
2023-06-27 3:06 ` Yu Zhao
2023-06-26 17:14 ` [PATCH v1 06/10] mm: Allow deferred splitting of arbitrary large anon folios Ryan Roberts
2023-06-26 17:14 ` Ryan Roberts
2023-06-27 2:54 ` Yu Zhao
2023-06-27 2:54 ` Yu Zhao
2023-06-27 2:54 ` Yu Zhao
2023-06-28 2:43 ` Yin Fengwei
2023-06-28 2:43 ` Yin Fengwei
2023-06-28 2:43 ` Yin Fengwei
2023-06-26 17:14 ` [PATCH v1 07/10] mm: Batch-zap large anonymous folio PTE mappings Ryan Roberts
2023-06-26 17:14 ` Ryan Roberts
2023-06-27 3:04 ` Yu Zhao
2023-06-27 3:04 ` Yu Zhao
2023-06-27 3:04 ` Yu Zhao
2023-06-27 9:46 ` Ryan Roberts
2023-06-27 9:46 ` Ryan Roberts
2023-06-27 9:46 ` Ryan Roberts
2023-06-26 17:14 ` [PATCH v1 08/10] mm: Kconfig hooks to determine max anon folio allocation order Ryan Roberts
2023-06-26 17:14 ` Ryan Roberts
2023-06-27 2:47 ` Yu Zhao
2023-06-27 2:47 ` Yu Zhao
2023-06-27 2:47 ` Yu Zhao
2023-06-27 9:54 ` Ryan Roberts
2023-06-27 9:54 ` Ryan Roberts
2023-06-27 9:54 ` Ryan Roberts
2023-06-29 1:38 ` Yang Shi
2023-06-29 1:38 ` Yang Shi
2023-06-29 1:38 ` Yang Shi
2023-06-29 11:31 ` Ryan Roberts
2023-06-29 11:31 ` Ryan Roberts
2023-06-29 11:31 ` Ryan Roberts
2023-06-26 17:14 ` [PATCH v1 09/10] arm64: mm: Declare support for large anonymous folios Ryan Roberts
2023-06-26 17:14 ` Ryan Roberts
2023-06-27 2:53 ` Yu Zhao
2023-06-27 2:53 ` Yu Zhao
2023-06-27 2:53 ` Yu Zhao
2023-06-26 17:14 ` [PATCH v1 10/10] mm: Allocate large folios for anonymous memory Ryan Roberts
2023-06-26 17:14 ` Ryan Roberts
2023-06-27 3:01 ` Yu Zhao
2023-06-27 3:01 ` Yu Zhao
2023-06-27 3:01 ` Yu Zhao
2023-06-27 9:57 ` Ryan Roberts
2023-06-27 9:57 ` Ryan Roberts
2023-06-27 9:57 ` Ryan Roberts
2023-06-27 18:33 ` Yu Zhao
2023-06-27 18:33 ` Yu Zhao
2023-06-27 18:33 ` Yu Zhao
2023-06-29 2:13 ` Yang Shi
2023-06-29 2:13 ` Yang Shi
2023-06-29 2:13 ` Yang Shi
2023-06-29 11:30 ` Ryan Roberts
2023-06-29 11:30 ` Ryan Roberts
2023-06-29 11:30 ` Ryan Roberts
2023-06-29 17:05 ` Yang Shi
2023-06-29 17:05 ` Yang Shi
2023-06-29 17:05 ` Yang Shi
2023-06-27 3:30 ` [PATCH v1 00/10] variable-order, " Yu Zhao
2023-06-27 3:30 ` Yu Zhao
2023-06-27 3:30 ` Yu Zhao
2023-06-27 7:49 ` Yu Zhao
2023-06-27 7:49 ` Yu Zhao
2023-06-27 7:49 ` Yu Zhao
2023-06-27 9:59 ` Ryan Roberts
2023-06-27 9:59 ` Ryan Roberts
2023-06-27 9:59 ` Ryan Roberts
2023-06-28 18:22 ` Yu Zhao
2023-06-28 18:22 ` Yu Zhao
2023-06-28 23:59 ` Yin Fengwei
2023-06-28 23:59 ` Yin Fengwei
2023-06-28 23:59 ` Yin Fengwei
2023-06-29 0:27 ` Yu Zhao
2023-06-29 0:27 ` Yu Zhao
2023-06-29 0:27 ` Yu Zhao
2023-06-29 0:31 ` Yin Fengwei
2023-06-29 0:31 ` Yin Fengwei
2023-06-29 0:31 ` Yin Fengwei
2023-06-29 15:28 ` Ryan Roberts
2023-06-29 15:28 ` Ryan Roberts
2023-06-29 2:21 ` Yang Shi
2023-06-29 2:21 ` Yang Shi
2023-06-29 2:21 ` Yang Shi
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=20230626171430.3167004-6-ryan.roberts@arm.com \
--to=ryan.roberts@arm.com \
--cc=akpm@linux-foundation.org \
--cc=borntraeger@linux.ibm.com \
--cc=bp@alien8.de \
--cc=catalin.marinas@arm.com \
--cc=dave.hansen@linux.intel.com \
--cc=david@redhat.com \
--cc=fengwei.yin@intel.com \
--cc=geert@linux-m68k.org \
--cc=hpa@zytor.com \
--cc=kirill.shutemov@linux.intel.com \
--cc=linux-alpha@vger.kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-ia64@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-m68k@lists.linux-m68k.org \
--cc=linux-mm@kvack.org \
--cc=linux-s390@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=svens@linux.ibm.com \
--cc=tglx@linutronix.de \
--cc=will@kernel.org \
--cc=willy@infradead.org \
--cc=yuzhao@google.com \
/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
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.