VPP-355: add PBB (802.1ah) tag rewrite
[vpp.git] / svm / svm.c
index 1ee5e95..e4ca98e 100644 (file)
--- a/svm/svm.c
+++ b/svm/svm.c
@@ -216,10 +216,10 @@ format_svm_region (u8 * s, va_list * args)
  * rnd_pagesize
  * Round to a pagesize multiple, presumably 4k works
  */
-static unsigned int
-rnd_pagesize (unsigned int size)
+static u64
+rnd_pagesize (u64 size)
 {
-  unsigned int rv;
+  u64 rv;
 
   rv = (size + (MMAP_PAGESIZE - 1)) & ~(MMAP_PAGESIZE - 1);
   return (rv);
@@ -235,7 +235,9 @@ svm_data_region_create (svm_map_region_args_t * a, svm_region_t * rp)
   u8 junk = 0;
   uword map_size;
 
-  map_size = rp->virtual_size - (MMAP_PAGESIZE + SVM_PVT_MHEAP_SIZE);
+  map_size = rp->virtual_size - (MMAP_PAGESIZE +
+                                (a->pvt_heap_size ? a->pvt_heap_size :
+                                 SVM_PVT_MHEAP_SIZE));
 
   if (a->flags & SVM_FLAGS_FILE)
     {
@@ -316,7 +318,9 @@ svm_data_region_map (svm_map_region_args_t * a, svm_region_t * rp)
   uword map_size;
   struct stat statb;
 
-  map_size = rp->virtual_size - (MMAP_PAGESIZE + SVM_PVT_MHEAP_SIZE);
+  map_size = rp->virtual_size -
+    (MMAP_PAGESIZE
+     + (a->pvt_heap_size ? a->pvt_heap_size : SVM_PVT_MHEAP_SIZE));
 
   if (a->flags & SVM_FLAGS_FILE)
     {
@@ -364,7 +368,9 @@ svm_data_region_map (svm_map_region_args_t * a, svm_region_t * rp)
        }
 
       ASSERT (map_size <= rp->virtual_size
-             - (MMAP_PAGESIZE + SVM_PVT_MHEAP_SIZE));
+             - (MMAP_PAGESIZE
+                +
+                (a->pvt_heap_size ? a->pvt_heap_size : SVM_PVT_MHEAP_SIZE)));
 
       if (mmap (rp->data_base, map_size, PROT_READ | PROT_WRITE,
                MAP_SHARED | MAP_FIXED, fd, 0) == MAP_FAILED)
@@ -528,7 +534,9 @@ svm_map_region (svm_map_region_args_t * a)
 
       rp->region_heap =
        mheap_alloc_with_flags ((void *) (a->baseva + MMAP_PAGESIZE),
-                               SVM_PVT_MHEAP_SIZE, MHEAP_FLAG_DISABLE_VM);
+                               (a->pvt_heap_size != 0) ?
+                               a->pvt_heap_size : SVM_PVT_MHEAP_SIZE,
+                               MHEAP_FLAG_DISABLE_VM);
       oldheap = svm_push_pvt_heap (rp);
 
       rp->region_name = (char *) format (0, "%s%c", a->name, 0);
@@ -542,7 +550,7 @@ svm_map_region (svm_map_region_args_t * a)
       vec_validate (rp->bitmap, words - 1);
 
       overhead_space = MMAP_PAGESIZE /* header */  +
-       SVM_PVT_MHEAP_SIZE;
+       ((a->pvt_heap_size != 0) ? a->pvt_heap_size : SVM_PVT_MHEAP_SIZE);
 
       bit = 0;
       data_base = (uword) rp->virtual_base;
@@ -724,10 +732,9 @@ svm_mutex_cleanup (void)
 }
 
 static void
