app/testpmd: setup attached ports on probe event
authorThomas Monjalon <thomas@monjalon.net>
Thu, 25 Oct 2018 15:11:17 +0000 (17:11 +0200)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 26 Oct 2018 20:14:06 +0000 (22:14 +0200)
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@monjalon.net>
Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>
app/test-pmd/cmdline.c
app/test-pmd/testpmd.c
app/test-pmd/testpmd.h
doc/guides/testpmd_app_ug/testpmd_funcs.rst

index e350c38..1050fde 100644 (file)
@@ -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,
index d4ab90b..9c0edca 100644 (file)
@@ -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");
index e0f86ee..3ff11e6 100644 (file)
@@ -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 */
 
index d5a1a73..e23079b 100644 (file)
@@ -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
 ~~~~~~~~~~~~~~~