vppinfra: detect memory attributes on clib_mem_init 90/28890/3
authorDamjan Marion <damarion@cisco.com>
Wed, 16 Sep 2020 19:36:00 +0000 (21:36 +0200)
committerAndrew Yourtchenko <ayourtch@gmail.com>
Thu, 17 Sep 2020 10:38:23 +0000 (10:38 +0000)
Type: improvement
Change-Id: I298aadfdf17d98dfb1ada1ec4f87e0821e6aeb7f
Signed-off-by: Damjan Marion <damarion@cisco.com>
src/vppinfra/linux/mem.c
src/vppinfra/mem.h
src/vppinfra/mem_dlmalloc.c

index c581181..42efc00 100644 (file)
@@ -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)
 {
index 9909726..f3484ce 100644 (file)
@@ -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,
index 2cd924a..0401df5 100644 (file)
@@ -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 */ );