summaryrefslogtreecommitdiffstats
path: root/src/vnet/session/segment_manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/session/segment_manager.c')
-rw-r--r--src/vnet/session/segment_manager.c73
1 files changed, 40 insertions, 33 deletions
diff --git a/src/vnet/session/segment_manager.c b/src/vnet/session/segment_manager.c
index c23e4c0237c..48d027553b1 100644
--- a/src/vnet/session/segment_manager.c
+++ b/src/vnet/session/segment_manager.c
@@ -197,27 +197,24 @@ u8
segment_manager_has_fifos (segment_manager_t * sm)
{
svm_fifo_segment_private_t *segment;
- /* Weird, but handle it */
- if (vec_len (sm->segment_indices) == 0)
- return 0;
- if (vec_len (sm->segment_indices) == 1)
- {
- segment = svm_fifo_segment_get_segment (sm->segment_indices[0]);
- if (svm_fifo_segment_num_fifos (segment) == 0)
- return 0;
- }
- if (CLIB_DEBUG)
+ int i;
+
+ for (i = 0; i < vec_len (sm->segment_indices); i++)
{
- svm_fifo_segment_private_t *segment;
- int i;
- for (i = 1; i < vec_len (sm->segment_indices); i++)
- {
- segment = svm_fifo_segment_get_segment (sm->segment_indices[i]);
- if (!svm_fifo_segment_has_fifos (segment))
- clib_warning ("segment has no fifos!");
- }
+ segment = svm_fifo_segment_get_segment (sm->segment_indices[i]);
+ if (CLIB_DEBUG && i && !svm_fifo_segment_has_fifos (segment)
+ && !(segment->h->flags & FIFO_SEGMENT_F_IS_PREALLOCATED))
+ clib_warning ("segment %d has no fifos!", sm->segment_indices[i]);
+ if (svm_fifo_segment_has_fifos (segment))
+ return 1;
}
- return 1;
+ return 0;
+}
+
+static u8
+segment_manager_app_detached (segment_manager_t * sm)
+{
+ return (sm->app_index == SEGMENT_MANAGER_INVALID_APP_INDEX);
}
static void
@@ -228,6 +225,13 @@ segment_manager_del_segment (segment_manager_t * sm, u32 segment_index)
clib_spinlock_lock (&sm->lockp);
svm_segment_index = sm->segment_indices[segment_index];
fifo_segment = svm_fifo_segment_get_segment (svm_segment_index);
+ if (!fifo_segment
+ || ((fifo_segment->h->flags & FIFO_SEGMENT_F_IS_PREALLOCATED)
+ && !segment_manager_app_detached (sm)))
+ {
+ clib_spinlock_unlock (&sm->lockp);
+ return;
+ }
svm_fifo_segment_delete (fifo_segment);
vec_del1 (sm->segment_indices, segment_index);
clib_spinlock_unlock (&sm->lockp);
@@ -288,26 +292,29 @@ segment_manager_del_sessions (segment_manager_t * sm)
*
* Since the fifos allocated in the segment keep backpointers to the sessions
* prior to removing the segment, we call session disconnect. This
- * subsequently propages into transport.
+ * subsequently propagates into transport.
*/
void
segment_manager_del (segment_manager_t * sm)
{
+ int i;
- ASSERT (vec_len (sm->segment_indices) <= 1);
- if (vec_len (sm->segment_indices))
+ ASSERT (!segment_manager_has_fifos (sm)
+ && segment_manager_app_detached (sm));
+
+ /* If we have empty preallocated segments that haven't been removed, remove
+ * them now. Apart from that, the first segment in the first segment manager
+ * is not removed when all fifos are removed. It can only be removed when
+ * the manager is explicitly deleted/detached by the app. */
+ for (i = vec_len (sm->segment_indices) - 1; i >= 0; i--)
{
- /* The first segment in the first segment manager is not removed when
- * all fifos are removed. It can only be removed when the manager is
- * explicitly deleted/detached by the app. */
if (CLIB_DEBUG)
{
- svm_fifo_segment_private_t *fifo_segment;
- fifo_segment =
- svm_fifo_segment_get_segment (sm->segment_indices[0]);
- ASSERT (!svm_fifo_segment_has_fifos (fifo_segment));
+ svm_fifo_segment_private_t *segment;
+ segment = svm_fifo_segment_get_segment (sm->segment_indices[i]);
+ ASSERT (!svm_fifo_segment_has_fifos (segment));
}
- segment_manager_del_segment (sm, 0);
+ segment_manager_del_segment (sm, i);
}
clib_spinlock_free (&sm->lockp);
if (CLIB_DEBUG)
@@ -322,8 +329,7 @@ segment_manager_init_del (segment_manager_t * sm)
segment_manager_del_sessions (sm);
else
{
- ASSERT (!sm->first_is_protected
- || sm->app_index == SEGMENT_MANAGER_INVALID_APP_INDEX);
+ ASSERT (!sm->first_is_protected || segment_manager_app_detached (sm));
segment_manager_del (sm);
}
}
@@ -478,7 +484,8 @@ segment_manager_dealloc_fifos (u32 svm_segment_index, svm_fifo_t * rx_fifo,
}
/* Remove segment manager if no sessions and detached from app */
- if (sm->app_index == SEGMENT_MANAGER_INVALID_APP_INDEX && is_first)
+ if (segment_manager_app_detached (sm)
+ && !segment_manager_has_fifos (sm))
segment_manager_del (sm);
}
}