[dpdk-dev] [PATCH v2 5/5] app/testpmd: setup attached ports on probe event

Thomas Monjalon thomas at monjalon.net
Thu Oct 25 17:11:17 CEST 2018


After probing is done, each new port must be setup.
The new ports are currently guessed by iterating on ports
matching the devargs string used for probing.

When probing a port, it is possible that one more port probing
get triggered (e.g. PF is automatically probed when probing
a VF representor). Such automatic probing will be caught only on event.

The iterator loop may be replaced by a call from the event callback.
In order to be able to test both modes, a command is added
to choose between iterator and event modes.

Signed-off-by: Thomas Monjalon <thomas at monjalon.net>
---
 app/test-pmd/cmdline.c                      | 57 +++++++++++++++++++++
 app/test-pmd/testpmd.c                      | 27 ++++++++--
 app/test-pmd/testpmd.h                      |  4 ++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 11 ++++
 4 files changed, 95 insertions(+), 4 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index e350c38a9..1050fde96 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -280,6 +280,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"set portlist (x[,y]*)\n"
 			"    Set the list of forwarding ports.\n\n"
 
+			"set port setup on (iterator|event)\n"
+			"    Select how attached port is retrieved for setup.\n\n"
+
 			"set tx loopback (port_id) (on|off)\n"
 			"    Enable or disable tx loopback.\n\n"
 
@@ -1249,6 +1252,59 @@ cmdline_parse_inst_t cmd_operate_specific_port = {
 	},
 };
 
+/* *** enable port setup (after attach) via iterator or event *** */
+struct cmd_set_port_setup_on_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t setup;
+	cmdline_fixed_string_t on;
+	cmdline_fixed_string_t mode;
+};
+
+static void cmd_set_port_setup_on_parsed(void *parsed_result,
+				__attribute__((unused)) struct cmdline *cl,
+				__attribute__((unused)) void *data)
+{
+	struct cmd_set_port_setup_on_result *res = parsed_result;
+
+	if (strcmp(res->mode, "event") == 0)
+		setup_on_probe_event = true;
+	else if (strcmp(res->mode, "iterator") == 0)
+		setup_on_probe_event = false;
+	else
+		printf("Unknown mode\n");
+}
+
+cmdline_parse_token_string_t cmd_set_port_setup_on_set =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_port_setup_on_result,
+			set, "set");
+cmdline_parse_token_string_t cmd_set_port_setup_on_port =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_port_setup_on_result,
+			port, "port");
+cmdline_parse_token_string_t cmd_set_port_setup_on_setup =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_port_setup_on_result,
+			setup, "setup");
+cmdline_parse_token_string_t cmd_set_port_setup_on_on =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_port_setup_on_result,
+			on, "on");
+cmdline_parse_token_string_t cmd_set_port_setup_on_mode =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_port_setup_on_result,
+			mode, "iterator#event");
+
+cmdline_parse_inst_t cmd_set_port_setup_on = {
+	.f = cmd_set_port_setup_on_parsed,
+	.data = NULL,
+	.help_str = "set port setup on iterator|event",
+	.tokens = {
+		(void *)&cmd_set_port_setup_on_set,
+		(void *)&cmd_set_port_setup_on_port,
+		(void *)&cmd_set_port_setup_on_setup,
+		(void *)&cmd_set_port_setup_on_on,
+		(void *)&cmd_set_port_setup_on_mode,
+		NULL,
+	},
+};
+
 /* *** attach a specified port *** */
 struct cmd_operate_attach_port_result {
 	cmdline_fixed_string_t port;
@@ -18529,6 +18585,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_set_port_setup_on,
 	(cmdline_parse_inst_t *)&cmd_config_speed_all,
 	(cmdline_parse_inst_t *)&cmd_config_speed_specific,
 	(cmdline_parse_inst_t *)&cmd_config_loopback_all,
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index d4ab90b45..9c0edcaed 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -345,6 +345,9 @@ uint8_t rmv_interrupt = 1; /* enabled by default */
 
 uint8_t hot_plug = 0; /**< hotplug disabled by default. */
 
+/* After attach, port setup is called on event or by iterator */
+bool setup_on_probe_event = true;
+
 /* Pretty printing of ethdev events */
 static const char * const eth_event_desc[] = {
 	[RTE_ETH_EVENT_UNKNOWN] = "unknown",
@@ -2285,7 +2288,7 @@ reset_port(portid_t pid)
 void
 attach_port(char *identifier)
 {
-	portid_t pi = 0;
+	portid_t pi;
 	struct rte_dev_iterator iterator;
 
 	printf("Attaching a new port...\n");
@@ -2300,7 +2303,19 @@ attach_port(char *identifier)
 		return;
 	}
 
+	/* first attach mode: event */
+	if (setup_on_probe_event) {
+		/* new ports are detected on RTE_ETH_EVENT_NEW event */
+		for (pi = 0; pi < RTE_MAX_ETHPORTS; pi++)
+			if (ports[pi].port_status == RTE_PORT_HANDLING &&
+					ports[pi].need_setup != 0)
+				setup_attached_port(pi);
+		return;
+	}
+
+	/* second attach mode: iterator */
 	RTE_ETH_FOREACH_MATCHING_DEV(pi, identifier, &iterator) {
+		/* setup ports matching the devargs used for probing */
 		if (port_is_forwarding(pi))
 			continue; /* port was already attached before */
 		setup_attached_port(pi);
@@ -2322,6 +2337,7 @@ setup_attached_port(portid_t pi)
 	ports_ids[nb_ports++] = pi;
 	fwd_ports_ids[nb_fwd_ports++] = pi;
 	nb_cfg_ports = nb_fwd_ports;
+	ports[pi].need_setup = 0;
 	ports[pi].port_status = RTE_PORT_STOPPED;
 
 	printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
@@ -2540,11 +2556,14 @@ eth_event_callback(portid_t port_id, enum rte_eth_event_type type, void *param,
 		fflush(stdout);
 	}
 
-	if (port_id_is_invalid(port_id, DISABLED_WARN))
-		return 0;
-
 	switch (type) {
+	case RTE_ETH_EVENT_NEW:
+		ports[port_id].need_setup = 1;
+		ports[port_id].port_status = RTE_PORT_HANDLING;
+		break;
 	case RTE_ETH_EVENT_INTR_RMV:
+		if (port_id_is_invalid(port_id, DISABLED_WARN))
+			break;
 		if (rte_eal_alarm_set(100000,
 				rmv_event_callback, (void *)(intptr_t)port_id))
 			fprintf(stderr, "Could not set up deferred device removal\n");
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index e0f86ee84..3ff11e644 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -5,6 +5,8 @@
 #ifndef _TESTPMD_H_
 #define _TESTPMD_H_
 
+#include <stdbool.h>
+
 #include <rte_pci.h>
 #include <rte_bus_pci.h>
 #include <rte_gro.h>
@@ -179,6 +181,7 @@ struct rte_port {
 	uint8_t                 tx_queue_stats_mapping_enabled;
 	uint8_t                 rx_queue_stats_mapping_enabled;
 	volatile uint16_t        port_status;    /**< port started or not */
+	uint8_t                 need_setup;     /**< port just attached */
 	uint8_t                 need_reconfig;  /**< need reconfiguring port or not */
 	uint8_t                 need_reconfig_queues; /**< need reconfiguring queues or not */
 	uint8_t                 rss_flag;   /**< enable rss or not */
@@ -329,6 +332,7 @@ extern uint8_t lsc_interrupt; /**< disabled by "--no-lsc-interrupt" parameter */
 extern uint8_t rmv_interrupt; /**< disabled by "--no-rmv-interrupt" parameter */
 extern uint32_t event_print_mask;
 /**< set by "--print-event xxxx" and "--mask-event xxxx parameters */
+extern bool setup_on_probe_event; /**< disabled by port setup-on iterator */
 extern uint8_t hot_plug; /**< enable by "--hot-plug" parameter */
 extern int do_mlockall; /**< set by "--mlockall" or "--no-mlockall" parameter */
 
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index d5a1a73a7..e23079b6d 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -609,6 +609,17 @@ For example, to change the port forwarding:
    RX P=1/Q=0 (socket 0) -> TX P=3/Q=0 (socket 0) peer=02:00:00:00:00:03
    RX P=3/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:02
 
+set port setup on
+~~~~~~~~~~~~~~~~~
+
+Select how to retrieve new ports created after "port attach" command::
+
+   testpmd> set port setup on (iterator|event)
+
+For each new port, a setup is done.
+It will find the probed ports via RTE_ETH_FOREACH_MATCHING_DEV loop
+in iterator mode, or via RTE_ETH_EVENT_NEW in event mode.
+
 set tx loopback
 ~~~~~~~~~~~~~~~
 
-- 
2.19.0



More information about the dev mailing list