From: Nithin Dabilpuram <ndabilpuram@marvell.com>
To: <ferruh.yigit@linux.intel.com>, Wenzhuo Lu <wenzhuo.lu@intel.com>,
Jingjing Wu <jingjing.wu@intel.com>,
Bernard Iremonger <bernard.iremonger@intel.com>,
John McNamara <john.mcnamara@intel.com>,
"Marko Kovacevic" <marko.kovacevic@intel.com>
Cc: <thomas@monjalon.net>, <dev@dpdk.org>,
Nithin Dabilpuram <ndabilpuram@marvell.com>
Subject: [dpdk-dev] [PATCH v3] app/testpmd: add device related cmds
Date: Wed, 17 Jul 2019 18:00:55 +0530 [thread overview]
Message-ID: <20190717123055.106873-1-ndabilpuram@marvell.com> (raw)
In-Reply-To: <20190513112112.7069-1-ndabilpuram@marvell.com>
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 <identifier>|all" is also added as a
part of this change.
Signed-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
---
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 (<identifier>|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>:"
+ "(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 <identifier>|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 (<identifier>|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 <string of hex digits \
(variable length, NIC dependent)>)
+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
----------------------
--
2.8.4
next prev parent reply other threads:[~2019-07-17 12:31 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-13 11:21 [dpdk-dev] [PATCH] app/testpmd: change port detach interface Nithin Dabilpuram
2019-05-13 11:21 ` Nithin Dabilpuram
2019-05-14 15:39 ` Thomas Monjalon
2019-05-14 15:39 ` Thomas Monjalon
2019-05-15 6:52 ` Nithin Dabilpuram
2019-05-15 6:52 ` Nithin Dabilpuram
2019-05-15 7:27 ` Thomas Monjalon
2019-05-15 7:27 ` Thomas Monjalon
2019-05-17 8:55 ` Nithin Dabilpuram
2019-05-17 8:59 ` Thomas Monjalon
2019-05-20 12:50 ` Nithin Dabilpuram
2019-05-29 8:16 ` Nithin Dabilpuram
2019-06-25 4:24 ` Nithin Dabilpuram
2019-07-02 15:58 ` Yigit, Ferruh
2019-07-03 5:05 ` Nithin Dabilpuram
2019-07-10 13:07 ` [dpdk-dev] [PATCH v2] app/testpmd: add device related cmds Nithin Dabilpuram
2019-07-16 18:30 ` Ferruh Yigit
2019-07-17 8:08 ` [dpdk-dev] [EXT] " Nithin Kumar Dabilpuram
2019-07-17 12:30 ` Nithin Dabilpuram [this message]
2019-07-17 16:51 ` [dpdk-dev] [PATCH v3] " Ferruh Yigit
2019-07-18 5:27 ` [dpdk-dev] [EXT] " Nithin Kumar Dabilpuram
2019-07-19 19:00 ` Ferruh Yigit
2019-07-22 6:01 ` Hemant Agrawal
2019-07-22 6:15 ` Nithin Kumar Dabilpuram
2019-07-22 16:04 ` Ferruh Yigit
2019-07-17 16:54 ` [dpdk-dev] " Ferruh Yigit
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190717123055.106873-1-ndabilpuram@marvell.com \
--to=ndabilpuram@marvell.com \
--cc=bernard.iremonger@intel.com \
--cc=dev@dpdk.org \
--cc=ferruh.yigit@linux.intel.com \
--cc=jingjing.wu@intel.com \
--cc=john.mcnamara@intel.com \
--cc=marko.kovacevic@intel.com \
--cc=thomas@monjalon.net \
--cc=wenzhuo.lu@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).