summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/vat/api_format.c79
-rw-r--r--src/vnet/interface.api43
-rw-r--r--src/vnet/interface_api.c93
-rw-r--r--src/vpp/api/custom_dump.c14
4 files changed, 228 insertions, 1 deletions
diff --git a/src/vat/api_format.c b/src/vat/api_format.c
index 88d4c0167e4..d334bcce870 100644
--- a/src/vat/api_format.c
+++ b/src/vat/api_format.c
@@ -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, \
diff --git a/src/vnet/interface.api b/src/vnet/interface.api
index a8d4d71d838..fdf34f0da34 100644
--- a/src/vnet/interface.api
+++ b/src/vnet/interface.api
@@ -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
{
diff --git a/src/vnet/interface_api.c b/src/vnet/interface_api.c
index 4ee3372ae28..644babef894 100644
--- a/src/vnet/interface_api.c
+++ b/src/vnet/interface_api.c
@@ -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)
{
diff --git a/src/vpp/api/custom_dump.c b/src/vpp/api/custom_dump.c
index 9e063be5c34..88b11635e11 100644
--- a/src/vpp/api/custom_dump.c
+++ b/src/vpp/api/custom_dump.c
@@ -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)
{