vppinfra: clib_mem_vm_{un}map thread safe 27/29627/2
authorDamjan Marion <damarion@cisco.com>
Mon, 26 Oct 2020 09:39:30 +0000 (10:39 +0100)
committerFlorin Coras <florin.coras@gmail.com>
Mon, 26 Oct 2020 23:39:27 +0000 (23:39 +0000)
Type: improvement
Change-Id: I1ab1b100000b4d7212c58e10312e16e7527bd333
Signed-off-by: Damjan Marion <damarion@cisco.com>
src/vppinfra/linux/mem.c
src/vppinfra/mem.h

index 1ef90da..121bf94 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <vppinfra/clib.h>
 #include <vppinfra/mem.h>
+#include <vppinfra/lock.h>
 #include <vppinfra/time.h>
 #include <vppinfra/format.h>
 #include <vppinfra/clib_error.h>
 #define MAP_FIXED_NOREPLACE 0x100000
 #endif
 
+static void
+map_lock ()
+{
+  while (clib_atomic_test_and_set (&clib_mem_main.map_lock))
+    CLIB_PAUSE ();
+}
+
+static void
+map_unlock ()
+{
+  clib_atomic_release (&clib_mem_main.map_lock);
+}
+
 __clib_export uword
 clib_mem_get_default_hugepage_size (void)
 {
@@ -463,6 +477,8 @@ clib_mem_vm_map_internal (void *base, clib_mem_page_sz_t log2_page_sz,
       return CLIB_MEM_VM_MAP_FAILED;
     }
 
+  map_lock ();
+
   if (mm->last_map)
     {
       mprotect (mm->last_map, sys_page_sz, PROT_READ | PROT_WRITE);
@@ -477,6 +493,8 @@ clib_mem_vm_map_internal (void *base, clib_mem_page_sz_t log2_page_sz,
   hdr->prev = mm->last_map;
   mm->last_map = hdr;
 
+  map_unlock ();
+
   hdr->base_addr = (uword) base;
   hdr->log2_page_sz = log2_page_sz;
   hdr->num_pages = size >> log2_page_sz;
@@ -503,6 +521,8 @@ clib_mem_vm_unmap (void *base)
   if (munmap ((void *) hdr->base_addr, size) != 0)
     return CLIB_MEM_ERROR;
 
+  map_lock ();
+
   if (hdr->next)
     {
       mprotect (hdr->next, sys_page_sz, PROT_READ | PROT_WRITE);
@@ -521,6 +541,8 @@ clib_mem_vm_unmap (void *base)
   else
     mm->first_map = hdr->next;
 
+  map_unlock ();
+
   if (munmap (hdr, sys_page_sz) != 0)
     return CLIB_MEM_ERROR;
 
index ca8161a..aba29bc 100644 (file)
@@ -145,6 +145,9 @@ typedef struct
   /* memory maps */
   clib_mem_vm_map_hdr_t *first_map, *last_map;
 
+  /* map lock */
+  u8 map_lock;
+
   /* last error */
   clib_error_t *error;
 } clib_mem_main_t;