X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fsvm%2Fsvm.c;h=d958c8378e5388c717a8a8a2a36e1a4b60536ec6;hb=73710c7da2f8deaea83dbbbfce8737c9c6cd2949;hp=d3e56c1a46a47569464580ec30e1ebd7829554b0;hpb=c5239ad59716a833a15523755b03418a47e02a5a;p=vpp.git diff --git a/src/svm/svm.c b/src/svm/svm.c index d3e56c1a46a..d958c8378e5 100644 --- a/src/svm/svm.c +++ b/src/svm/svm.c @@ -83,7 +83,7 @@ svm_get_global_region_base_va () unformat_free (&input); close (fd); - count_leading_zeros (bits, end); + bits = count_leading_zeros (end); bits = 64 - bits; if (bits >= 36 && bits <= 48) return ((1ul << bits) / 4) - (2 * SVM_GLOBAL_REGION_SIZE); @@ -339,9 +339,13 @@ svm_data_region_create (svm_map_region_args_t * a, svm_region_t * rp) if (a->flags & SVM_FLAGS_MHEAP) { + mheap_t *heap_header; rp->data_heap = mheap_alloc_with_flags ((void *) (rp->data_base), map_size, MHEAP_FLAG_DISABLE_VM); + heap_header = mheap_header (rp->data_heap); + heap_header->flags |= MHEAP_FLAG_THREAD_SAFE; + rp->flags |= SVM_FLAGS_MHEAP; } return 0; @@ -652,6 +656,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) { @@ -721,6 +729,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"); @@ -1034,7 +1044,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; @@ -1134,7 +1144,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); @@ -1147,11 +1162,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 (); @@ -1191,7 +1218,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); @@ -1201,6 +1228,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) {