svm: make more fifo segment header fields private
[vpp.git] / src / vnet / session / segment_manager.c
index 73b2f71..e04f626 100644 (file)
@@ -87,9 +87,9 @@ segment_manager_segment_index (segment_manager_t * sm, fifo_segment_t * seg)
  * If needed a writer's lock is acquired before allocating a new segment
  * to avoid affecting any of the segments pool readers.
  */
-int
-segment_manager_add_segment (segment_manager_t *sm, uword segment_size,
-                            u8 notify_app)
+static inline int
+segment_manager_add_segment_inline (segment_manager_t *sm, uword segment_size,
+                                   u8 notify_app, u8 flags)
 {
   segment_manager_main_t *smm = &sm_main;
   segment_manager_props_t *props;
@@ -158,10 +158,11 @@ segment_manager_add_segment (segment_manager_t *sm, uword segment_size,
   /*
    * Set watermarks in segment
    */
-  fs->h->high_watermark = sm->high_watermark;
-  fs->h->low_watermark = sm->low_watermark;
+  fs->high_watermark = sm->high_watermark;
+  fs->low_watermark = sm->low_watermark;
+  fs->flags = flags;
+  fs->flags &= ~FIFO_SEGMENT_F_MEM_LIMIT;
   fs->h->pct_first_alloc = props->pct_first_alloc;
-  fs->h->flags &= ~FIFO_SEGMENT_F_MEM_LIMIT;
 
   if (notify_app)
     {
@@ -181,6 +182,20 @@ done:
   return fs_index;
 }
 
+int
+segment_manager_add_segment (segment_manager_t *sm, uword segment_size,
+                            u8 notify_app)
+{
+  return segment_manager_add_segment_inline (sm, segment_size, notify_app, 0);
+}
+
+int
+segment_manager_add_segment2 (segment_manager_t *sm, uword segment_size,
+                             u8 flags)
+{
+  return segment_manager_add_segment_inline (sm, segment_size, 0, flags);
+}
+
 /**
  * Remove segment without lock
  */
@@ -498,8 +513,8 @@ sm_free_w_index_helper (void *arg)
     segment_manager_free (sm);
 }
 
-static void
-segment_manager_free_safe (segment_manager_t * sm)
+void
+segment_manager_free_safe (segment_manager_t *sm)
 {
   if (!vlib_thread_is_main_w_barrier ())
     {
@@ -626,6 +641,59 @@ segment_manager_del_sessions (segment_manager_t * sm)
   vec_free (handles);
 }
 
+/**
+ * Initiate disconnects for sessions in specified state 'owned' by a segment
+ * manager
+ */
+void
+segment_manager_del_sessions_filter (segment_manager_t *sm,
+                                    session_state_t *states)
+{
+  session_handle_t *handles = 0, *handle;
+  fifo_segment_t *fs;
+  session_t *session;
+  int slice_index;
+  svm_fifo_t *f;
+
+  ASSERT (pool_elts (sm->segments) != 0);
+
+  /* Across all fifo segments used by the server */
+  segment_manager_foreach_segment_w_lock (
+    fs, sm, ({
+      for (slice_index = 0; slice_index < fs->n_slices; slice_index++)
+       {
+         f = fifo_segment_get_slice_fifo_list (fs, slice_index);
+         while (f)
+           {
+             session = session_get_if_valid (f->shr->master_session_index,
+                                             f->master_thread_index);
+             if (session)
+               {
+                 session_state_t *state;
+                 vec_foreach (state, states)
+                   {
+                     if (session->session_state == *state)
+                       {
+                         vec_add1 (handles, session_handle (session));
+                         break;
+                       }
+                   }
+               }
+             f = f->next;
+           }
+       }
+    }));
+
+  vec_foreach (handle, handles)
+    {
+      session = session_get_from_handle (*handle);
+      session_close (session);
+      /* Avoid propagating notifications back to the app */
+      session->app_wrk_index = APP_INVALID_INDEX;
+    }
+  vec_free (handles);
+}
+
 int
 segment_manager_try_alloc_fifos (fifo_segment_t * fifo_segment,
                                 u32 thread_index,
@@ -685,16 +753,16 @@ segment_manager_alloc_session_fifos (segment_manager_t * sm,
 
   segment_manager_segment_reader_lock (sm);
 
-  /* *INDENT-OFF* */
   pool_foreach (cur, sm->segments)  {
-    free_bytes = fifo_segment_available_bytes (cur);
-    if (free_bytes > max_free_bytes)
-      {
-        max_free_bytes = free_bytes;
-        fs = cur;
-      }
+      if (fifo_segment_flags (cur) & FIFO_SEGMENT_F_CUSTOM_USE)
+       continue;
+      free_bytes = fifo_segment_available_bytes (cur);
+      if (free_bytes > max_free_bytes)
+       {
+         max_free_bytes = free_bytes;
+         fs = cur;
+       }
   }
-  /* *INDENT-ON* */
 
   if (fs)
     {
@@ -1004,10 +1072,11 @@ segment_manager_format_sessions (segment_manager_t * sm, int verbose)
   if (!sm)
     {
       if (verbose)
-       vlib_cli_output (vm, "%-40s%-20s%-15s%-10s", "Connection", "App",
-                        "API Client", "SegManager");
+       vlib_cli_output (vm, "%-" SESSION_CLI_ID_LEN "s%-20s%-15s%-10s",
+                        "Connection", "App", "API Client", "SegManager");
       else
-       vlib_cli_output (vm, "%-40s%-20s", "Connection", "App");
+       vlib_cli_output (vm, "%-" SESSION_CLI_ID_LEN "s%-20s", "Connection",
+                        "App");
       return;
     }
 
@@ -1033,11 +1102,11 @@ segment_manager_format_sessions (segment_manager_t * sm, int verbose)
            str = format (0, "%U", format_session, session, verbose);
 
            if (verbose)
-             s = format (s, "%-40v%-20v%-15u%-10u", str, app_name,
-                         app_wrk->api_client_index,
+             s = format (s, "%-" SESSION_CLI_ID_LEN "v%-20v%-15u%-10u", str,
+                         app_name, app_wrk->api_client_index,
                          app_wrk->connects_seg_manager);
            else
-             s = format (s, "%-40v%-20v", str, app_name);
+             s = format (s, "%-" SESSION_CLI_ID_LEN "v%-20v", str, app_name);
 
            vlib_cli_output (vm, "%v", s);
            vec_reset_length (s);