VPP API: Memory trace
[vpp.git] / src / svm / svm.c
index d3e56c1..d958c83 100644 (file)
@@ -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)
 {