-svm_region_init_internal (char *root_path, int uid, int gid)
+svm_region_init_internal (svm_map_region_args_t * a)
 {
   svm_region_t *rp;
-  svm_map_region_args_t _a, *a = &_a;
   u64 ticks = clib_cpu_time_now ();
   uword randomize_baseva;
 
@@ -745,14 +752,7 @@ svm_region_init_internal (char *root_path, int uid, int gid)
   else
     randomize_baseva = (ticks & 3) * MMAP_PAGESIZE;
 
-  memset (a, 0, sizeof (*a));
-  a->root_path = root_path;
-  a->name = SVM_GLOBAL_REGION_NAME;
-  a->baseva = SVM_GLOBAL_REGION_BASEVA + randomize_baseva;
-  a->size = SVM_GLOBAL_REGION_SIZE;
-  a->flags = SVM_FLAGS_NODATA;
-  a->uid = uid;
-  a->gid = gid;
+  a->baseva += randomize_baseva;
 
   rp = svm_map_region (a);
   ASSERT (rp);
@@ -770,7 +770,7 @@ svm_region_init_internal (char *root_path, int uid, int gid)
       oldheap = svm_push_pvt_heap (rp);
       vec_validate (mp, 0);
       mp->name_hash = hash_create_string (0, sizeof (uword));
-      mp->root_path = root_path ? format (0, "%s%c", root_path, 0) : 0;
+      mp->root_path = a->root_path ? format (0, "%s%c", a->root_path, 0) : 0;
       rp->data_base = mp;
       svm_pop_heap (oldheap);
     }
@@ -781,19 +781,58 @@ svm_region_init_internal (char *root_path, int uid, int gid)
 void
 svm_region_init (void)
 {
-  svm_region_init_internal (0, 0 /* uid */ , 0 /* gid */ );
+  svm_map_region_args_t _a, *a = &_a;
+
+  memset (a, 0, sizeof (*a));
+  a->root_path = 0;
+  a->name = SVM_GLOBAL_REGION_NAME;
+  a->baseva = SVM_GLOBAL_REGION_BASEVA;
+  a->size = SVM_GLOBAL_REGION_SIZE;
+  a->flags = SVM_FLAGS_NODATA;
+  a->uid = 0;
+  a->gid = 0;
+
+  svm_region_init_internal (a);
 }
 
 void
 svm_region_init_chroot (char *root_path)
 {
-  svm_region_init_internal (root_path, 0 /* uid */ , 0 /* gid */ );
+  svm_map_region_args_t _a, *a = &_a;
+
+  memset (a, 0, sizeof (*a));
+  a->root_path = root_path;
+  a->name = SVM_GLOBAL_REGION_NAME;
+  a->baseva = SVM_GLOBAL_REGION_BASEVA;
+  a->size = SVM_GLOBAL_REGION_SIZE;
+  a->flags = SVM_FLAGS_NODATA;
+  a->uid = 0;
+  a->gid = 0;
+
+  svm_region_init_internal (a);
 }
 
 void
 svm_region_init_chroot_uid_gid (char *root_path, int uid, int gid)
 {
-  svm_region_init_internal (root_path, uid, gid);
+  svm_map_region_args_t _a, *a = &_a;
+
+  memset (a, 0, sizeof (*a));
+  a->root_path = root_path;
+  a->name = SVM_GLOBAL_REGION_NAME;
+  a->baseva = SVM_GLOBAL_REGION_BASEVA;
+  a->size = SVM_GLOBAL_REGION_SIZE;
+  a->flags = SVM_FLAGS_NODATA;
+  a->uid = uid;
+  a->gid = gid;
+
+  svm_region_init_internal (a);
+}
+
+void
+svm_region_init_args (svm_map_region_args_t * a)
+{
+  svm_region_init_internal (a);
 }
 
 void *
@@ -810,7 +849,8 @@ svm_region_find_or_create (svm_map_region_args_t * a)
 
   ASSERT (root_rp);
 
-  a->size += MMAP_PAGESIZE + SVM_PVT_MHEAP_SIZE;
+  a->size += MMAP_PAGESIZE +
+    ((a->pvt_heap_size != 0) ? a->pvt_heap_size : SVM_PVT_MHEAP_SIZE);
   a->size = rnd_pagesize (a->size);
 
   region_lock (root_rp, 4);
@@ -869,8 +909,8 @@ svm_region_find_or_create (svm_map_region_args_t * a)
   /* Completely out of VM? */
   if (index >= root_rp->bitmap_size)
     {
-      clib_warning ("region %s: not enough VM to allocate 0x%x",
-                   root_rp->region_name, a->size);
+      clib_warning ("region %s: not enough VM to allocate 0x%llx (%lld)",
+                   root_rp->region_name, a->size, a->size);
       svm_pop_heap (oldheap);
       region_unlock (root_rp);
       return 0;