From: Peter Xu <peterx@redhat.com>
To: linux-mm@kvack.org, linux-kernel@vger.kernel.org
Cc: Alistair Popple <apopple@nvidia.com>,
Matthew Wilcox <willy@infradead.org>,
peterx@redhat.com, David Hildenbrand <david@redhat.com>,
Andrea Arcangeli <aarcange@redhat.com>,
Hugh Dickins <hughd@google.com>, Yang Shi <shy828301@gmail.com>,
Vlastimil Babka <vbabka@suse.cz>,
John Hubbard <jhubbard@nvidia.com>,
Andrew Morton <akpm@linux-foundation.org>,
"Kirill A . Shutemov" <kirill@shutemov.name>
Subject: [PATCH v5 3/4] mm: Change zap_details.zap_mapping into even_cows
Date: Thu, 17 Feb 2022 14:07:45 +0800 [thread overview]
Message-ID: <20220217060746.71256-4-peterx@redhat.com> (raw)
In-Reply-To: <20220217060746.71256-1-peterx@redhat.com>
Currently we have a zap_mapping pointer maintained in zap_details, when it
is specified we only want to zap the pages that has the same mapping with
what the caller has specified.
But what we want to do is actually simpler: we want to skip zapping
private (COW-ed) pages in some cases. It comes from unmap_mapping_pages()
where we could have passed in different even_cows values. The other user
is unmap_mapping_folio() where we always want to skip private pages.
According to Hugh, we used a mapping pointer for historical reason, as
explained here:
https://lore.kernel.org/lkml/391aa58d-ce84-9d4-d68d-d98a9c533255@google.com/
Quoting partly from Hugh:
Which raises the question again of why I did not just use a boolean flag
there originally: aah, I think I've found why. In those days there was a
horrible "optimization", for better performance on some benchmark I
guess, which when you read from /dev/zero into a private mapping, would
map the zero page there (look up read_zero_pagealigned() and
zeromap_page_range() if you dare). So there was another category of page
to be skipped along with the anon COWs, and I didn't want multiple tests
in the zap loop, so checking check_mapping against page->mapping did
both. I think nowadays you could do it by checking for PageAnon page (or
genuine swap entry) instead.
This patch replaced the zap_details.zap_mapping pointer into the even_cows
boolean, then we check it against PageAnon.
Suggested-by: Hugh Dickins <hughd@google.com>
Reviewed-by: John Hubbard <jhubbard@nvidia.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
---
mm/memory.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/mm/memory.c b/mm/memory.c
index 3728632ea993..c2defe8a1472 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1309,8 +1309,8 @@ copy_page_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma)
* Parameter block passed down to zap_pte_range in exceptional cases.
*/
struct zap_details {
- struct address_space *zap_mapping; /* Check page->mapping if set */
struct folio *single_folio; /* Locked folio to be unmapped */
+ bool even_cows; /* Zap COWed private pages too? */
};
/* Whether we should zap all COWed (private) pages too */
@@ -1321,13 +1321,10 @@ static inline bool should_zap_cows(struct zap_details *details)
return true;
/* Or, we zap COWed pages only if the caller wants to */
- return !details->zap_mapping;
+ return details->even_cows;
}
-/*
- * We set details->zap_mapping when we want to unmap shared but keep private
- * pages. Return true if we should zap this page, false otherwise.
- */
+/* Decides whether we should zap this page with the page pointer specified */
static inline bool should_zap_page(struct zap_details *details, struct page *page)
{
/* If we can make a decision without *page.. */
@@ -1338,7 +1335,8 @@ static inline bool should_zap_page(struct zap_details *details, struct page *pag
if (!page)
return true;
- return details->zap_mapping == page_rmapping(page);
+ /* Otherwise we should only zap non-anon pages */
+ return !PageAnon(page);
}
static unsigned long zap_pte_range(struct mmu_gather *tlb,
@@ -3398,7 +3396,7 @@ void unmap_mapping_folio(struct folio *folio)
first_index = folio->index;
last_index = folio->index + folio_nr_pages(folio) - 1;
- details.zap_mapping = mapping;
+ details.even_cows = false;
details.single_folio = folio;
i_mmap_lock_write(mapping);
@@ -3427,7 +3425,7 @@ void unmap_mapping_pages(struct address_space *mapping, pgoff_t start,
pgoff_t first_index = start;
pgoff_t last_index = start + nr - 1;
- details.zap_mapping = even_cows ? NULL : mapping;
+ details.even_cows = even_cows;
if (last_index < first_index)
last_index = ULONG_MAX;
--
2.32.0
next prev parent reply other threads:[~2022-02-17 6:08 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-17 6:07 [PATCH v5 0/4] mm: Rework zap ptes on swap entries Peter Xu
2022-02-17 6:07 ` [PATCH v5 1/4] mm: Don't skip swap entry even if zap_details specified Peter Xu
2022-02-17 6:07 ` [PATCH v5 2/4] mm: Rename zap_skip_check_mapping() to should_zap_page() Peter Xu
2022-02-17 6:07 ` Peter Xu [this message]
2022-02-17 6:07 ` [PATCH v5 4/4] mm: Rework swap handling of zap_pte_range Peter Xu
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=20220217060746.71256-4-peterx@redhat.com \
--to=peterx@redhat.com \
--cc=aarcange@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=apopple@nvidia.com \
--cc=david@redhat.com \
--cc=hughd@google.com \
--cc=jhubbard@nvidia.com \
--cc=kirill@shutemov.name \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=shy828301@gmail.com \
--cc=vbabka@suse.cz \
--cc=willy@infradead.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox