@@ -50,12 +50,22 @@
/****************/
+static uint8_t test_abi_version = TEST_DPDK_ABI_VERSION_DEFAULT;
+
+static struct test_abi_version_list abi_version_list =
+ TAILQ_HEAD_INITIALIZER(abi_version_list);
+
static struct test_commands_list commands_list =
TAILQ_HEAD_INITIALIZER(commands_list);
-void
-add_test_command(struct test_command *t)
+void add_abi_version(struct test_abi_version *av)
+{
+ TAILQ_INSERT_TAIL(&abi_version_list, av, next);
+}
+
+void add_test_command(struct test_command *t, uint8_t abi_version)
{
+ t->abi_version = abi_version;
TAILQ_INSERT_TAIL(&commands_list, t, next);
}
@@ -63,6 +73,12 @@ struct cmd_autotest_result {
cmdline_fixed_string_t autotest;
};
+cmdline_parse_token_string_t
+cmd_autotest_autotest[TEST_DPDK_ABI_VERSION_MAX] = {
+ [0 ... TEST_DPDK_ABI_VERSION_MAX-1] =
+ TOKEN_STRING_INITIALIZER(struct cmd_autotest_result, autotest, "")
+};
+
static void cmd_autotest_parsed(void *parsed_result,
__attribute__((unused)) struct cmdline *cl,
__attribute__((unused)) void *data)
@@ -72,7 +88,8 @@ static void cmd_autotest_parsed(void *parsed_result,
int ret = 0;
TAILQ_FOREACH(t, &commands_list, next) {
- if (!strcmp(res->autotest, t->command))
+ if (!strcmp(res->autotest, t->command)
+ && t->abi_version == test_abi_version)
ret = t->callback();
}
@@ -86,10 +103,6 @@ static void cmd_autotest_parsed(void *parsed_result,
fflush(stdout);
}
-cmdline_parse_token_string_t cmd_autotest_autotest =
- TOKEN_STRING_INITIALIZER(struct cmd_autotest_result, autotest,
- "");
-
cmdline_parse_inst_t cmd_autotest = {
.f = cmd_autotest_parsed, /* function to call */
.data = NULL, /* 2nd arg of func */
@@ -244,6 +257,53 @@ cmdline_parse_inst_t cmd_quit = {
/****************/
+struct cmd_set_abi_version_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t abi_version_name;
+};
+
+static void cmd_set_abi_version_parsed(
+ void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct test_abi_version *av;
+ struct cmd_set_abi_version_result *res = parsed_result;
+
+ TAILQ_FOREACH(av, &abi_version_list, next) {
+ if (!strcmp(res->abi_version_name, av->version_name)) {
+
+ printf("abi version set to %s\n", av->version_name);
+ test_abi_version = av->version_id;
+ cmd_autotest.tokens[0] =
+ (void *)&cmd_autotest_autotest[av->version_id];
+ }
+ }
+
+ fflush(stdout);
+}
+
+cmdline_parse_token_string_t cmd_set_abi_version_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_abi_version_result, set,
+ "set_abi_version");
+
+cmdline_parse_token_string_t cmd_set_abi_version_abi_version =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_abi_version_result,
+ abi_version_name, NULL);
+
+cmdline_parse_inst_t cmd_set_abi_version = {
+ .f = cmd_set_abi_version_parsed, /* function to call */
+ .data = NULL, /* 2nd arg of func */
+ .help_str = "set abi version: ",
+ .tokens = { /* token list, NULL terminated */
+ (void *)&cmd_set_abi_version_set,
+ (void *)&cmd_set_abi_version_abi_version,
+ NULL,
+ },
+};
+
+/****************/
+
struct cmd_set_rxtx_result {
cmdline_fixed_string_t set;
cmdline_fixed_string_t mode;
@@ -259,7 +319,7 @@ static void cmd_set_rxtx_parsed(void *parsed_result, struct cmdline *cl,
cmdline_parse_token_string_t cmd_set_rxtx_set =
TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_result, set,
- "set_rxtx_mode");
+ "set_rxtx_mode");
cmdline_parse_token_string_t cmd_set_rxtx_mode =
TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_result, mode, NULL);
@@ -360,29 +420,66 @@ cmdline_parse_ctx_t main_ctx[] = {
(cmdline_parse_inst_t *)&cmd_set_rxtx,
(cmdline_parse_inst_t *)&cmd_set_rxtx_anchor,
(cmdline_parse_inst_t *)&cmd_set_rxtx_sc,
+ (cmdline_parse_inst_t *)&cmd_set_abi_version,
NULL,
};
int commands_init(void)
{
+ struct test_abi_version *av;
struct test_command *t;
- char *commands;
- int commands_len = 0;
+ char *commands[TEST_DPDK_ABI_VERSION_MAX];
+ char *help;
+
+ int commands_len[TEST_DPDK_ABI_VERSION_MAX] = {
+ [0 ... TEST_DPDK_ABI_VERSION_MAX-1] = 0
+ };
+ int help_len = strlen(cmd_set_abi_version.help_str);
+ int abi_version;
+
+ /* set the set_abi_version command help string */
+ TAILQ_FOREACH(av, &abi_version_list, next) {
+ help_len += strlen(av->version_name) + 1;
+ }
+
+ help = (char *)calloc(help_len, sizeof(char));
+ if (!help)
+ return -1;
+
+ strlcat(help, cmd_set_abi_version.help_str, help_len);
+ TAILQ_FOREACH(av, &abi_version_list, next) {
+ strlcat(help, av->version_name, help_len);
+ if (TAILQ_NEXT(av, next) != NULL)
+ strlcat(help, "|", help_len);
+ }
+
+ cmd_set_abi_version.help_str = help;
+ /* set the parse strings for the command lists */
TAILQ_FOREACH(t, &commands_list, next) {
- commands_len += strlen(t->command) + 1;
+ commands_len[t->abi_version] += strlen(t->command) + 1;
}
- commands = (char *)calloc(commands_len, sizeof(char));
- if (!commands)
- return -1;
+ for (abi_version = 0; abi_version < TEST_DPDK_ABI_VERSION_MAX;
+ abi_version++) {
+ commands[abi_version] =
+ (char *)calloc(commands_len[abi_version], sizeof(char));
+ if (!commands[abi_version])
+ return -1;
+ }
TAILQ_FOREACH(t, &commands_list, next) {
- strlcat(commands, t->command, commands_len);
+ strlcat(commands[t->abi_version],
+ t->command, commands_len[t->abi_version]);
if (TAILQ_NEXT(t, next) != NULL)
- strlcat(commands, "#", commands_len);
+ strlcat(commands[t->abi_version],
+ "#", commands_len[t->abi_version]);
}
- cmd_autotest_autotest.string_data.str = commands;
+ for (abi_version = 0; abi_version < TEST_DPDK_ABI_VERSION_MAX;
+ abi_version++)
+ cmd_autotest_autotest[abi_version].string_data.str =
+ commands[abi_version];
+
return 0;
}
@@ -307,3 +307,5 @@ unit_test_suite_runner(struct unit_test_suite *suite)
return TEST_SKIPPED;
return TEST_SUCCESS;
}
+
+REGISTER_TEST_ABI_VERSION(default, TEST_DPDK_ABI_VERSION_DEFAULT)
@@ -162,25 +162,59 @@ int test_set_rxtx_conf(cmdline_fixed_string_t mode);
int test_set_rxtx_anchor(cmdline_fixed_string_t type);
int test_set_rxtx_sc(cmdline_fixed_string_t type);
+#define MAP_ABI_SYMBOL_VERSION(name, abi_version) \
+ __asm(".symver "RTE_STR(name)","RTE_STR(name)"@"RTE_STR(abi_version))
+
+#define TEST_DPDK_ABI_VERSION_DEFAULT 0
+#define TEST_DPDK_ABI_VERSION_V1604 1
+#define TEST_DPDK_ABI_VERSION_V20 2
+#define TEST_DPDK_ABI_VERSION_MAX 3
+
+TAILQ_HEAD(test_abi_version_list, test_abi_version);
+struct test_abi_version {
+ TAILQ_ENTRY(test_abi_version) next;
+ const char *version_name;
+ uint8_t version_id;
+};
+
+void add_abi_version(struct test_abi_version *av);
+
+/* Register a test function with its command string */
+#define REGISTER_TEST_ABI_VERSION(name, id) \
+ static struct test_abi_version test_struct_##name = { \
+ .version_name = RTE_STR(name), \
+ .version_id = id, \
+ }; \
+ RTE_INIT(test_register_##name) \
+ { \
+ add_abi_version(&test_struct_##name); \
+ }
+
typedef int (test_callback)(void);
TAILQ_HEAD(test_commands_list, test_command);
struct test_command {
TAILQ_ENTRY(test_command) next;
const char *command;
test_callback *callback;
+ uint8_t abi_version;
};
-void add_test_command(struct test_command *t);
+void add_test_command(struct test_command *t, uint8_t abi_version);
+
+/* Register a test function with its command string and abi version */
+#define REGISTER_TEST_COMMAND_VERSION(cmd, func, abi_version) \
+ static struct test_command test_struct_##cmd = { \
+ .command = RTE_STR(cmd), \
+ .callback = func, \
+ }; \
+ RTE_INIT(test_register_##cmd) \
+ { \
+ add_test_command(&test_struct_##cmd, abi_version); \
+ }
/* Register a test function with its command string */
+
#define REGISTER_TEST_COMMAND(cmd, func) \
- static struct test_command test_struct_##cmd = { \
- .command = RTE_STR(cmd), \
- .callback = func, \
- }; \
- RTE_INIT(test_register_##cmd) \
- { \
- add_test_command(&test_struct_##cmd); \
- }
+ REGISTER_TEST_COMMAND_VERSION(cmd, func, TEST_DPDK_ABI_VERSION_DEFAULT)
#endif
@@ -221,6 +221,10 @@ The macros exported are:
the linker to bind references to symbol ``b`` to the internal symbol
``b_e``.
+* ``BIND_VERSION_SYMBOL(b, n)``: Creates a symbol version entry instructing
+ the linker to bind references to symbol ``b`` to the external symbol
+ ``b@DPDK_n``
+
* ``MAP_STATIC_SYMBOL(f, p)``: Declare the prototype ``f``, and map it to the
fully qualified function ``p``, so that if a symbol becomes versioned, it
can still be mapped back to the public symbol name.
@@ -50,6 +50,13 @@
#define BIND_DEFAULT_SYMBOL(b, e, n) __asm__(".symver " RTE_STR(b) RTE_STR(e) ", " RTE_STR(b) "@@DPDK_" RTE_STR(n))
#define __vsym __attribute__((used))
+/*
+ * BIND_VERSION_SYMBOL
+ * Creates a symbol version entry instructing the linker to bind references to
+ * symbol <b> to the symbol version <b>@DPDK_<n>
+ */
+#define BIND_VERSION_SYMBOL(b, n) __asm__(".symver " RTE_STR(b) ", " RTE_STR(b) "@DPDK_" RTE_STR(n))
+
/*
* MAP_STATIC_SYMBOL
* If a function has been bifurcated into multiple versions, none of which