do not use mmap when the mmap limit is too low (#19714)
Costa Tsaousis committed
Feb 26, 2025 at 11:32 UTC
b71bc97008bfb55742503e67a67899fe2d71147c
5 files changed
+45
-2
CMakeLists.txt
+2
@@ -1056,6 +1056,8 @@ set(LIBNETDATA_FILES
1056
src/libnetdata/os/run_dir.h
1057
src/libnetdata/os/file_lock.c
1058
src/libnetdata/os/file_lock.h
1059
+ src/libnetdata/os/mmap_limit.c
1060
+ src/libnetdata/os/mmap_limit.h
1061
)
1062
1063
list(APPEND LIBNETDATA_FILES ${INICFG_FILES})
src/libnetdata/aral/aral.c
+11
-2
@@ -143,6 +143,15 @@ struct aral {
143
#define aral_pages_head_free(ar, marked) (marked ? &ar->aral_lock.pages_marked_free : &ar->aral_lock.pages_free)
144
#define aral_pages_head_full(ar, marked) (marked ? &ar->aral_lock.pages_marked_full : &ar->aral_lock.pages_full)
145
146
+static inline bool aral_malloc_use_mmap(ARAL *ar __maybe_unused, size_t size) {
147
+ unsigned long long mmap_limit = os_mmap_limit();
148
+
149
+ if(mmap_limit > 256 * 1000 && size >= ARAL_MALLOC_USE_MMAP_ABOVE)
150
+ return true;
151
+
152
+ return false;
153
+}
154
+
155
const char *aral_name(ARAL *ar) {
156
return ar->config.name;
157
}
@@ -503,7 +512,7 @@ static ALWAYS_INLINE size_t aral_next_allocation_size___adders_lock_needed(ARAL
512
ar->ops[idx].adders.allocation_size = size;
513
}
514
506
- if(!ar->config.mmap.enabled && size < ARAL_MALLOC_USE_MMAP_ABOVE) {
515
+ if(!ar->config.mmap.enabled && aral_malloc_use_mmap(ar, size)) {
516
// when doing malloc, don't allocate entire pages, but only what needed
517
size =
518
aral_elements_in_page_size(ar, size) * ar->config.element_size +
@@ -553,7 +562,7 @@ static ARAL_PAGE *aral_create_page___no_lock_needed(ARAL *ar, size_t size TRACE_
562
else {
563
size_t ARAL_PAGE_size = memory_alignment(sizeof(ARAL_PAGE), SYSTEM_REQUIRED_ALIGNMENT);
564
556
- if (size >= ARAL_MALLOC_USE_MMAP_ABOVE) {
565
+ if (aral_malloc_use_mmap(ar, size)) {
566
bool mapped;
567
uint8_t *ptr =
568
nd_mmap_advanced(NULL, size, MAP_ANONYMOUS | MAP_PRIVATE, 1, false, ar->config.options & ARAL_DONT_DUMP, NULL);
src/libnetdata/os/mmap_limit.c
new
+21
@@ -0,0 +1,21 @@
1
+// SPDX-License-Identifier: GPL-3.0-or-later
2
+
3
+#include "mmap_limit.h"
4
+#include "libnetdata/libnetdata.h"
5
+
6
+unsigned long long os_mmap_limit(void) {
7
+ static unsigned long long cached_limit = 0;
8
+
9
+ if (cached_limit)
10
+ return cached_limit;
11
+
12
+#if defined(OS_LINUX)
13
+ if(read_single_number_file("/proc/sys/vm/max_map_count", &cached_limit) != 0)
14
+ cached_limit = 65536;
15
+#else
16
+ // For other operating systems, assume no limit.
17
+ cached_limit = UINT32_MAX;
18
+#endif
19
+
20
+ return cached_limit;
21
+}
src/libnetdata/os/mmap_limit.h
new
+10
@@ -0,0 +1,10 @@
1
+// SPDX-License-Identifier: GPL-3.0-or-later
2
+
3
+#ifndef NETDATA_MMAP_LIMIT_H
4
+#define NETDATA_MMAP_LIMIT_H
5
+
6
+#include "libnetdata/common.h"
7
+
8
+unsigned long long os_mmap_limit(void);
9
+
10
+#endif //NETDATA_MMAP_LIMIT_H
src/libnetdata/os/os.h
+1
@@ -39,6 +39,7 @@
39
#include "boot_id.h"
40
#include "run_dir.h"
41
#include "file_lock.h"
42
+#include "mmap_limit.h"
43
44
// this includes windows.h to the whole of netdata
45
// so various conflicts arise