VPP-236 Support 64-bit vector lengths, shared memory segments >4 GB

Change-Id: I02aee33e96e7ae32094b9f82f6a667d30bb52f59
Signed-off-by: Dave Barach <dave@barachs.net>
diff --git a/svm/svm.c b/svm/svm.c
index 1ee5e95..851baea 100644
--- a/svm/svm.c
+++ b/svm/svm.c
@@ -216,10 +216,10 @@
  * 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 @@
   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 @@
   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 @@
 	}
 
       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 @@
 
       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 @@
       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 @@
 }
 
 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 @@
   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 @@
       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 @@
 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 @@
 
   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 @@
   /* 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;
@@ -892,7 +932,7 @@
   a->baseva = root_rp->virtual_base + index * MMAP_PAGESIZE;
 
   rp = svm_map_region (a);
-
+  
   pool_get (mp->subregions, subp);
   name = format (0, "%s%c", a->name, 0);
   subp->subregion_name = name;