[PATCH v0 1/1] mkfs: set MAP_NORESERVE to force overcommit in exfat_map_blankmem()
David Timber <[email protected]>
| Newsgroups | dev.linux.lists.exfat |
|---|---|
| Message-ID | <[email protected]> |
Without the mmap() flag MAP_NORESERVE, the function still fails on
memory contraint systems because the kernel reserves VSZ including the
swap space even though the actual space required is only about 128
KB(0xFFFFFFF4 512-byte clusters divided by 8). Not using the flag
defeats the purpose of mapping /dev/zero.
Add MAP_NORESERVE to the flags when calling mmap() so that the kernel
disregards the VSZ available on the system when creating the mapping.
Also add comments on the reasoning behind the use of /dev/zero instead
of MAP_ANONYMOUS.
Fixes: dbffb9d29c86 ("mkfs: reduce RSS memory footprint for huge bitmap")
Signed-off-by: David Timber <[email protected]>
---
include/libexfat.h | 10 +++++++---
lib/libexfat.c | 4 ++--
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/include/libexfat.h b/include/libexfat.h
index 8dbb8ea..5126371 100644
--- a/include/libexfat.h
+++ b/include/libexfat.h
@@ -329,8 +329,11 @@ void exfat_close_fd_devzero(void);
* EBADFD if exfat_open_fd_devzero() has been called successfully, or any other
* errno set in mmap().
*
- * Note that /dev/zero mapping do not count towards committed memory. See
- * vm.overcommit for detail.
+ * Note that /dev/zero mappings do not count towards committed memory. See
+ * vm.overcommit for detail. /dev/zero is used instead of MAP_ANONYMOUS for
+ * portability reasons(the behaviour of shared read-only anonymous mapping is
+ * not well-defined). However, on Linux, it should be equivalent to allocating
+ * memory through MAP_ANONYMOUS.
*
* For rw version of this function, see exfat_map_blankmem().
*/
@@ -340,7 +343,8 @@ const void *exfat_map_zeromem(const size_t len, bool *mapped);
* zeros(e.g. allocation bitmap).
*
* The function has the exact same semantics as exfat_map_zeromem(), except that
- * it calls mmap() with PROT_READ|PROT_WRITE and MAP_PRIVATE.
+ * it calls mmap() with PROT_READ|PROT_WRITE and MAP_PRIVATE|MAP_NORESERVE if
+ * and only if supported by the platform.
*/
void *exfat_map_blankmem(const size_t len, bool *mapped);
/*
diff --git a/lib/libexfat.c b/lib/libexfat.c
index efd50ea..8212d76 100644
--- a/lib/libexfat.c
+++ b/lib/libexfat.c
@@ -1303,9 +1303,9 @@ void *exfat_map_blankmem(const size_t len, bool *mapped)
int prot = -1;
int flags = -1;
-#ifdef _POSIX_MAPPED_FILES
+#if defined(_POSIX_MAPPED_FILES) && defined(MAP_NORESERVE)
prot = PROT_READ|PROT_WRITE;
- flags = MAP_PRIVATE;
+ flags = MAP_PRIVATE|MAP_NORESERVE;
#endif
return exfat_do_map_zerodev(len, mapped, prot, flags);
}
--
2.55.0