vcl: wait for segments with segment handle
[vpp.git] / src / vnet / session / application.c
index a70625a..f362896 100644 (file)
@@ -443,7 +443,7 @@ application_detach_process (application_t * app, u32 api_client_index)
   vec_foreach (wrk_index, wrks)
   {
     app_wrk = app_worker_get (wrk_index[0]);
-    args->wrk_index = app_wrk->wrk_map_index;
+    args->wrk_map_index = app_wrk->wrk_map_index;
     args->is_add = 0;
     vnet_app_worker_add_del (args);
   }
@@ -924,21 +924,22 @@ vnet_app_worker_add_del (vnet_app_worker_add_del_args_t * a)
       sm = segment_manager_get (app_wrk->first_segment_manager);
       fs = segment_manager_get_segment_w_lock (sm, 0);
       a->segment = &fs->ssvm;
+      a->segment_handle = segment_manager_segment_handle (sm, fs);
       segment_manager_segment_reader_unlock (sm);
       a->evt_q = app_wrk->event_queue;
-      a->wrk_index = app_wrk->wrk_map_index;
+      a->wrk_map_index = app_wrk->wrk_map_index;
     }
   else
     {
-      wrk_map = app_worker_map_get (app, a->wrk_index);
+      wrk_map = app_worker_map_get (app, a->wrk_map_index);
       if (!wrk_map)
        return clib_error_return_code (0, VNET_API_ERROR_INVALID_VALUE, 0,
                                       "App %u does not have worker %u",
-                                      app->app_index, a->wrk_index);
+                                      app->app_index, a->wrk_map_index);
       app_wrk = app_worker_get (wrk_map->wrk_index);
       if (!app_wrk)
        return clib_error_return_code (0, VNET_API_ERROR_INVALID_VALUE, 0,
-                                      "No worker %u", a->wrk_index);
+                                      "No worker %u", a->wrk_map_index);
       application_api_table_del (app_wrk->api_client_index);
       app_worker_free (app_wrk);
       app_worker_map_free (app, wrk_map);
@@ -1007,11 +1008,12 @@ application_use_mq_for_ctrl (application_t * app)
  * Send an API message to the external app, to map new segment
  */
 int
-app_worker_add_segment_notify (u32 app_wrk_index, ssvm_private_t * fs)
+app_worker_add_segment_notify (u32 app_wrk_index, u64 segment_handle)
 {
   app_worker_t *app_wrk = app_worker_get (app_wrk_index);
   application_t *app = application_get (app_wrk->app_index);
-  return app->cb_fns.add_segment_callback (app_wrk->api_client_index, fs);
+  return app->cb_fns.add_segment_callback (app_wrk->api_client_index,
+                                          segment_handle);
 }
 
 u32
@@ -1589,14 +1591,15 @@ application_local_session_connect (app_worker_t * client_wrk,
                                   local_session_t * ll, u32 opaque)
 {
   u32 seg_size, evt_q_sz, evt_q_elts, margin = 16 << 10;
+  u32 round_rx_fifo_sz, round_tx_fifo_sz, sm_index;
   segment_manager_properties_t *props, *cprops;
-  u32 round_rx_fifo_sz, round_tx_fifo_sz;
   int rv, has_transport, seg_index;
   svm_fifo_segment_private_t *seg;
   application_t *server, *client;
   segment_manager_t *sm;
   local_session_t *ls;
   svm_msg_q_t *sq, *cq;
+  u64 segment_handle;
 
   ls = application_local_session_alloc (server_wrk);
   server = application_get (server_wrk->app_index);
@@ -1651,8 +1654,13 @@ application_local_session_connect (app_worker_t * client_wrk,
       segment_manager_segment_reader_unlock (sm);
       goto failed;
     }
+  sm_index = segment_manager_index (sm);
   ls->server_rx_fifo->ct_session_index = ls->session_index;
   ls->server_tx_fifo->ct_session_index = ls->session_index;
+  ls->server_rx_fifo->segment_manager = sm_index;
+  ls->server_tx_fifo->segment_manager = sm_index;
+  ls->server_rx_fifo->segment_index = seg_index;
+  ls->server_tx_fifo->segment_index = seg_index;
   ls->svm_segment_index = seg_index;
   ls->listener_index = ll->session_index;
   ls->client_wrk_index = client_wrk->wrk_index;
@@ -1660,8 +1668,9 @@ application_local_session_connect (app_worker_t * client_wrk,
   ls->listener_session_type = ll->session_type;
   ls->session_state = SESSION_STATE_READY;
 
+  segment_handle = segment_manager_segment_handle (sm, seg);
   if ((rv = server->cb_fns.add_segment_callback (server_wrk->api_client_index,
-                                                &seg->ssvm)))
+                                                segment_handle)))
     {
       clib_warning ("failed to notify server of new segment");
       segment_manager_segment_reader_unlock (sm);
@@ -1706,6 +1715,7 @@ application_local_session_connect_notify (local_session_t * ls)
   segment_manager_t *sm;
   application_t *client;
   int rv, is_fail = 0;
+  u64 segment_handle;
   uword client_key;
 
   client_wrk = app_worker_get (ls->client_wrk_index);
@@ -1714,8 +1724,9 @@ application_local_session_connect_notify (local_session_t * ls)
 
   sm = application_get_local_segment_manager_w_session (server_wrk, ls);
   seg = segment_manager_get_segment_w_lock (sm, ls->svm_segment_index);
+  segment_handle = segment_manager_segment_handle (sm, seg);
   if ((rv = client->cb_fns.add_segment_callback (client_wrk->api_client_index,
-                                                &seg->ssvm)))
+                                                segment_handle)))
     {
       clib_warning ("failed to notify client %u of new segment",
                    ls->client_wrk_index);
@@ -1770,13 +1781,14 @@ application_local_session_cleanup (app_worker_t * client_wrk,
   if (!has_transport)
     {
       application_t *server = application_get (server_wrk->app_index);
+      u64 segment_handle = segment_manager_segment_handle (sm, seg);
       server->cb_fns.del_segment_callback (server_wrk->api_client_index,
-                                          &seg->ssvm);
+                                          segment_handle);
       if (client_wrk)
        {
          application_t *client = application_get (client_wrk->app_index);
          client->cb_fns.del_segment_callback (client_wrk->api_client_index,
-                                              &seg->ssvm);
+                                              segment_handle);
        }
       segment_manager_del_segment (sm, seg);
     }
