aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDamjan Marion <damarion@cisco.com>2020-09-16 21:36:00 +0200
committerAndrew Yourtchenko <ayourtch@gmail.com>2020-09-17 10:38:23 +0000
commitc63e2a4f980e09b4274558f0562cee285f9741b5 (patch)
treeaff372a95841fcb4d00e9f67298497fe858f6224
parentf6e6c788070e1421bbe7b10d449d9b65918ba561 (diff)
vppinfra: detect memory attributes on clib_mem_init
Type: improvement Change-Id: I298aadfdf17d98dfb1ada1ec4f87e0821e6aeb7f Signed-off-by: Damjan Marion <damarion@cisco.com>
-rw-r--r--src/vppinfra/linux/mem.c74
-rw-r--r--src/vppinfra/mem.h10
-rw-r--r--src/vppinfra/mem_dlmalloc.c2
3 files changed, 82 insertions, 4 deletions
diff --git a/src/vppinfra/linux/mem.c b/src/vppinfra/linux/mem.c
index c5811816c1f..42efc007ceb 100644
--- a/src/vppinfra/linux/mem.c
+++ b/src/vppinfra/linux/mem.c
@@ -46,6 +46,9 @@
#define F_SEAL_WRITE 0x0008 /* prevent writes */
#endif
+#ifndef MFD_HUGETLB
+#define MFD_HUGETLB 0x0004U
+#endif
uword
clib_mem_get_page_size (void)
@@ -87,6 +90,73 @@ done:
return 1024ULL * size;
}
+static clib_mem_page_sz_t
+legacy_get_log2_default_hugepage_size (void)
+{
+ clib_mem_page_sz_t log2_page_size = CLIB_MEM_PAGE_SZ_UNKNOWN;
+ FILE *fp;
+ char tmp[33] = { };
+
+ if ((fp = fopen ("/proc/meminfo", "r")) == NULL)
+ return CLIB_MEM_PAGE_SZ_UNKNOWN;
+
+ while (fscanf (fp, "%32s", tmp) > 0)
+ if (strncmp ("Hugepagesize:", tmp, 13) == 0)
+ {
+ u32 size;
+ if (fscanf (fp, "%u", &size) > 0)
+ log2_page_size = 10 + min_log2 (size);
+ break;
+ }
+
+ fclose (fp);
+ return log2_page_size;
+}
+
+void
+clib_mem_main_init ()
+{
+ clib_mem_main_t *mm = &clib_mem_main;
+ uword page_size;
+ void *va;
+ int fd;
+
+ if (mm->log2_page_sz != CLIB_MEM_PAGE_SZ_UNKNOWN)
+ return;
+
+ /* system page size */
+ page_size = sysconf (_SC_PAGESIZE);
+ mm->log2_page_sz = min_log2 (page_size);
+
+ /* default system hugeppage size */
+ if ((fd = memfd_create ("test", MFD_HUGETLB)) != -1)
+ {
+ mm->log2_default_hugepage_sz = clib_mem_get_fd_log2_page_size (fd);
+ close (fd);
+ }
+ else /* likely kernel older than 4.14 */
+ mm->log2_default_hugepage_sz = legacy_get_log2_default_hugepage_size ();
+
+ /* numa nodes */
+ va = mmap (0, page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE |
+ MAP_ANONYMOUS, -1, 0);
+ if (va == MAP_FAILED)
+ return;
+
+ if (mlock (va, page_size))
+ goto done;
+
+ for (int i = 0; i < CLIB_MAX_NUMAS; i++)
+ {
+ int status;
+ if (move_pages (0, 1, &va, &i, &status, 0) == 0)
+ mm->numa_node_bitmap |= 1ULL << i;
+ }
+
+done:
+ munmap (va, page_size);
+}
+
u64
clib_mem_get_fd_page_size (int fd)
{
@@ -119,10 +189,6 @@ clib_mem_vm_randomize_va (uword * requested_va,
(clib_cpu_time_now () & bit_mask) * (1ull << log2_page_size);
}
-#ifndef MFD_HUGETLB
-#define MFD_HUGETLB 0x0004U
-#endif
-
clib_error_t *
clib_mem_create_fd (char *name, int *fdp)
{
diff --git a/src/vppinfra/mem.h b/src/vppinfra/mem.h
index 99097263dfa..f3484cea09d 100644
--- a/src/vppinfra/mem.h
+++ b/src/vppinfra/mem.h
@@ -73,6 +73,15 @@ typedef enum
typedef struct
{
+ /* log2 system page size */
+ clib_mem_page_sz_t log2_page_sz;
+
+ /* log2 system default hugepage size */
+ clib_mem_page_sz_t log2_default_hugepage_sz;
+
+ /* bitmap of available numa nodes */
+ u32 numa_node_bitmap;
+
/* per CPU heaps */
void *per_cpu_mheaps[CLIB_MAX_MHEAPS];
@@ -294,6 +303,7 @@ clib_mem_set_heap (void *heap)
return clib_mem_set_per_cpu_heap (heap);
}
+void clib_mem_main_init ();
void *clib_mem_init (void *heap, uword size);
void *clib_mem_init_thread_safe (void *memory, uword memory_size);
void *clib_mem_init_thread_safe_numa (void *memory, uword memory_size,
diff --git a/src/vppinfra/mem_dlmalloc.c b/src/vppinfra/mem_dlmalloc.c
index 2cd924a605d..0401df5993e 100644
--- a/src/vppinfra/mem_dlmalloc.c
+++ b/src/vppinfra/mem_dlmalloc.c
@@ -201,6 +201,8 @@ clib_mem_init_internal (void *memory, uword memory_size, int set_heap)
{
u8 *heap;
+ clib_mem_main_init ();
+
if (memory)
{
heap = create_mspace_with_base (memory, memory_size, 1 /* locked */ );