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;