diff options
author | Florin Coras <fcoras@cisco.com> | 2018-01-29 05:11:24 -0800 |
---|---|---|
committer | Damjan Marion <dmarion.lists@gmail.com> | 2018-02-02 09:11:33 +0000 |
commit | d6c30d9cae3ec8946c75d9ed87d40c053e2c083a (patch) | |
tree | 3addc31e5f2499a04cf3ffb5873e3f4c3e5a54e2 /src/svm/svm.c | |
parent | f2d0611e1bca0cca0776dc833fd42ae7b358d8e4 (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/svm.c')
-rw-r--r-- | src/svm/svm.c | 39 |
1 files changed, 34 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; |