aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet')
-rw-r--r--src/vnet/interface.api43
-rw-r--r--src/vnet/interface_api.c93
2 files changed, 135 insertions, 1 deletions
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)
{