summaryrefslogtreecommitdiffstats
path: root/src/svm
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2018-01-29 05:11:24 -0800
committerDamjan Marion <dmarion.lists@gmail.com>2018-02-02 09:11:33 +0000
commitd6c30d9cae3ec8946c75d9ed87d40c053e2c083a (patch)
tree3addc31e5f2499a04cf3ffb5873e3f4c3e5a54e2 /src/svm
parentf2d0611e1bca0cca0776dc833fd42ae7b358d8e4 (diff)
vlmemory/svm: fix client detach from svm region
Clients cannot know at svm region detach time if the shm backing files have been recreated (e.g., if vpp restarts) and therefore should not try to unlink them. Otherwise, terminating clients attached to previous instantiations of a re-allocated region end up making the new instance un-mappable by removing its backing file. Change-Id: Idcd0cab776e63fd75b821bc9f0fac58217b9ccbe Signed-off-by: Florin Coras <fcoras@cisco.com>
Diffstat (limited to 'src/svm')
-rw-r--r--src/svm/svm.c39
-rw-r--r--src/svm/svm_common.h2
2 files changed, 36 insertions, 5 deletions
diff --git a/src/svm/svm.c b/src/svm/svm.c
index d3e56c1a46a..16a58fa126a 100644
--- a/src/svm/svm.c
+++ b/src/svm/svm.c
@@ -1034,7 +1034,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 +1134,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 +1152,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 +1208,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);
@@ -1202,6 +1219,18 @@ found:
}
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)
{
int j;
diff --git a/src/svm/svm_common.h b/src/svm/svm_common.h
index c650165b4cf..e523da50db6 100644
--- a/src/svm/svm_common.h
+++ b/src/svm/svm_common.h
@@ -118,7 +118,9 @@ int svm_region_init_chroot (const char *root_path);
void svm_region_init_chroot_uid_gid (const char *root_path, int uid, int gid);
void svm_region_init_args (svm_map_region_args_t * a);
void svm_region_exit (void);
+void svm_region_exit_client (void);
void svm_region_unmap (void *rp_arg);
+void svm_region_unmap_client (void *rp_arg);
void svm_client_scan (const char *root_path);
void svm_client_scan_this_region_nolock (svm_region_t * rp);
u8 *shm_name_from_svm_map_region_args (svm_map_region_args_t * a);