File 2613-erts-Add-Mumadtn-true-for-MADV_DONTNEED-instead-of-M.patch of Package erlang
From 81754b0ef920bfe43f4bedd0ff34c03818942de0 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Mon, 18 Aug 2025 16:50:04 +0200
Subject: [PATCH 3/3] erts: Add +Mumadtn true for MADV_DONTNEED instead of
MADV_FREE
---
erts/doc/references/erts_alloc.md | 8 ++++++++
erts/emulator/beam/erl_alloc.c | 4 ++++
erts/emulator/beam/erl_alloc_util.c | 4 ++++
erts/emulator/beam/erl_alloc_util.h | 7 +++++--
erts/emulator/sys/common/erl_mmap.c | 7 +++++++
erts/emulator/sys/common/erl_mmap.h | 10 +++++-----
erts/etc/common/erlexec.c | 1 +
7 files changed, 34 insertions(+), 7 deletions(-)
diff --git a/erts/doc/references/erts_alloc.md b/erts/doc/references/erts_alloc.md
index c4d95b244b..57c5e2a711 100644
--- a/erts/doc/references/erts_alloc.md
+++ b/erts/doc/references/erts_alloc.md
@@ -413,6 +413,9 @@ identifier is effected.
used. The value chosen depends on the allocator type and can be changed
between ERTS versions.
+ On Unix flag [`+Mumadtn`](erts_alloc.md#Mumadtn) may also be set to pass
+ `MADV_DONTNEED` instead of `MADV_FREE` as argument to `madvise()`.
+
See also [`acul`](erts_alloc.md#M_acul).
- **`+M<S>as bf|aobf|aoff|aoffcbf|aoffcaobf|ageffcaoff|ageffcbf|ageffcaobf|gf|af`{:
@@ -581,6 +584,11 @@ All allocators based on `alloc_util` are effected.
`true`. If set to `false`, `sys_alloc` carriers are never created by
allocators using the `alloc_util` framework.
+- **`+Mumadtn <bool>`{: #Mumadtn }** - Control how to mark memory as re-usable
+ on Unix when [`+M<S>acful`](erts_alloc.md#M_acful) is set. Default is `false`
+ which means `MADV_FREE` is passed to `madvise()`. If set to `true`,
+ `MADV_DONTNEED` is passed instead.
+
### Special Flag for literal_alloc
- **`+MIscs <size in MB>`{: #MIscs }** - `literal_alloc` super carrier size (in
diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c
index f173a9223c..f5bc19fdbb 100644
--- a/erts/emulator/beam/erl_alloc.c
+++ b/erts/emulator/beam/erl_alloc.c
@@ -1825,6 +1825,10 @@ handle_args(int *argc, char **argv, erts_alc_hndl_args_init_t *init)
init->alloc_util.sac
= get_bool_value(argv[i]+6, argv, &i);
}
+ else if (has_prefix("madtn", argv[i]+3)) {
+ init->alloc_util.madtn
+ = get_bool_value(argv[i]+8, argv, &i);
+ }
else {
int a;
int start = i;
diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c
index 9a15b68e21..8c3dd7b460 100644
--- a/erts/emulator/beam/erl_alloc_util.c
+++ b/erts/emulator/beam/erl_alloc_util.c
@@ -7028,6 +7028,10 @@ erts_alcu_init(AlcUInit_t *init)
#endif
allow_sys_alloc_carriers = init->sac;
+#if defined(HAVE_MADVISE) && defined(MADV_FREE)
+ erts_madvise_discard_advice = (init->madtn ? MADV_DONTNEED : MADV_FREE);
+#endif
+
#ifdef DEBUG
carrier_alignment = sizeof(Unit_t);
#endif
diff --git a/erts/emulator/beam/erl_alloc_util.h b/erts/emulator/beam/erl_alloc_util.h
index 6c017b815a..ecff02dd91 100644
--- a/erts/emulator/beam/erl_alloc_util.h
+++ b/erts/emulator/beam/erl_alloc_util.h
@@ -42,6 +42,7 @@ typedef struct {
UWord ycs;
UWord mmc;
int sac;
+ int madtn;
} AlcUInit_t;
typedef struct {
@@ -102,7 +103,8 @@ typedef struct {
#define ERTS_DEFAULT_ALCU_INIT { \
.ycs = 1024*1024, /* (bytes): sys_alloc carrier size */\
.mmc = ~((UWord) 0), /* (amount): max mseg carriers */\
- .sac = 1 /* (bool): sys_alloc carriers */\
+ .sac = 1, /* (bool): sys_alloc carriers */\
+ .madtn = 0 /* (bool) => erts_madvise_discard_advice */\
}
#define ERTS_DEFAULT_ALLCTR_INIT { \
@@ -143,7 +145,8 @@ typedef struct {
#define ERTS_DEFAULT_ALCU_INIT { \
.ycs = 128*1024, /* (bytes): sys_alloc carrier size */\
.mmc = 1024, /* (amount): max mseg carriers */\
- .sac = 1 /* (bool): sys_alloc carriers */\
+ .sac = 1, /* (bool): sys_alloc carriers */\
+ .madtn = 0 /* (bool) => erts_madvise_discard_advice */\
}
#define ERTS_DEFAULT_ALLCTR_INIT { \
diff --git a/erts/emulator/sys/common/erl_mmap.c b/erts/emulator/sys/common/erl_mmap.c
index 03cf6f7e9d..e07a1622b3 100644
--- a/erts/emulator/sys/common/erl_mmap.c
+++ b/erts/emulator/sys/common/erl_mmap.c
@@ -34,6 +34,13 @@
#include <sys/mman.h>
#endif
+#if defined(HAVE_MADVISE) && defined(MADV_FREE)
+/* Note that we don't default to MADV_DONTNEED since it promises that
+ * the given region will be zeroed on access, which turned out to be
+ * too much of a performance hit. */
+int erts_madvise_discard_advice = MADV_FREE;
+#endif
+
int erts_mem_guard(void *p, UWord size, int readable, int writable) {
#if defined(WIN32)
diff --git a/erts/emulator/sys/common/erl_mmap.h b/erts/emulator/sys/common/erl_mmap.h
index 20acd528e3..3218f67974 100644
--- a/erts/emulator/sys/common/erl_mmap.h
+++ b/erts/emulator/sys/common/erl_mmap.h
@@ -156,7 +156,6 @@ Eterm erts_mmap_info_options(ErtsMemMapper*,
char *prefix, fmtfn_t *print_to_p, void *print_to_arg,
Uint **hpp, Uint *szp);
-
#ifdef ERTS_WANT_MEM_MAPPERS
# include "erl_alloc_types.h"
@@ -194,6 +193,10 @@ int erts_mem_guard(void *p, UWord size, int readable, int writable);
* its contents) the next time it's accessed. */
ERTS_GLB_INLINE void erts_mem_discard(void *p, UWord size);
+#if defined(HAVE_MADVISE) && defined(MADV_FREE)
+extern int erts_madvise_discard_advice; // MADV_FREE or MADV_DONTNEED
+#endif
+
#if ERTS_GLB_INLINE_INCL_FUNC_DEF
#ifdef VALGRIND
@@ -220,11 +223,8 @@ ERTS_GLB_INLINE void erts_mem_discard(void *p, UWord size);
#include <sys/mman.h>
ERTS_GLB_INLINE void erts_mem_discard(void *ptr, UWord size) {
- /* Note that we don't fall back to MADV_DONTNEED since it promises that
- * the given region will be zeroed on access, which turned out to be
- * too much of a performance hit. */
#ifdef MADV_FREE
- madvise(ptr, size, MADV_FREE);
+ madvise(ptr, size, erts_madvise_discard_advice);
#else
(void)ptr;
(void)size;
diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c
index 6da1971cad..fdad5b0d5e 100644
--- a/erts/etc/common/erlexec.c
+++ b/erts/etc/common/erlexec.c
@@ -100,6 +100,7 @@ static char *plusM_au_alloc_switches[] = {
/* +M other arguments */
static char *plusM_other_switches[] = {
"ea",
+ "umadtn",
"ummc",
"uycs",
"usac",
--
2.51.0