From patchwork Wed Jul 17 12:30:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nithin Dabilpuram X-Patchwork-Id: 56617 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id A927B58C6; Wed, 17 Jul 2019 14:31:05 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by dpdk.org (Postfix) with ESMTP id 034F14D27 for ; Wed, 17 Jul 2019 14:31:03 +0200 (CEST) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id x6HCUhDS021409; Wed, 17 Jul 2019 05:31:03 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=pfpt0818; bh=7tgzNjp+SUnssD/WXvY6TA2RHzWPrHRmbAhfOQQAfME=; b=RP+fRc6ixDpt8OXDGvFd3ek12wlem4indHSp/XDqCIJXTsg7DO9Jav2wbfPBOuZU1X6x M6j3w7CUP7BHYld5Dhu2b+ebHAsjrXnnMOfyc3NUGGER0qVNXaoHKjdsAOOuQYDUD5Wo oZv9blO6zK23z7tdhFhOCkR6q2P/MeVSb82R7lcCb3wQI1feB4K+jGBQMCv96yx2g/eD yKHpeYYGzg8RpLsjN2E9UCOiJOiviSeWSpmgOETbG8BtRBkpSCXz4kLhlq1XBQhQk7kj o2SFbHylqsiLGDX/C4Y/VJN1Pj43CQzkSuaR9rq9QJWQZoVw/kzFGHxCX4ghHR4lJL3V ng== Received: from sc-exch02.marvell.com ([199.233.58.182]) by mx0a-0016f401.pphosted.com with ESMTP id 2ts07vg52e-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Wed, 17 Jul 2019 05:31:03 -0700 Received: from SC-EXCH03.marvell.com (10.93.176.83) by SC-EXCH02.marvell.com (10.93.176.82) with Microsoft SMTP Server (TLS) id 15.0.1367.3; Wed, 17 Jul 2019 05:31:01 -0700 Received: from maili.marvell.com (10.93.176.43) by SC-EXCH03.marvell.com (10.93.176.83) with Microsoft SMTP Server id 15.0.1367.3 via Frontend Transport; Wed, 17 Jul 2019 05:31:02 -0700 Received: from hyd1588t430.marvell.com (unknown [10.29.52.204]) by maili.marvell.com (Postfix) with ESMTP id C786B3F703F; Wed, 17 Jul 2019 05:30:58 -0700 (PDT) From: Nithin Dabilpuram To: , Wenzhuo Lu , Jingjing Wu , Bernard Iremonger , John McNamara , "Marko Kovacevic" CC: , , Nithin Dabilpuram Date: Wed, 17 Jul 2019 18:00:55 +0530 Message-ID: <20190717123055.106873-1-ndabilpuram@marvell.com> X-Mailer: git-send-email 2.8.4 In-Reply-To: <20190513112112.7069-1-ndabilpuram@marvell.com> References: <20190513112112.7069-1-ndabilpuram@marvell.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:5.22.84,1.0.8 definitions=2019-07-17_05:2019-07-17,2019-07-17 signatures=0 Subject: [dpdk-dev] [PATCH v3] app/testpmd: add device related cmds X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" With the latest published interface of rte_eal_hotplug_[add,remove](), and rte_eth_dev_close(), rte_eth_dev_close() would cleanup all the data structures of port's eth dev leaving the device common resource intact if RTE_ETH_DEV_CLOSE_REMOVE is set in dev flags. So a new command "detach device" (~hotplug remove) to work, with device identifier like "port attach" is added to be able to detach closed devices. Also to display currently probed devices, another command "show device info |all" is also added as a part of this change. Signed-off-by: Nithin Dabilpuram Reviewed-by: Ferruh Yigit --- v3: * Add help command text for new device related commands v2: * Add new commands "device detach" and "show device info all" instead of change in existing command "port detach" app/test-pmd/cmdline.c | 107 +++++++++++++++++++++++++++- app/test-pmd/config.c | 73 +++++++++++++++++++ app/test-pmd/testpmd.c | 45 ++++++++++++ app/test-pmd/testpmd.h | 2 + doc/guides/testpmd_app_ug/testpmd_funcs.rst | 64 +++++++++++++++++ 5 files changed, 289 insertions(+), 2 deletions(-) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 01dd45f..6b8aeed 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -101,6 +101,7 @@ static void cmd_help_brief_parsed(__attribute__((unused)) void *parsed_result, " help registers : Reading and setting port registers.\n" " help filters : Filters configuration help.\n" " help traffic_management : Traffic Management commmands.\n" + " help devices : Device related cmds.\n" " help all : All of the above sections.\n\n" ); @@ -236,6 +237,9 @@ static void cmd_help_long_parsed(void *parsed_result, "show port (port_id) tx_metadata\n" " Show Tx metadata value set" " for a specific port\n\n" + + "show device info (|all)" + " Show general information about devices probed.\n\n" ); } @@ -1240,6 +1244,17 @@ static void cmd_help_long_parsed(void *parsed_result, ); } + if (show_all || !strcmp(res->section, "devices")) { + cmdline_printf( + cl, + "\n" + "Device Operations:\n" + "--------------\n" + "device detach (identifier)\n" + " Detach device by identifier.\n\n" + ); + } + } cmdline_parse_token_string_t cmd_help_long_help = @@ -1248,13 +1263,13 @@ cmdline_parse_token_string_t cmd_help_long_help = cmdline_parse_token_string_t cmd_help_long_section = TOKEN_STRING_INITIALIZER(struct cmd_help_long_result, section, "all#control#display#config#" - "ports#registers#filters#traffic_management"); + "ports#registers#filters#traffic_management#devices"); cmdline_parse_inst_t cmd_help_long = { .f = cmd_help_long_parsed, .data = NULL, .help_str = "help all|control|display|config|ports|register|" - "filters|traffic_management: " + "filters|traffic_management|devices: " "Show help", .tokens = { (void *)&cmd_help_long_help, @@ -1493,6 +1508,47 @@ cmdline_parse_inst_t cmd_operate_detach_port = { }, }; +/* *** detach device by identifier *** */ +struct cmd_operate_detach_device_result { + cmdline_fixed_string_t device; + cmdline_fixed_string_t keyword; + cmdline_fixed_string_t identifier; +}; + +static void cmd_operate_detach_device_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_operate_detach_device_result *res = parsed_result; + + if (!strcmp(res->keyword, "detach")) + detach_device(res->identifier); + else + printf("Unknown parameter\n"); +} + +cmdline_parse_token_string_t cmd_operate_detach_device_device = + TOKEN_STRING_INITIALIZER(struct cmd_operate_detach_device_result, + device, "device"); +cmdline_parse_token_string_t cmd_operate_detach_device_keyword = + TOKEN_STRING_INITIALIZER(struct cmd_operate_detach_device_result, + keyword, "detach"); +cmdline_parse_token_string_t cmd_operate_detach_device_identifier = + TOKEN_STRING_INITIALIZER(struct cmd_operate_detach_device_result, + identifier, NULL); + +cmdline_parse_inst_t cmd_operate_detach_device = { + .f = cmd_operate_detach_device_parsed, + .data = NULL, + .help_str = "device detach :" + "(identifier: pci address or virtual dev name)", + .tokens = { + (void *)&cmd_operate_detach_device_device, + (void *)&cmd_operate_detach_device_keyword, + (void *)&cmd_operate_detach_device_identifier, + NULL, + }, +}; /* *** configure speed for all ports *** */ struct cmd_config_speed_all { cmdline_fixed_string_t port; @@ -7456,6 +7512,51 @@ cmdline_parse_inst_t cmd_showport = { }, }; +/* *** SHOW DEVICE INFO *** */ +struct cmd_showdevice_result { + cmdline_fixed_string_t show; + cmdline_fixed_string_t device; + cmdline_fixed_string_t what; + cmdline_fixed_string_t identifier; +}; + +static void cmd_showdevice_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_showdevice_result *res = parsed_result; + if (!strcmp(res->what, "info")) { + if (!strcmp(res->identifier, "all")) + device_infos_display(NULL); + else + device_infos_display(res->identifier); + } +} + +cmdline_parse_token_string_t cmd_showdevice_show = + TOKEN_STRING_INITIALIZER(struct cmd_showdevice_result, show, + "show"); +cmdline_parse_token_string_t cmd_showdevice_device = + TOKEN_STRING_INITIALIZER(struct cmd_showdevice_result, device, "device"); +cmdline_parse_token_string_t cmd_showdevice_what = + TOKEN_STRING_INITIALIZER(struct cmd_showdevice_result, what, + "info"); +cmdline_parse_token_string_t cmd_showdevice_identifier = + TOKEN_STRING_INITIALIZER(struct cmd_showdevice_result, + identifier, NULL); + +cmdline_parse_inst_t cmd_showdevice = { + .f = cmd_showdevice_parsed, + .data = NULL, + .help_str = "show device info |all", + .tokens = { + (void *)&cmd_showdevice_show, + (void *)&cmd_showdevice_device, + (void *)&cmd_showdevice_what, + (void *)&cmd_showdevice_identifier, + NULL, + }, +}; /* *** SHOW QUEUE INFO *** */ struct cmd_showqueue_result { cmdline_fixed_string_t show; @@ -18723,6 +18824,7 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_showport, (cmdline_parse_inst_t *)&cmd_showqueue, (cmdline_parse_inst_t *)&cmd_showportall, + (cmdline_parse_inst_t *)&cmd_showdevice, (cmdline_parse_inst_t *)&cmd_showcfg, (cmdline_parse_inst_t *)&cmd_showfwdall, (cmdline_parse_inst_t *)&cmd_start, @@ -18811,6 +18913,7 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_operate_specific_port, (cmdline_parse_inst_t *)&cmd_operate_attach_port, (cmdline_parse_inst_t *)&cmd_operate_detach_port, + (cmdline_parse_inst_t *)&cmd_operate_detach_device, (cmdline_parse_inst_t *)&cmd_set_port_setup_on, (cmdline_parse_inst_t *)&cmd_config_speed_all, (cmdline_parse_inst_t *)&cmd_config_speed_specific, diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 1d80470..537e73f 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -386,6 +386,79 @@ tx_queue_infos_display(portid_t port_id, uint16_t queue_id) printf("\n"); } +static int bus_match_all(const struct rte_bus *bus, const void *data) +{ + RTE_SET_USED(bus); + RTE_SET_USED(data); + return 0; +} + +void +device_infos_display(const char *identifier) +{ + static const char *info_border = "*********************"; + struct rte_bus *start = NULL, *next; + struct rte_dev_iterator dev_iter; + char name[RTE_ETH_NAME_MAX_LEN]; + struct rte_ether_addr mac_addr; + struct rte_device *dev; + struct rte_devargs da; + portid_t port_id; + char devstr[128]; + + memset(&da, 0, sizeof(da)); + if (!identifier) + goto skip_parse; + + if (rte_devargs_parsef(&da, "%s", identifier)) { + printf("cannot parse identifier\n"); + if (da.args) + free(da.args); + return; + } + +skip_parse: + while ((next = rte_bus_find(start, bus_match_all, NULL)) != NULL) { + + start = next; + if (identifier && da.bus != next) + continue; + + /* Skip buses that don't have iterate method */ + if (!next->dev_iterate) + continue; + + snprintf(devstr, sizeof(devstr), "bus=%s", next->name); + RTE_DEV_FOREACH(dev, devstr, &dev_iter) { + + if (!dev->driver) + continue; + /* Check for matching device if identifier is present */ + if (identifier && + strncmp(da.name, dev->name, strlen(dev->name))) + continue; + printf("\n%s Infos for device %s %s\n", + info_border, dev->name, info_border); + printf("Bus name: %s", dev->bus->name); + printf("\nDriver name: %s", dev->driver->name); + printf("\nDevargs: %s", + dev->devargs ? dev->devargs->args : ""); + printf("\nConnect to socket: %d", dev->numa_node); + printf("\n"); + + /* List ports with matching device name */ + RTE_ETH_FOREACH_DEV_OF(port_id, dev) { + rte_eth_macaddr_get(port_id, &mac_addr); + printf("\n\tPort id: %-2d", port_id); + print_ethaddr("\n\tMAC address: ", &mac_addr); + rte_eth_dev_get_name_by_port(port_id, name); + printf("\n\tDevice name: %s", name); + printf("\n"); + } + } + }; +} + void port_infos_display(portid_t port_id) { diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index 3ed3523..a3b1542 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -2476,6 +2476,51 @@ detach_port_device(portid_t port_id) } void +detach_device(char *identifier) +{ + struct rte_dev_iterator iterator; + struct rte_devargs da; + portid_t port_id; + + printf("Removing a device...\n"); + + memset(&da, 0, sizeof(da)); + if (rte_devargs_parsef(&da, "%s", identifier)) { + printf("cannot parse identifier\n"); + if (da.args) + free(da.args); + return; + } + + RTE_ETH_FOREACH_MATCHING_DEV(port_id, identifier, &iterator) { + if (ports[port_id].port_status != RTE_PORT_CLOSED) { + if (ports[port_id].port_status != RTE_PORT_STOPPED) { + printf("Port %u not stopped\n", port_id); + return; + } + + /* sibling ports are forced to be closed */ + if (ports[port_id].flow_list) + port_flow_flush(port_id); + ports[port_id].port_status = RTE_PORT_CLOSED; + printf("Port %u is now closed\n", port_id); + } + } + + if (rte_eal_hotplug_remove(da.bus->name, da.name) != 0) { + TESTPMD_LOG(ERR, "Failed to detach device %s(%s)\n", + da.name, da.bus->name); + return; + } + + remove_invalid_ports(); + + printf("Device %s is detached\n", identifier); + printf("Now total ports is %d\n", nb_ports); + printf("Done\n"); +} + +void pmd_test_exit(void) { portid_t pt_id; diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index e3a6f7c..93bed6d 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -689,6 +689,7 @@ void nic_stats_clear(portid_t port_id); void nic_xstats_display(portid_t port_id); void nic_xstats_clear(portid_t port_id); void nic_stats_mapping_display(portid_t port_id); +void device_infos_display(const char *identifier); void port_infos_display(portid_t port_id); void port_summary_display(portid_t port_id); void port_summary_header_display(void); @@ -788,6 +789,7 @@ void stop_port(portid_t pid); void close_port(portid_t pid); void reset_port(portid_t pid); void attach_port(char *identifier); +void detach_device(char *identifier); void detach_port_device(portid_t port_id); int all_ports_stopped(void); int port_is_stopped(portid_t port_id); diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index ebab2f1..04b9a31 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -467,6 +467,29 @@ Show Tx metadata value set for a specific port:: testpmd> show port (port_id) tx_metadata +show device info +~~~~~~~~~~~~~~~~ + +Show general information about devices probed:: + + testpmd> show device info (|all) + +For example: + +.. code-block:: console + + testpmd> show device info net_pcap0 + + ********************* Infos for device net_pcap0 ********************* + Bus name: vdev + Driver name: net_pcap + Devargs: iface=enP2p6s0,phy_mac=1 + Connect to socket: -1 + + Port id: 2 + MAC address: 1E:37:93:28:04:B8 + Device name: net_pcap0 + dump physmem ~~~~~~~~~~~~ @@ -2289,6 +2312,47 @@ hash of input [IP] packets received on port:: ipv6-udp-ex ) +Device Functions +---------------- + +The following sections show functions for device operations. + +device detach +~~~~~~~~~~~~~ + +Detach a device specified by pci address or virtual device args:: + + testpmd> device detach (identifier) + +Before detaching a device associated with ports, the ports should be stopped and closed. + +For example, to detach a pci device whose address is 0002:03:00.0. + +.. code-block:: console + + testpmd> device detach 0002:03:00.0 + Removing a device... + Port 1 is now closed + EAL: Releasing pci mapped resource for 0002:03:00.0 + EAL: Calling pci_unmap_resource for 0002:03:00.0 at 0x218a050000 + EAL: Calling pci_unmap_resource for 0002:03:00.0 at 0x218c050000 + Device 0002:03:00.0 is detached + Now total ports is 1 + +For example, to detach a port created by pcap PMD. + +.. code-block:: console + + testpmd> device detach net_pcap0 + Removing a device... + Port 0 is now closed + Device net_pcap0 is detached + Now total ports is 0 + Done + +In this case, identifier is ``net_pcap0``. +This identifier format is the same as ``--vdev`` format of DPDK applications. + Link Bonding Functions ----------------------