itf: dump interface rx-placement 51/14751/5
authorMohsin Kazmi <sykazmi@cisco.com>
Mon, 10 Sep 2018 16:11:00 +0000 (18:11 +0200)
committerOle Trøan <otroan@employees.org>
Wed, 26 Sep 2018 05:19:48 +0000 (05:19 +0000)
Change-Id: I7dd48c8a2c77f82a2c1aa8311b062f5f0bc4e3fd
Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
src/vat/api_format.c
src/vnet/interface.api
src/vnet/interface_api.c
src/vpp/api/custom_dump.c

index 88d4c01..d334bcc 100644 (file)
@@ -5549,6 +5549,7 @@ _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
   sw_interface_add_del_address_reply)                                   \
 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)    \
+_(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details)        \
 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)          \
 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)          \
@@ -6620,6 +6621,82 @@ api_sw_interface_set_rx_placement (vat_main_t * vam)
   return ret;
 }
 
+static void vl_api_sw_interface_rx_placement_details_t_handler
+  (vl_api_sw_interface_rx_placement_details_t * mp)
+{
+  vat_main_t *vam = &vat_main;
+  u32 worker_id = ntohl (mp->worker_id);
+
+  print (vam->ofp,
+        "\n%-11d %-11s %-6d %-5d %-9s",
+        ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
+        worker_id, ntohl (mp->queue_id),
+        (mp->mode ==
+         1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
+}
+
+static void vl_api_sw_interface_rx_placement_details_t_handler_json
+  (vl_api_sw_interface_rx_placement_details_t * mp)
+{
+  vat_main_t *vam = &vat_main;
+  vat_json_node_t *node = NULL;
+
+  if (VAT_JSON_ARRAY != vam->json_tree.type)
+    {
+      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
+      vat_json_init_array (&vam->json_tree);
+    }
+  node = vat_json_array_add (&vam->json_tree);
+
+  vat_json_init_object (node);
+  vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
+  vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
+  vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
+  vat_json_object_add_uint (node, "mode", mp->mode);
+}
+
+static int
+api_sw_interface_rx_placement_dump (vat_main_t * vam)
+{
+  unformat_input_t *i = vam->input;
+  vl_api_sw_interface_rx_placement_dump_t *mp;
+  vl_api_control_ping_t *mp_ping;
+  int ret;
+  u32 sw_if_index;
+  u8 sw_if_index_set = 0;
+
+  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
+       sw_if_index_set++;
+      else if (unformat (i, "sw_if_index %d", &sw_if_index))
+       sw_if_index_set++;
+      else
+       break;
+    }
+
+  print (vam->ofp,
+        "\n%-11s %-11s %-6s %-5s %-4s",
+        "sw_if_index", "main/worker", "thread", "queue", "mode");
+
+  /* Dump Interface rx placement */
+  M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
+
+  if (sw_if_index_set)
+    mp->sw_if_index = htonl (sw_if_index);
+  else
+    mp->sw_if_index = ~0;
+
+  S (mp);
+
+  /* Use a control ping for synchronization */
+  MPING (CONTROL_PING, mp_ping);
+  S (mp_ping);
+
+  W (ret);
+  return ret;
+}
+
 static int
 api_sw_interface_clear_stats (vat_main_t * vam)
 {
@@ -23469,6 +23546,8 @@ _(sw_interface_set_rx_mode,                                             \
   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
 _(sw_interface_set_rx_placement,                                        \
   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
+_(sw_interface_rx_placement_dump,                                       \
+  "[<intfc> | sw_if_index <id>]")                                         \
 _(sw_interface_set_table,                                               \
   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
 _(sw_interface_set_mpls_enable,                                         \
index a8d4d71..fdf34f0 100644 (file)
@@ -1,4 +1,4 @@
-option version = "2.0.0";
+option version = "2.1.0";
 
 service {
   rpc want_interface_events returns want_interface_events_reply
@@ -433,6 +433,9 @@ autoreply define sw_interface_set_rx_mode
 };
 
 /** \brief Set an interface's rx-placement
+    Rx-Queue placement on specific thread is operational for only hardware
+    interface. It will not set queue - thread placement for sub-interfaces,
+    p2p and pipe interfaces.
     @param client_index - opaque cookie to identify the sender
     @param context - sender context, to match reply w/ request
     @param sw_if_index - the interface whose rx-placement will be set
@@ -450,6 +453,44 @@ autoreply define sw_interface_set_rx_placement
     u8 is_main;
 };
 
+/** \brief dump the rx queue placement of interface(s)
+    @param sw_if_index - optional interface index for which queue placement to
+      be requested. sw_if_index = ~0 will dump placement information for all
+      interfaces. It will not dump information related to sub-interfaces, p2p
+      and pipe interfaces.
+*/
+define sw_interface_rx_placement_dump
+{
+  u32 client_index;
+  u32 context;
+  u32 sw_if_index;
+};
+
+/** \brief show the interface's queue - thread placement
+    This api is used to display the interface and queue worker
+    thread placement. One message per rx-queue per interface will
+    be sent to client.
+    Each message will contain information about rx-queue id of an
+    interface, interface index, thread on which this rx-queue is
+    placed and mode of rx-queue.
+    @param client_index - opaque cookie to identify the sender
+    @param context - sender context, to match reply w/ request
+    @param sw_if_index - the interface whose rx-placement will be dumped
+    @param queue_id - the queue id
+    @param worker_id - the worker id on which queue_id is placed,
+                       worker_id = 0 means main thread.
+    @param mode - polling=1, interrupt=2, adaptive=3
+*/
+define sw_interface_rx_placement_details
+{
+  u32 client_index;
+  u32 context;
+  u32 sw_if_index;
+  u32 queue_id;
+  u32 worker_id;
+  u8 mode;
+};
+
 /* Gross kludge, DGMS */
 autoreply define interface_name_renumber
 {
index 4ee3372..644babe 100644 (file)
@@ -56,6 +56,7 @@ _(WANT_INTERFACE_EVENTS, want_interface_events)                 \
 _(SW_INTERFACE_DUMP, sw_interface_dump)                         \
 _(SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address)   \
 _(SW_INTERFACE_SET_RX_MODE, sw_interface_set_rx_mode)           \
+_(SW_INTERFACE_RX_PLACEMENT_DUMP, sw_interface_rx_placement_dump) \
 _(SW_INTERFACE_SET_RX_PLACEMENT, sw_interface_set_rx_placement)        \
 _(SW_INTERFACE_SET_TABLE, sw_interface_set_table)               \
 _(SW_INTERFACE_GET_TABLE, sw_interface_get_table)               \
@@ -958,6 +959,98 @@ out:
   REPLY_MACRO (VL_API_SW_INTERFACE_SET_RX_MODE_REPLY);
 }
 
+static void
+send_interface_rx_placement_details (vpe_api_main_t * am,
+                                    vl_api_registration_t * rp,
+                                    u32 sw_if_index, u32 worker_id,
+                                    u32 queue_id, u8 mode, u32 context)
+{
+  vl_api_sw_interface_rx_placement_details_t *mp;
+  mp = vl_msg_api_alloc (sizeof (*mp));
+  memset (mp, 0, sizeof (*mp));
+
+  mp->_vl_msg_id = htons (VL_API_SW_INTERFACE_RX_PLACEMENT_DETAILS);
+  mp->sw_if_index = htonl (sw_if_index);
+  mp->queue_id = htonl (queue_id);
+  mp->worker_id = htonl (worker_id);
+  mp->mode = mode;
+  mp->context = context;
+
+  vl_api_send_msg (rp, (u8 *) mp);
+}
+
+static void vl_api_sw_interface_rx_placement_dump_t_handler
+  (vl_api_sw_interface_rx_placement_dump_t * mp)
+{
+  vnet_main_t *vnm = vnet_get_main ();
+  vpe_api_main_t *am = &vpe_api_main;
+  u32 sw_if_index = ntohl (mp->sw_if_index);
+  vl_api_registration_t *reg;
+
+  reg = vl_api_client_index_to_registration (mp->client_index);
+  if (!reg)
+    return;
+
+  if (sw_if_index == ~0)
+    {
+      vnet_device_input_runtime_t *rt;
+      vnet_device_and_queue_t *dq;
+      vlib_node_t *pn = vlib_get_node_by_name (am->vlib_main,
+                                              (u8 *) "device-input");
+      uword si;
+      int index = 0;
+
+      /* *INDENT-OFF* */
+      foreach_vlib_main (({
+        clib_bitmap_foreach (si, pn->sibling_bitmap,
+        ({
+          rt = vlib_node_get_runtime_data (this_vlib_main, si);
+          vec_foreach (dq, rt->devices_and_queues)
+            {
+              vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm,
+                                                             dq->hw_if_index);
+              send_interface_rx_placement_details (am, reg, hw->sw_if_index, index,
+                                          dq->queue_id, dq->mode, mp->context);
+            }
+        }));
+        index++;
+      }));
+      /* *INDENT-ON* */
+    }
+  else
+    {
+      int i;
+      vnet_sw_interface_t *si;
+
+      if (!vnet_sw_if_index_is_api_valid (sw_if_index))
+       {
+         clib_warning ("sw_if_index %u does not exist", sw_if_index);
+         goto bad_sw_if_index;
+       }
+
+      si = vnet_get_sw_interface (vnm, sw_if_index);
+      if (si->type != VNET_SW_INTERFACE_TYPE_HARDWARE)
+       {
+         clib_warning ("interface type is not HARDWARE! P2P, PIPE and SUB"
+                       " interfaces are not supported");
+         goto bad_sw_if_index;
+       }
+
+      vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, si->hw_if_index);
+
+      for (i = 0; i < vec_len (hw->dq_runtime_index_by_queue); i++)
+       {
+         send_interface_rx_placement_details (am, reg, hw->sw_if_index,
+                                              hw->input_node_thread_index_by_queue
+                                              [i], i,
+                                              hw->rx_mode_by_queue[i],
+                                              mp->context);
+       }
+    }
+
+  BAD_SW_IF_INDEX_LABEL;
+}
+
 static void vl_api_sw_interface_set_rx_placement_t_handler
   (vl_api_sw_interface_set_rx_placement_t * mp)
 {
index 9e063be..88b1163 100644 (file)
@@ -134,6 +134,20 @@ static void *vl_api_sw_interface_set_rx_placement_t_print
   FINISH;
 }
 
+static void *vl_api_sw_interface_rx_placement_dump_t_print
+  (vl_api_sw_interface_rx_placement_dump_t * mp, void *handle)
+{
+  u8 *s;
+  u32 sw_if_index = ntohl (mp->sw_if_index);
+
+  s = format (0, "SCRIPT: sw_interface_rx_placement_dump ");
+
+  if (sw_if_index != ~0)
+    s = format (s, "sw_if_index %d ", sw_if_index);
+
+  FINISH;
+}
+
 static void *vl_api_sw_interface_event_t_print
   (vl_api_sw_interface_event_t * mp, void *handle)
 {