From f0b42f48b8a1dc582a230b195c855789189ff233 Mon Sep 17 00:00:00 2001 From: Mohsin Kazmi Date: Mon, 10 Sep 2018 18:11:00 +0200 Subject: [PATCH] itf: dump interface rx-placement Change-Id: I7dd48c8a2c77f82a2c1aa8311b062f5f0bc4e3fd Signed-off-by: Mohsin Kazmi --- src/vat/api_format.c | 79 ++++++++++++++++++++++++++++++++++++++++ src/vnet/interface.api | 43 +++++++++++++++++++++- src/vnet/interface_api.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++ src/vpp/api/custom_dump.c | 14 +++++++ 4 files changed, 228 insertions(+), 1 deletion(-) 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, \ " | sw_if_index [queue ] ") \ _(sw_interface_set_rx_placement, \ " | sw_if_index [queue ] [worker | main]") \ +_(sw_interface_rx_placement_dump, \ + "[ | sw_if_index ]") \ _(sw_interface_set_table, \ " | sw_if_index vrf [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) { -- 2.16.6