From: Rik van Riel <riel@surriel.com>
To: linux-kernel@vger.kernel.org
Cc: linux-mm@kvack.org, kernel-team@meta.com,
Mike Kravetz <mike.kravetz@oracle.com>,
Andrew Morton <akpm@linux-foundation.org>,
David Hildenbrand <david@redhat.com>
Subject: [PATCH] mm,madvise,hugetlb: fix unexpected data loss with MADV_DONTNEED on hugetlbfs
Date: Fri, 21 Oct 2022 15:45:46 -0400 [thread overview]
Message-ID: <20221021154546.57df96db@imladris.surriel.com> (raw)
A common use case for hugetlbfs is for the application to create
memory pools backed by huge pages, which then get handed over to
some malloc library (eg. jemalloc) for further management.
That malloc library may be doing MADV_DONTNEED calls on memory
that is no longer needed, expecting those calls to happen on
PAGE_SIZE boundaries.
However, currently the MADV_DONTNEED code rounds up any such
requests to HPAGE_PMD_SIZE boundaries. This leads to undesired
outcomes when jemalloc expects a 4kB MADV_DONTNEED, but 2MB of
memory get zeroed out, instead.
Use of pre-built shared libraries means that user code does not
always know the page size of every memory arena in use.
Avoid unexpected data loss with MADV_DONTNEED by rounding up
only to PAGE_SIZE (in do_madvise), and rounding down to huge
page granularity.
That way programs will only get as much memory zeroed out as
they requested.
While we're here, refactor madvise_dontneed_free_valid_vma
a little so mlocked hugetlb VMAs need MADV_DONTNEED_LOCKED.
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: David Hildenbrand <david@redhat.com>
Fixes: 90e7e7f5ef3f ("mm: enable MADV_DONTNEED for hugetlb mappings")
---
mm/madvise.c | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/mm/madvise.c b/mm/madvise.c
index 2baa93ca2310..a60e8e23c323 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -799,21 +799,29 @@ static bool madvise_dontneed_free_valid_vma(struct vm_area_struct *vma,
unsigned long *end,
int behavior)
{
- if (!is_vm_hugetlb_page(vma)) {
- unsigned int forbidden = VM_PFNMAP;
+ unsigned int forbidden = VM_PFNMAP;
- if (behavior != MADV_DONTNEED_LOCKED)
- forbidden |= VM_LOCKED;
+ if (behavior != MADV_DONTNEED_LOCKED)
+ forbidden |= VM_LOCKED;
- return !(vma->vm_flags & forbidden);
- }
+ if (vma->vm_flags & forbidden)
+ return false;
+
+ if (!is_vm_hugetlb_page(vma))
+ return true;
if (behavior != MADV_DONTNEED && behavior != MADV_DONTNEED_LOCKED)
return false;
if (start & ~huge_page_mask(hstate_vma(vma)))
return false;
- *end = ALIGN(*end, huge_page_size(hstate_vma(vma)));
+ /*
+ * Madvise callers expect the length to be rounded up to the page
+ * size, but they may not know the page size for this VMA is larger
+ * than PAGE_SIZE! Round down huge pages to avoid unexpected data loss.
+ */
+ *end = ALIGN_DOWN(*end, huge_page_size(hstate_vma(vma)));
+
return true;
}
@@ -828,6 +836,10 @@ static long madvise_dontneed_free(struct vm_area_struct *vma,
if (!madvise_dontneed_free_valid_vma(vma, start, &end, behavior))
return -EINVAL;
+ /* A small MADV_DONTNEED on a huge page gets rounded down to zero. */
+ if (start == end)
+ return 0;
+
if (!userfaultfd_remove(vma, start, end)) {
*prev = NULL; /* mmap_lock has been dropped, prev is stale */
--
2.37.2
next reply other threads:[~2022-10-21 19:45 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-21 19:45 Rik van Riel [this message]
2022-10-21 20:48 ` Mike Kravetz
2022-10-21 23:29 ` Rik van Riel
2022-10-21 23:42 ` Mike Kravetz
2022-10-21 20:48 ` Andrew Morton
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=20221021154546.57df96db@imladris.surriel.com \
--to=riel@surriel.com \
--cc=akpm@linux-foundation.org \
--cc=david@redhat.com \
--cc=kernel-team@meta.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mike.kravetz@oracle.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox