[dpdk-dev] [PATCH v2 5/5] app/testpmd: add command to test NIC restoration

Wei Dai wei.dai at intel.com
Tue Jun 27 16:07:18 CEST 2017


When a NIC is reset, a message will show it.
And then user can run the command "reset_port port_id"
to reset the port and to keep same port id without any
without any configuration.
This patch adds a testpmd command "reconfig_port port_id"
to test whether the port can be reconfigured to have
success Rx and Tx function.
The new command will configure the port with the simplest
setting which includes only 1 Rx queue, only 1 Tx queue,
Rx mode = None and Tx mode = None.
It check if the port can receive and forward some packets.
For example 100 packets in this new command.
Before testing with "reset_port port_id" and then
"reconfig_port port_id", current forwarding should be stopped
first to avoid crash.

Signed-off-by: Wei Dai <wei.dai at intel.com>
---
 app/test-pmd/cmdline.c | 31 ++++++++++++++++
 app/test-pmd/config.c  | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.h |  1 +
 3 files changed, 130 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 90f6bde..1038cee 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -2618,6 +2618,36 @@ cmdline_parse_inst_t cmd_reset_port = {
 	},
 };
 
+/* *** reconfig a port with simplest settings only for test *** */
+struct cmd_reconfig_port_result {
+	cmdline_fixed_string_t command;
+	uint8_t port_id;
+};
+
+static void cmd_reconfig_port_parsed(__attribute__((unused)) void *parsed_result,
+			    __attribute__((unused)) struct cmdline *cl,
+			    __attribute__((unused)) void *data)
+{
+	struct cmd_reconfig_port_result *res = parsed_result;
+	reconfig_port(res->port_id);
+}
+
+cmdline_parse_token_string_t cmd_reconfig_port_cmd =
+	TOKEN_STRING_INITIALIZER(struct cmd_reconfig_port_result, command, "reconfig_port");
+cmdline_parse_token_num_t cmd_reconfig_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_reconfig_port_result, port_id, UINT8);
+
+cmdline_parse_inst_t cmd_reconfig_port = {
+	.f = cmd_reconfig_port_parsed,
+	.data = NULL,
+	.help_str = "reconfig_port <port_id>",
+	.tokens = {
+		(void *)&cmd_reconfig_port_cmd,
+		(void *)&cmd_reconfig_port_id,
+		NULL,
+	},
+};
+
 /* *** SET CORELIST and PORTLIST CONFIGURATION *** */
 
 unsigned int
@@ -13782,6 +13812,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_read_rxd_txd,
 	(cmdline_parse_inst_t *)&cmd_stop,
 	(cmdline_parse_inst_t *)&cmd_reset_port,
+	(cmdline_parse_inst_t *)&cmd_reconfig_port,
 	(cmdline_parse_inst_t *)&cmd_mac_addr,
 	(cmdline_parse_inst_t *)&cmd_set_qmap,
 	(cmdline_parse_inst_t *)&cmd_operate_port,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index da3b525..1fd6a54 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -3331,3 +3331,101 @@ reset_port(portid_t port_id)
 		return;
 	printf("Reset port %d failed. diag=%d\n", port_id, diag);	
 }
+
+static void
+test_simplest_rxtx(portid_t port)
+{
+#define BURST_SIZE 32
+#define NUM_PACKETS 100
+
+	struct rte_mbuf *bufs[BURST_SIZE];
+	uint16_t nb_rx, nb_tx, total;
+
+	printf("Begin to forward at least %d packets to test reconfiguration\n", NUM_PACKETS);
+	total = 0;
+	while (1) {
+		nb_rx = rte_eth_rx_burst(port, 0, bufs, BURST_SIZE);
+		if (nb_rx == 0)
+			continue;
+		nb_tx = rte_eth_tx_burst(port, 0, bufs, nb_rx);
+		total += nb_tx;
+		/* Free any unsent packets. */
+		if (unlikely(nb_tx < nb_rx)) {
+			uint16_t buf;
+			for (buf = nb_tx; buf < nb_rx; buf++)
+				rte_pktmbuf_free(bufs[buf]);
+		}
+		if (total >= NUM_PACKETS)
+			break;
+	}
+	printf("Finish forwarding %u packets to test reconfiguration\n", total);
+	return;
+}
+
+int
+reconfig_port(portid_t port)
+{
+#define RX_RING_SIZE 128
+#define TX_RING_SIZE 512
+
+#define NUM_MBUFS 8191
+#define MBUF_CACHE_SIZE 250
+
+	struct rte_mempool *mbuf_pool;
+	struct rte_eth_conf dev_conf = {
+		.rxmode = { .max_rx_pkt_len = ETHER_MAX_LEN }
+	};
+	const uint16_t rx_rings = 1, tx_rings = 1;
+	int retval;
+	uint16_t q;
+
+	if (port_id_is_invalid(port, ENABLED_WARN))
+		return -1;
+
+	/* Creates a new mempool in memory to hold the mbufs. */
+	mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS,
+		MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_eth_dev_socket_id(port));
+
+	/* Configure the Ethernet device. */
+	retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &dev_conf);
+	if (retval != 0)
+		return retval;
+
+	/* Allocate and set up 1 RX queue per Ethernet port. */
+	for (q = 0; q < rx_rings; q++) {
+		retval = rte_eth_rx_queue_setup(port, q, RX_RING_SIZE,
+				rte_eth_dev_socket_id(port), NULL, mbuf_pool);
+		if (retval < 0)
+			return retval;
+	}
+
+	/* Allocate and set up 1 TX queue per Ethernet port. */
+	for (q = 0; q < tx_rings; q++) {
+		retval = rte_eth_tx_queue_setup(port, q, TX_RING_SIZE,
+				rte_eth_dev_socket_id(port), NULL);
+		if (retval < 0)
+			return retval;
+	}
+
+	/* Start the Ethernet port. */
+	retval = rte_eth_dev_start(port);
+	if (retval < 0)
+		return retval;
+
+	/* Display the port MAC address. */
+	struct ether_addr addr;
+	rte_eth_macaddr_get(port, &addr);
+	printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8
+			   " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n",
+			(unsigned)port,
+			addr.addr_bytes[0], addr.addr_bytes[1],
+			addr.addr_bytes[2], addr.addr_bytes[3],
+			addr.addr_bytes[4], addr.addr_bytes[5]);
+
+	/* Enable RX in promiscuous mode for the Ethernet device. */
+	rte_eth_promiscuous_enable(port);
+
+	test_simplest_rxtx(port);
+
+	return 0;
+}
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 956eec5..c4c2e59 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -599,6 +599,7 @@ void close_port(portid_t pid);
 void attach_port(char *identifier);
 void detach_port(uint8_t port_id);
 void reset_port(portid_t port_id);
+int reconfig_port(portid_t port_id);
 int all_ports_stopped(void);
 int port_is_started(portid_t port_id);
 void pmd_test_exit(void);
-- 
2.7.4



More information about the dev mailing list