X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fsvm%2Fsvm.c;h=6249a342be28a141fe6b4be981f59186a534c994;hb=c35f3e835b4078fedabc1ff5013bc4727f533e16;hp=2cbc0d77c22e41caa094b52daf2cbc00c2d9381e;hpb=83d47438ae7c9b3fc53329846ee46a82a3087578;p=vpp.git diff --git a/src/svm/svm.c b/src/svm/svm.c index 2cbc0d77c22..6249a342be2 100644 --- a/src/svm/svm.c +++ b/src/svm/svm.c @@ -61,6 +61,10 @@ svm_get_root_rp (void) u64 svm_get_global_region_base_va () { +#ifdef CLIB_SANITIZE_ADDR + return 0x200000000000; +#endif + #if __aarch64__ /* On AArch64 VA space can have different size, from 36 to 48 bits. Here we are trying to detect VA bits by parsing /proc/self/maps @@ -76,14 +80,15 @@ svm_get_global_region_base_va () unformat_init_clib_file (&input, fd); while (unformat_check_input (&input) != UNFORMAT_END_OF_INPUT) { - unformat (&input, "%llx-%llx", &start, &end); + if (unformat (&input, "%llx-%llx", &start, &end)) + end--; unformat_skip_line (&input); } unformat_free (&input); close (fd); - count_leading_zeros (bits, end); - bits = 64 - (bits + 1); + bits = count_leading_zeros (end); + bits = 64 - bits; if (bits >= 36 && bits <= 48) return ((1ul << bits) / 4) - (2 * SVM_GLOBAL_REGION_SIZE); else @@ -91,7 +96,7 @@ svm_get_global_region_base_va () #endif /* default value */ - return 0x30000000; + return 0x130000000ULL; } static void @@ -102,7 +107,7 @@ region_lock (svm_region_t * rp, int tag) rp->mutex_owner_pid = getpid (); rp->mutex_owner_tag = tag; #endif - ASSERT (nheld < MAXLOCK); + ASSERT (nheld < MAXLOCK); //NOSONAR /* * Keep score of held mutexes so we can try to exit * cleanly if the world comes to an end at the worst possible @@ -235,14 +240,6 @@ format_svm_region (u8 * s, va_list * args) } } } - s = format (s, " rgn heap stats: %U", format_mheap, - rp->region_heap, 0); - if ((rp->flags & SVM_FLAGS_MHEAP) && rp->data_heap) - { - s = format (s, "\n data heap stats: %U", format_mheap, - rp->data_heap, 1); - } - s = format (s, "\n"); } return (s); @@ -338,9 +335,10 @@ svm_data_region_create (svm_map_region_args_t * a, svm_region_t * rp) if (a->flags & SVM_FLAGS_MHEAP) { - rp->data_heap = - mheap_alloc_with_flags ((void *) (rp->data_base), map_size, - MHEAP_FLAG_DISABLE_VM); + rp->data_heap = create_mspace_with_base (rp->data_base, + map_size, 1 /* locked */ ); + mspace_disable_expand (rp->data_heap); + rp->flags |= SVM_FLAGS_MHEAP; } return 0; @@ -423,10 +421,7 @@ svm_data_region_map (svm_map_region_args_t * a, svm_region_t * rp) u8 * shm_name_from_svm_map_region_args (svm_map_region_args_t * a) { - u8 *path; u8 *shm_name; - u8 *split_point; - u8 *mkdir_arg = 0; int root_path_offset = 0; int name_offset = 0; @@ -436,29 +431,6 @@ shm_name_from_svm_map_region_args (svm_map_region_args_t * a) if (a->root_path[0] == '/') root_path_offset++; - /* create the root_path under /dev/shm - iterate through path creating directories */ - - path = format (0, "/dev/shm/%s%c", &a->root_path[root_path_offset], 0); - split_point = path + 1; - vec_add1 (mkdir_arg, '-'); - - while (*split_point) - { - while (*split_point && *split_point != '/') - { - vec_add1 (mkdir_arg, *split_point); - split_point++; - } - vec_add1 (mkdir_arg, 0); - - /* ready to descend another level */ - mkdir_arg[vec_len (mkdir_arg) - 1] = '-'; - split_point++; - } - vec_free (mkdir_arg); - vec_free (path); - if (a->name[0] == '/') name_offset = 1; @@ -482,7 +454,7 @@ svm_region_init_mapped_region (svm_map_region_args_t * a, svm_region_t * rp) ASSERT (rp); int rv; - memset (rp, 0, sizeof (*rp)); + clib_memset (rp, 0, sizeof (*rp)); if (pthread_mutexattr_init (&attr)) clib_unix_warning ("mutexattr_init"); @@ -513,12 +485,13 @@ svm_region_init_mapped_region (svm_map_region_args_t * a, svm_region_t * rp) rp->virtual_base = a->baseva; rp->virtual_size = a->size; - rp->region_heap = - mheap_alloc_with_flags (uword_to_pointer - (a->baseva + MMAP_PAGESIZE, void *), - (a->pvt_heap_size != - 0) ? a->pvt_heap_size : SVM_PVT_MHEAP_SIZE, - MHEAP_FLAG_DISABLE_VM); + rp->region_heap = create_mspace_with_base + (uword_to_pointer (a->baseva + MMAP_PAGESIZE, void *), + (a->pvt_heap_size != + 0) ? a->pvt_heap_size : SVM_PVT_MHEAP_SIZE, 1 /* locked */ ); + + mspace_disable_expand (rp->region_heap); + oldheap = svm_push_pvt_heap (rp); rp->region_name = (char *) format (0, "%s%c", a->name, 0); @@ -651,6 +624,10 @@ svm_map_region (svm_map_region_args_t * a) return (0); } + /* Reset ownership in case the client started first */ + if (fchown (svm_fd, a->uid, a->gid) < 0) + clib_unix_warning ("segment chown [ok if client starts first]"); + time_left = 20; while (1) { @@ -720,6 +697,8 @@ svm_map_region (svm_map_region_args_t * a) return (0); } + close (svm_fd); + if ((uword) rp != rp->virtual_base) { clib_warning ("mmap botch"); @@ -767,7 +746,7 @@ svm_map_region (svm_map_region_args_t * a) return ((void *) rp); } - return 0; /* NOTREACHED */ + return 0; /* NOTREACHED *///NOSONAR } static void @@ -776,7 +755,7 @@ svm_mutex_cleanup (void) int i; for (i = 0; i < nheld; i++) { - pthread_mutex_unlock (mutexes_held[i]); + pthread_mutex_unlock (mutexes_held[i]); //NOSONAR } } @@ -837,7 +816,7 @@ svm_region_init (void) { svm_map_region_args_t _a, *a = &_a; - memset (a, 0, sizeof (*a)); + clib_memset (a, 0, sizeof (*a)); a->root_path = 0; a->name = SVM_GLOBAL_REGION_NAME; a->baseva = svm_get_global_region_base_va (); @@ -854,7 +833,7 @@ svm_region_init_chroot (const char *root_path) { svm_map_region_args_t _a, *a = &_a; - memset (a, 0, sizeof (*a)); + clib_memset (a, 0, sizeof (*a)); a->root_path = root_path; a->name = SVM_GLOBAL_REGION_NAME; a->baseva = svm_get_global_region_base_va (); @@ -871,7 +850,7 @@ svm_region_init_chroot_uid_gid (const char *root_path, int uid, int gid) { svm_map_region_args_t _a, *a = &_a; - memset (a, 0, sizeof (*a)); + clib_memset (a, 0, sizeof (*a)); a->root_path = root_path; a->name = SVM_GLOBAL_REGION_NAME; a->baseva = svm_get_global_region_base_va (); @@ -1033,7 +1012,7 @@ svm_region_unlink (svm_region_t * rp) * a new region client showing up at the wrong moment. */ void -svm_region_unmap (void *rp_arg) +svm_region_unmap_internal (void *rp_arg, u8 is_client) { int i, mypid = getpid (); int nclients_left; @@ -1133,7 +1112,12 @@ found: vec_free (name); region_unlock (rp); - svm_region_unlink (rp); + + /* If a client asks for the cleanup, don't unlink the backing + * file since we can't tell if it has been recreated. */ + if (!is_client) + svm_region_unlink (rp); + munmap ((void *) virtual_base, virtual_size); region_unlock (root_rp); svm_pop_heap (oldheap); @@ -1146,11 +1130,23 @@ found: munmap ((void *) virtual_base, virtual_size); } +void +svm_region_unmap (void *rp_arg) +{ + svm_region_unmap_internal (rp_arg, 0 /* is_client */ ); +} + +void +svm_region_unmap_client (void *rp_arg) +{ + svm_region_unmap_internal (rp_arg, 1 /* is_client */ ); +} + /* * svm_region_exit */ -void -svm_region_exit () +static void +svm_region_exit_internal (u8 is_client) { void *oldheap; int i, mypid = getpid (); @@ -1190,7 +1186,7 @@ svm_region_exit () found: - if (vec_len (root_rp->client_pids) == 0) + if (!is_client && vec_len (root_rp->client_pids) == 0) svm_region_unlink (root_rp); region_unlock (root_rp); @@ -1200,6 +1196,18 @@ found: munmap ((void *) virtual_base, virtual_size); } +void +svm_region_exit (void) +{ + svm_region_exit_internal (0 /* is_client */ ); +} + +void +svm_region_exit_client (void) +{ + svm_region_exit_internal (1 /* is_client */ ); +} + void svm_client_scan_this_region_nolock (svm_region_t * rp) {