Introduce a testpmd API so that drivers can register specific commands. A driver can list some files to compile with testpmd, by setting them in the testpmd_sources (driver local) meson variable. drivers/meson.build then takes care of appending this to a global meson variable, and adding the driver to testpmd dependency.
Note: testpmd.h is fixed to that it is self sufficient when being included. Signed-off-by: David Marchand <david.march...@redhat.com> --- app/test-pmd/cmdline.c | 83 ++++++++++++++++++++++++++++++++++++---- app/test-pmd/meson.build | 5 +++ app/test-pmd/testpmd.c | 4 ++ app/test-pmd/testpmd.h | 16 ++++++++ drivers/meson.build | 5 +++ meson.build | 2 + 6 files changed, 108 insertions(+), 7 deletions(-) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 6ffea8e21a..ed62027834 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -69,6 +69,9 @@ #include "bpf_cmd.h" static struct cmdline *testpmd_cl; +static cmdline_parse_ctx_t *main_ctx; +static TAILQ_HEAD(, testpmd_cmdline_parser) cmdline_parsers = + TAILQ_HEAD_INITIALIZER(cmdline_parsers); static void cmd_reconfig_device_queue(portid_t id, uint8_t dev, uint8_t queue); @@ -94,6 +97,7 @@ static void cmd_help_brief_parsed(__rte_unused void *parsed_result, " help filters : Filters configuration help.\n" " help traffic_management : Traffic Management commands.\n" " help devices : Device related cmds.\n" + " help drivers : Driver specific cmds.\n" " help all : All of the above sections.\n\n" ); @@ -1177,6 +1181,21 @@ static void cmd_help_long_parsed(void *parsed_result, ); } + if (show_all || !strcmp(res->section, "drivers")) { + struct testpmd_cmdline_parser *parser; + unsigned int i; + + cmdline_printf( + cl, + "\n" + "Driver specific:\n" + "----------------\n" + ); + TAILQ_FOREACH(parser, &cmdline_parsers, next) { + for (i = 0; parser->help[i] != NULL; i++) + cmdline_printf(cl, "%s\n", parser->help[i]); + } + } } cmdline_parse_token_string_t cmd_help_long_help = @@ -1184,14 +1203,14 @@ 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#devices"); + "all#control#display#config#ports#registers#" + "filters#traffic_management#devices#drivers"); 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|devices: " + "filters|traffic_management|devices|drivers: " "Show help", .tokens = { (void *)&cmd_help_long_help, @@ -17810,7 +17829,7 @@ cmdline_parse_inst_t cmd_show_port_flow_transfer_proxy = { /* ******************************************************************************** */ /* list of instructions */ -cmdline_parse_ctx_t main_ctx[] = { +static cmdline_parse_ctx_t builtin_ctx[] = { (cmdline_parse_inst_t *)&cmd_help_brief, (cmdline_parse_inst_t *)&cmd_help_long, (cmdline_parse_inst_t *)&cmd_quit, @@ -18096,6 +18115,59 @@ cmdline_parse_ctx_t main_ctx[] = { NULL, }; +void +testpmd_add_commands(struct testpmd_cmdline_parser *parser) +{ + TAILQ_INSERT_TAIL(&cmdline_parsers, parser, next); +} + +int +init_cmdline(void) +{ + struct testpmd_cmdline_parser *parser; + cmdline_parse_ctx_t *ctx; + unsigned int count = 0; + unsigned int i; + + /* initialize non-constant commands */ + cmd_set_fwd_mode_init(); + cmd_set_fwd_retry_mode_init(); + + main_ctx = NULL; + for (i = 0; builtin_ctx[i] != NULL; i++) { + ctx = realloc(main_ctx, (count + i + 1) * sizeof(*ctx)); + if (ctx == NULL) + goto err; + main_ctx = ctx; + main_ctx[count + i] = builtin_ctx[i]; + } + count += i; + + TAILQ_FOREACH(parser, &cmdline_parsers, next) { + for (i = 0; parser->ctx[i] != NULL; i++) { + ctx = realloc(main_ctx, (count + i + 1) * sizeof(*ctx)); + if (ctx == NULL) + goto err; + ctx[count + i] = parser->ctx[i]; + } + count += i; + } + + /* cmdline expects a NULL terminated array */ + ctx = realloc(main_ctx, (count + 1) * sizeof(*ctx)); + if (ctx == NULL) + goto err; + ctx[count] = NULL; + count += 1; + + main_ctx = ctx; + + return 0; +err: + free(main_ctx); + return -1; +} + /* read cmdline commands from file */ void cmdline_read_from_file(const char *filename) @@ -18123,9 +18195,6 @@ void prompt(void) { int ret; - /* initialize non-constant commands */ - cmd_set_fwd_mode_init(); - cmd_set_fwd_retry_mode_init(); testpmd_cl = cmdline_stdin_new(main_ctx, "testpmd> "); if (testpmd_cl == NULL) diff --git a/app/test-pmd/meson.build b/app/test-pmd/meson.build index 43130c8856..46a7511e9a 100644 --- a/app/test-pmd/meson.build +++ b/app/test-pmd/meson.build @@ -73,3 +73,8 @@ endif if dpdk_conf.has('RTE_NET_DPAA') deps += ['bus_dpaa', 'mempool_dpaa', 'net_dpaa'] endif + +# Driver specific sources include some testpmd headers. +includes = include_directories('.') +sources += testpmd_drivers_sources +deps += testpmd_drivers_deps diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index fe2ce19f99..5bda46e32b 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -4263,6 +4263,10 @@ main(int argc, char** argv) } #endif #ifdef RTE_LIB_CMDLINE + if (init_cmdline() != 0) + rte_exit(EXIT_FAILURE, + "Could not initialise cmdline context.\n"); + if (strlen(cmdline_filename) != 0) cmdline_read_from_file(cmdline_filename); diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index 31f766c965..9058d21a07 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -16,7 +16,13 @@ #include <rte_gso.h> #endif #include <rte_os_shim.h> +#include <rte_ethdev.h> +#include <rte_flow.h> +#include <rte_mbuf_dyn.h> + #include <cmdline.h> +#include <cmdline_parse.h> + #include <sys/queue.h> #ifdef RTE_HAS_JANSSON #include <jansson.h> @@ -866,6 +872,7 @@ unsigned int parse_item_list(const char *str, const char *item_name, unsigned int *parsed_items, int check_unique_values); void launch_args_parse(int argc, char** argv); void cmdline_read_from_file(const char *filename); +int init_cmdline(void); void prompt(void); void prompt_exit(void); void nic_stats_display(portid_t port_id); @@ -1169,6 +1176,15 @@ extern int flow_parse(const char *src, void *result, unsigned int size, struct rte_flow_item **pattern, struct rte_flow_action **actions); +/* For registering commands out of testpmd sources. */ +struct testpmd_cmdline_parser { + TAILQ_ENTRY(testpmd_cmdline_parser) next; + cmdline_parse_ctx_t *ctx; + const char *help[]; +}; + +void testpmd_add_commands(struct testpmd_cmdline_parser *parser); + /* * Work-around of a compilation error with ICC on invocations of the * rte_be_to_cpu_16() function. diff --git a/drivers/meson.build b/drivers/meson.build index 1d8123b00c..4daa2658b7 100644 --- a/drivers/meson.build +++ b/drivers/meson.build @@ -102,6 +102,7 @@ foreach subpath:subdirs # static builds. ext_deps = [] pkgconfig_extra_libs = [] + testpmd_sources = [] if not enable_drivers.contains(drv_path) build = false @@ -246,6 +247,10 @@ foreach subpath:subdirs set_variable('shared_@0@'.format(lib_name), shared_dep) set_variable('static_@0@'.format(lib_name), static_dep) dependency_name = ''.join(lib_name.split('rte_')) + if testpmd_sources.length() != 0 + testpmd_drivers_sources += testpmd_sources + testpmd_drivers_deps += dependency_name + endif if developer_mode message('drivers/@0@: Defining dependency "@1@"'.format( drv_path, dependency_name)) diff --git a/meson.build b/meson.build index 937f6110c0..5561171617 100644 --- a/meson.build +++ b/meson.build @@ -42,6 +42,8 @@ dpdk_drivers = [] dpdk_extra_ldflags = [] dpdk_libs_disabled = [] dpdk_drvs_disabled = [] +testpmd_drivers_sources = [] +testpmd_drivers_deps = [] abi_version_file = files('ABI_VERSION') if host_machine.cpu_family().startswith('x86') -- 2.23.0