vlib: add max-size configuration parameter for pmalloc
[vpp.git] / src / vlib / physmem.c
index 2599bce..846f9a0 100755 (executable)
 #include <vlib/pci/pci.h>
 #include <vlib/linux/vfio.h>
 
+#if defined(__x86_64__) && !defined(CLIB_SANITIZE_ADDR)
+/* we keep physmem in low 38 bits of VA address space as some
+   IOMMU implamentation cannot map above that range */
+#define VLIB_PHYSMEM_DEFAULT_BASE_ADDDR                (1ULL << 36)
+#else
+/* let kernel decide */
+#define VLIB_PHYSMEM_DEFAULT_BASE_ADDDR                0
+#endif
+
 clib_error_t *
 vlib_physmem_shared_map_create (vlib_main_t * vm, char *name, uword size,
-                               u32 numa_node, u32 * map_index)
+                               u32 log2_page_sz, u32 numa_node,
+                               u32 * map_index)
 {
   clib_pmalloc_main_t *pm = vm->physmem_main.pmalloc_main;
   vlib_physmem_main_t *vpm = &vm->physmem_main;
@@ -41,7 +51,8 @@ vlib_physmem_shared_map_create (vlib_main_t * vm, char *name, uword size,
   void *va;
   uword i;
 
-  va = clib_pmalloc_create_shared_arena (pm, name, size, numa_node);
+  va = clib_pmalloc_create_shared_arena (pm, name, size, log2_page_sz,
+                                        numa_node);
 
   if (va == 0)
     return clib_error_return (0, "%U", format_clib_error,
@@ -53,12 +64,14 @@ vlib_physmem_shared_map_create (vlib_main_t * vm, char *name, uword size,
   *map_index = map->index = map - vpm->maps;
   map->base = va;
   map->fd = a->fd;
-  map->n_pages = a->n_pages;
-  map->log2_page_size = a->log2_page_sz;
+  map->n_pages = a->n_pages * a->subpages_per_page;
+  map->log2_page_size = a->log2_subpage_sz;
+  map->numa_node = a->numa_node;
 
   for (i = 0; i < a->n_pages; i++)
     {
-      uword pa = clib_pmalloc_get_pa (pm, (u8 *) va + (i << a->log2_page_sz));
+      uword pa =
+       clib_pmalloc_get_pa (pm, (u8 *) va + (i << a->log2_subpage_sz));
 
       /* maybe iova */
       if (pa == 0)
@@ -98,7 +111,16 @@ vlib_physmem_init (vlib_main_t * vm)
                              CLIB_CACHE_LINE_BYTES);
   memset (p, 0, sizeof (clib_pmalloc_main_t));
   vpm->pmalloc_main = (clib_pmalloc_main_t *) p;
-  clib_pmalloc_init (vpm->pmalloc_main, 0);
+
+  if (vpm->base_addr == 0)
+    vpm->base_addr = VLIB_PHYSMEM_DEFAULT_BASE_ADDDR;
+
+  clib_pmalloc_init (vpm->pmalloc_main, vpm->base_addr, vpm->max_size);
+
+  /* update base_addr and max_size per actual allocation */
+  vpm->base_addr = (uword) vpm->pmalloc_main->base;
+  vpm->max_size = (uword) vpm->pmalloc_main->max_pages <<
+    vpm->pmalloc_main->def_log2_page_sz;
 
   return error;
 }
@@ -109,7 +131,7 @@ show_physmem (vlib_main_t * vm,
 {
   vlib_physmem_main_t *vpm = &vm->physmem_main;
   unformat_input_t _line_input, *line_input = &_line_input;
-  u32 verbose = 0;
+  u32 verbose = 0, map = 0;
 
   if (unformat_user (input, unformat_line_input, line_input))
     {
@@ -123,24 +145,52 @@ show_physmem (vlib_main_t * vm,
            verbose = 2;
          else if (unformat (line_input, "d"))
            verbose = 2;
+         else if (unformat (line_input, "map"))
+           map = 1;
          else
            break;
        }
       unformat_free (line_input);
     }
 
-  vlib_cli_output (vm, "  %U", format_pmalloc, vpm->pmalloc_main, verbose);
+  if (map)
+    vlib_cli_output (vm, " %U", format_pmalloc_map, vpm->pmalloc_main);
+  else
+    vlib_cli_output (vm, " %U", format_pmalloc, vpm->pmalloc_main, verbose);
+
   return 0;
 }
 
 /* *INDENT-OFF* */
 VLIB_CLI_COMMAND (show_physmem_command, static) = {
   .path = "show physmem",
-  .short_help = "Show physical memory allocation",
+  .short_help = "show physmem [verbose | detail | map]",
   .function = show_physmem,
 };
 /* *INDENT-ON* */
 
+static clib_error_t *
+vlib_physmem_config (vlib_main_t * vm, unformat_input_t * input)
+{
+  vlib_physmem_main_t *vpm = &vm->physmem_main;
+
+  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (input, "base-addr 0x%lx", &vpm->base_addr))
+       ;
+      else if (unformat (input, "max-size %U",
+                        unformat_memory_size, &vpm->max_size))
+       ;
+      else
+       return unformat_parse_error (input);
+    }
+
+  unformat_free (input);
+  return 0;
+}
+
+VLIB_EARLY_CONFIG_FUNCTION (vlib_physmem_config, "physmem");
+
 /*
  * fd.io coding-style-patch-verification: ON
  *