@@ -2215,6 +2227,19 @@ application_format_local_connects (application_t * app, int verbose)
   /* *INDENT-ON* */
 }
 
+u8 *
+format_application_worker (u8 * s, va_list * args)
+{
+  app_worker_t *app_wrk = va_arg (*args, app_worker_t *);
+  u32 indent = 1;
+
+  s = format (s, "%U wrk-index %u app-index %u map-index %u "
+             "api-client-index %d\n", format_white_space, indent,
+             app_wrk->wrk_index, app_wrk->app_index, app_wrk->wrk_map_index,
+             app_wrk->api_client_index);
+  return s;
+}
+
 u8 *
 format_application (u8 * s, va_list * args)
 {
@@ -2222,13 +2247,12 @@ format_application (u8 * s, va_list * args)
   CLIB_UNUSED (int verbose) = va_arg (*args, int);
   segment_manager_properties_t *props;
   const u8 *app_ns_name, *app_name;
+  app_worker_map_t *wrk_map;
+  app_worker_t *app_wrk;
 
   if (app == 0)
     {
-      if (verbose)
-       s = format (s, "%-10s%-20s%-15s%-15s%-15s%-15s", "Index", "Name",
-                   "Namespace", "Add seg size", "Rx-f size", "Tx-f size");
-      else
+      if (!verbose)
        s = format (s, "%-10s%-20s%-40s", "Index", "Name", "Namespace");
       return s;
     }
@@ -2236,14 +2260,27 @@ format_application (u8 * s, va_list * args)
   app_name = app_get_name (app);
   app_ns_name = app_namespace_id_from_index (app->ns_index);
   props = application_segment_manager_properties (app);
-  if (verbose)
-    s = format (s, "%-10u%-20s%-15u%-15U%-15U%-15U", app->app_index,
-               app_name, app->ns_index,
-               format_memory_size, props->add_segment_size,
-               format_memory_size, props->rx_fifo_size, format_memory_size,
-               props->tx_fifo_size);
-  else
-    s = format (s, "%-10u%-20s%-40s", app->app_index, app_name, app_ns_name);
+  if (!verbose)
+    {
+      s = format (s, "%-10u%-20s%-40s", app->app_index, app_name,
+                 app_ns_name);
+      return s;
+    }
+
+  s = format (s, "app-name %s app-index %u ns-index %u seg-size %U\n",
+             app_name, app->app_index, app->ns_index,
+             format_memory_size, props->add_segment_size);
+  s = format (s, "rx-fifo-size %U tx-fifo-size %U workers:\n",
+             format_memory_size, props->rx_fifo_size,
+             format_memory_size, props->tx_fifo_size);
+
+  /* *INDENT-OFF* */
+  pool_foreach (wrk_map, app->worker_maps, ({
+      app_wrk = app_worker_get (wrk_map->wrk_index);
+      s = format (s, "%U", format_application_worker, app_wrk);
+  }));
+  /* *INDENT-ON* */
+
   return s;
 }
 
@@ -2318,6 +2355,7 @@ show_app_command_fn (vlib_main_t * vm, unformat_input_t * input,
 {
   int do_server = 0, do_client = 0, do_local = 0;
   application_t *app;
+  u32 app_index = ~0;
   int verbose = 0;
 
   session_cli_return_if_not_enabled ();
@@ -2330,25 +2368,44 @@ show_app_command_fn (vlib_main_t * vm, unformat_input_t * input,
        do_client = 1;
       else if (unformat (input, "local"))
        do_local = 1;
+      else if (unformat (input, "%u", &app_index))
+       ;
       else if (unformat (input, "verbose"))
        verbose = 1;
       else
-       break;
+       return clib_error_return (0, "unknown input `%U'",
+                                 format_unformat_error, input);
     }
 
   if (do_server)
-    application_format_all_listeners (vm, do_local, verbose);
+    {
+      application_format_all_listeners (vm, do_local, verbose);
+      return 0;
+    }
 
   if (do_client)
-    application_format_all_clients (vm, do_local, verbose);
+    {
+      application_format_all_clients (vm, do_local, verbose);
+      return 0;
+    }
+
+  if (app_index != ~0)
+    {
+      app = application_get_if_valid (app_index);
+      if (!app)
+       return clib_error_return (0, "No app with index %u", app_index);
+
+      vlib_cli_output (vm, "%U", format_application, app, /* verbose */ 1);
+      return 0;
+    }
 
   /* Print app related info */
   if (!do_server && !do_client)
     {
-      vlib_cli_output (vm, "%U", format_application, 0, verbose);
+      vlib_cli_output (vm, "%U", format_application, 0, 0);
       /* *INDENT-OFF* */
       pool_foreach (app, app_main.app_pool, ({
-       vlib_cli_output (vm, "%U", format_application, app, verbose);
+       vlib_cli_output (vm, "%U", format_application, app, 0);
       }));
       /* *INDENT-ON* */
     }