summaryrefslogtreecommitdiffstats
path: root/svm
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2016-08-03 14:34:38 -0400
committerKeith Burns <alagalah@gmail.com>2016-08-15 13:57:25 +0000
commitb3d93dacfde8ab21bbce171fff2971b2ed7bce6a (patch)
tree8d3b44e8a8fcbf155979114a929590fc9473b914 /svm
parentc53191deb39231cf8408cf9eb0adf5c878ddda68 (diff)
VPP-236 Support 64-bit vector lengths, shared memory segments >4 GB
Change-Id: I02aee33e96e7ae32094b9f82f6a667d30bb52f59 Signed-off-by: Dave Barach <dave@barachs.net>
Diffstat (limited to 'svm')
-rw-r--r--svm/svm.c92
-rw-r--r--svm/svm.h6
-rw-r--r--svm/svmtool.c9
3 files changed, 75 insertions, 32 deletions
diff --git a/svm/svm.c b/svm/svm.c
index 1ee5e95df29..851baea55ed 100644
--- 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;
@@ -892,7 +932,7 @@ svm_region_find_or_create (svm_map_region_args_t * a)
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;
diff --git a/svm/svm.h b/svm/svm.h
index 1682b7ad2fa..c42d2b578df 100644
--- a/svm/svm.h
+++ b/svm/svm.h
@@ -71,8 +71,9 @@ typedef struct svm_map_region_args_
{
char *root_path; /* NULL means use the truly global arena */
char *name;
- uword baseva;
- uword size;
+ u64 baseva;
+ u64 size;
+ u64 pvt_heap_size;
uword flags;
char *backing_file;
uword backing_mmap_size;
@@ -116,6 +117,7 @@ void *svm_region_find_or_create (svm_map_region_args_t * a);
void svm_region_init (void);
void svm_region_init_chroot (char *root_path);
void svm_region_init_chroot_uid_gid (char *root_path, int uid, int gid);
+void svm_region_init_args (svm_map_region_args_t *a);
void svm_region_exit (void);
void svm_region_unmap (void *rp_arg);
void svm_client_scan (char *root_path);
diff --git a/svm/svmtool.c b/svm/svmtool.c
index 545f071e47e..2e55a0873e3 100644
--- a/svm/svmtool.c
+++ b/svm/svmtool.c
@@ -206,10 +206,10 @@ svm_map_region_nolock (svm_map_region_args_t * a)
* 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);
@@ -247,7 +247,8 @@ svm_existing_region_map_nolock (void *root_arg, svm_map_region_args_t * a)
void *oldheap;
uword *p;
- a->size += MMAP_PAGESIZE + SVM_PVT_MHEAP_SIZE;
+ a->size += MMAP_PAGESIZE +
+ (a->pvt_heap_size ? a->pvt_heap_size : SVM_PVT_MHEAP_SIZE);
a->size = rnd_pagesize (a->size);
region_lock (root_rp, 4);