fib: fix crash when create vxlan/vxlan-gpe/geneve/gtpu tunnel.
[vpp.git] / src / svm / svm.c
index d958c83..0a91055 100644 (file)
@@ -36,7 +36,6 @@
 #include <vppinfra/bitmap.h>
 #include <vppinfra/fifo.h>
 #include <vppinfra/time.h>
-#include <vppinfra/mheap.h>
 #include <vppinfra/heap.h>
 #include <vppinfra/pool.h>
 #include <vppinfra/format.h>
@@ -91,8 +90,11 @@ svm_get_global_region_base_va ()
     clib_unix_error ("unexpected va bits '%u'", bits);
 #endif
 
+#ifdef CLIB_SANITIZE_ADDR
+  return 0x200000000000;
+#endif
   /* default value */
-  return 0x30000000;
+  return 0x130000000ULL;
 }
 
 static void
@@ -103,7 +105,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
@@ -236,14 +238,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);
@@ -333,18 +327,15 @@ svm_data_region_create (svm_map_region_args_t * a, svm_region_t * rp)
          return -3;
        }
       close (fd);
-      rp->backing_file = (char *) format (0, "%s\0", a->backing_file);
+      clib_mem_unpoison (rp->data_base, map_size);
+      rp->backing_file = (char *) format (0, "%s%c", a->backing_file, 0);
       rp->flags |= SVM_FLAGS_FILE;
     }
 
   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->data_heap = clib_mem_create_heap (rp->data_base, map_size,
+                                           1 /* locked */ , "svm data");
 
       rp->flags |= SVM_FLAGS_MHEAP;
     }
@@ -421,6 +412,7 @@ svm_data_region_map (svm_map_region_args_t * a, svm_region_t * rp)
          return -3;
        }
       close (fd);
+      clib_mem_unpoison (rp->data_base, map_size);
     }
   return 0;
 }
@@ -428,10 +420,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;
 
@@ -441,29 +430,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;
 
@@ -487,7 +453,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");
@@ -518,12 +484,12 @@ 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 = clib_mem_create_heap
+    (uword_to_pointer (a->baseva + MMAP_PAGESIZE, void *),
+     (a->pvt_heap_size !=
+      0) ? a->pvt_heap_size : SVM_PVT_MHEAP_SIZE, 1 /* locked */ ,
+     "svm region");
+
   oldheap = svm_push_pvt_heap (rp);
 
   rp->region_name = (char *) format (0, "%s%c", a->name, 0);
@@ -639,6 +605,7 @@ svm_map_region (svm_map_region_args_t * a)
          return (0);
        }
       close (svm_fd);
+      clib_mem_unpoison (rp, a->size);
 
       svm_region_init_mapped_region (a, rp);
 
@@ -695,6 +662,9 @@ svm_map_region (svm_map_region_args_t * a)
          clib_warning ("mmap");
          return (0);
        }
+
+      clib_mem_unpoison (rp, MMAP_PAGESIZE);
+
       /*
        * We lost the footrace to create this region; make sure
        * the winner has crossed the finish line.
@@ -731,6 +701,8 @@ svm_map_region (svm_map_region_args_t * a)
 
       close (svm_fd);
 
+      clib_mem_unpoison (rp, a->size);
+
       if ((uword) rp != rp->virtual_base)
        {
          clib_warning ("mmap botch");
@@ -743,12 +715,17 @@ svm_map_region (svm_map_region_args_t * a)
       pid_holding_region_lock = rp->mutex_owner_pid;
       if (pid_holding_region_lock && kill (pid_holding_region_lock, 0) < 0)
        {
+         pthread_mutexattr_t attr;
          clib_warning
            ("region %s mutex held by dead pid %d, tag %d, force unlock",
             rp->region_name, pid_holding_region_lock, rp->mutex_owner_tag);
          /* owner pid is nonexistent */
-         rp->mutex.__data.__owner = 0;
-         rp->mutex.__data.__lock = 0;
+         if (pthread_mutexattr_init (&attr))
+           clib_unix_warning ("mutexattr_init");
+         if (pthread_mutexattr_setpshared (&attr, PTHREAD_PROCESS_SHARED))
+           clib_unix_warning ("mutexattr_setpshared");
+         if (pthread_mutex_init (&rp->mutex, &attr))
+           clib_unix_warning ("mutex_init");
          dead_region_recovery = 1;
        }
 
@@ -778,7 +755,7 @@ svm_map_region (svm_map_region_args_t * a)
       return ((void *) rp);
 
     }
-  return 0;                    /* NOTREACHED */
+  return 0;                    /* NOTREACHED *///NOSONAR
 }
 
 static void
@@ -787,7 +764,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
     }
 }
 
@@ -848,7 +825,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 ();
@@ -865,7 +842,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 ();
@@ -882,7 +859,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 ();
@@ -1074,6 +1051,7 @@ svm_region_unmap_internal (void *rp_arg, u8 is_client)
   oldheap = svm_push_pvt_heap (rp);    /* nb vec_delete() in the loop */
 
   /* Remove the caller from the list of mappers */
+  clib_mem_unpoison (rp->client_pids, vec_bytes (rp->client_pids));
   for (i = 0; i < vec_len (rp->client_pids); i++)
     {
       if (rp->client_pids[i] == mypid)
@@ -1206,6 +1184,7 @@ svm_region_exit_internal (u8 is_client)
   virtual_base = root_rp->virtual_base;
   virtual_size = root_rp->virtual_size;
 
+  clib_mem_unpoison (root_rp->client_pids, vec_bytes (root_rp->client_pids));
   for (i = 0; i < vec_len (root_rp->client_pids); i++)
     {
       if (root_rp->client_pids[i] == mypid)
@@ -1313,10 +1292,10 @@ svm_client_scan (const char *root_path)
    * find_or_create.
    */
   /* *INDENT-OFF* */
-  pool_foreach (subp, mp->subregions, ({
+  pool_foreach (subp, mp->subregions)  {
         name = vec_dup (subp->subregion_name);
         vec_add1(svm_names, name);
-      }));
+      }
   /* *INDENT-ON* */
 
   pthread_mutex_unlock (&root_rp->mutex);