diff options
author | Dave Barach <dave@barachs.net> | 2016-08-03 14:34:38 -0400 |
---|---|---|
committer | Keith Burns <alagalah@gmail.com> | 2016-08-15 13:57:25 +0000 |
commit | b3d93dacfde8ab21bbce171fff2971b2ed7bce6a (patch) | |
tree | 8d3b44e8a8fcbf155979114a929590fc9473b914 /svm | |
parent | c53191deb39231cf8408cf9eb0adf5c878ddda68 (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.c | 92 | ||||
-rw-r--r-- | svm/svm.h | 6 | ||||
-rw-r--r-- | svm/svmtool.c | 9 |
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); |