From: Tonghao Zhang <[email protected]> This patch introduces last-init queue, user can register a callback for theirs initialization. Running rte_last_init_run(), the almost resource of DPDK are available, such as memzone, ring. With this way, user don't introduce additional codes in eal layer.
[This patch will be used for next patch.] Signed-off-by: Tonghao Zhang <[email protected]> --- v2: * rename rte_last_init_register ->rte_init_register * rename rte_last_init struct ->rte_init * rename rte_init_cb ->rte_init_cb_t * free the rte_init node when not used. * remove rte_init and others to eal_private.h * add comments * fix checkpatch warning --- lib/librte_eal/common/eal_common_init.c | 74 +++++++++++++++++++++++++++++++++ lib/librte_eal/common/eal_private.h | 23 ++++++++++ lib/librte_eal/common/meson.build | 1 + lib/librte_eal/freebsd/Makefile | 1 + lib/librte_eal/freebsd/eal.c | 6 +++ lib/librte_eal/include/rte_init.h | 59 ++++++++++++++++++++++++++ lib/librte_eal/linux/Makefile | 1 + lib/librte_eal/linux/eal.c | 6 +++ 8 files changed, 171 insertions(+) create mode 100644 lib/librte_eal/common/eal_common_init.c create mode 100644 lib/librte_eal/include/rte_init.h diff --git a/lib/librte_eal/common/eal_common_init.c b/lib/librte_eal/common/eal_common_init.c new file mode 100644 index 0000000..1d89db3 --- /dev/null +++ b/lib/librte_eal/common/eal_common_init.c @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2020 DPDK Community + */ + +#include <sys/queue.h> + +#include <rte_init.h> +#include <rte_debug.h> +#include <rte_tailq.h> + +#include "eal_private.h" + +static struct rte_init_list rte_init_list = + TAILQ_HEAD_INITIALIZER(rte_init_list); + +void +rte_init_register(rte_init_cb_t cb, const void *arg, enum rte_init_type type) +{ + struct rte_init *last; + + RTE_VERIFY(cb); + + last = malloc(sizeof(*last)); + if (last == NULL) + rte_panic("Alloc memory for rte_init node failed\n"); + + last->type = type; + last->arg = arg; + last->cb = cb; + + TAILQ_INSERT_TAIL(&rte_init_list, last, next); +} + +static int +eal_rte_init_run_type(enum rte_init_type type) +{ + struct rte_init *last; + int ret; + + TAILQ_FOREACH(last, &rte_init_list, next) { + if (last->type != type) + continue; + + ret = last->cb(last->arg); + if (ret < 0) + return ret; + } + + return 0; +} + +int +eal_rte_init_run(void) +{ + struct rte_init *last; + struct rte_init *tmp; + int ret; + + ret = eal_rte_init_run_type(RTE_INIT_PRE); + if (ret < 0) + return ret; + + ret = eal_rte_init_run_type(RTE_INIT_POST); + if (ret < 0) + return ret; + + /* Free rte_init node, not used anymore. */ + TAILQ_FOREACH_SAFE(last, &rte_init_list, next, tmp) { + TAILQ_REMOVE(&rte_init_list, last, next); + free(last); + } + + return 0; +} diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h index ddcfbe2..f0bcc97 100644 --- a/lib/librte_eal/common/eal_private.h +++ b/lib/librte_eal/common/eal_private.h @@ -11,6 +11,7 @@ #include <rte_dev.h> #include <rte_lcore.h> +#include <rte_init.h> /** * Structure storing internal configuration (per-lcore) @@ -60,6 +61,28 @@ struct rte_config { } __attribute__((__packed__)); /** + * A structure describing a generic initialization. + */ +struct rte_init { + TAILQ_ENTRY(rte_init) next; + enum rte_init_type type; + rte_init_cb_t cb; + const void *arg; +}; + +/** Double linked list of rte_init. */ +TAILQ_HEAD(rte_init_list, rte_init); + +/** + * Run the callback registered in the global double linked list. + * + * @return + * - 0 on success + * - Negative on error + */ +int eal_rte_init_run(void); + +/** * Get the global configuration structure. * * @return diff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build index 02d9280..ad0ce6a 100644 --- a/lib/librte_eal/common/meson.build +++ b/lib/librte_eal/common/meson.build @@ -43,6 +43,7 @@ sources += files( 'eal_common_thread.c', 'eal_common_timer.c', 'eal_common_uuid.c', + 'eal_common_init.c', 'hotplug_mp.c', 'malloc_elem.c', 'malloc_heap.c', diff --git a/lib/librte_eal/freebsd/Makefile b/lib/librte_eal/freebsd/Makefile index e5d4d8f..89c5649 100644 --- a/lib/librte_eal/freebsd/Makefile +++ b/lib/librte_eal/freebsd/Makefile @@ -60,6 +60,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_thread.c SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_proc.c SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_fbarray.c SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_uuid.c +SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_common_init.c SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_malloc.c SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += hotplug_mp.c SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += malloc_elem.c diff --git a/lib/librte_eal/freebsd/eal.c b/lib/librte_eal/freebsd/eal.c index 6ae37e7..63af98c 100644 --- a/lib/librte_eal/freebsd/eal.c +++ b/lib/librte_eal/freebsd/eal.c @@ -874,6 +874,12 @@ static void rte_eal_init_alert(const char *msg) eal_check_mem_on_local_socket(); + if (eal_rte_init_run() < 0) { + rte_eal_init_alert("Cannot init objects in rte-init queue"); + rte_errno = EFAULT; + return -1; + } + eal_thread_init_master(rte_config.master_lcore); ret = eal_thread_dump_affinity(cpuset, sizeof(cpuset)); diff --git a/lib/librte_eal/include/rte_init.h b/lib/librte_eal/include/rte_init.h new file mode 100644 index 0000000..636efff --- /dev/null +++ b/lib/librte_eal/include/rte_init.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2020 DPDK Community + */ + +#ifndef _RTE_INIT_H_ +#define _RTE_INIT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdio.h> +#include <sys/queue.h> + +/** + * Implementation specific callback function which is + * responsible for specificed initialization. + * + * This is called when almost resources are available. + * + * @return + * 0 for successful callback + * Negative for unsuccessful callback with error value + */ +typedef int (*rte_init_cb_t)(const void *arg); + +/** + * rte_init type. + * + * The rte_init of RTE_INIT_PRE are called firstly, + * and then RTE_INIT_POST. + */ +enum rte_init_type { + RTE_INIT_PRE, + RTE_INIT_POST +}; + +/** + * Register a rte_init callback. + * + * @param cb + * A pointer to a rte_init_cb structure, which will be used + * in rte_eal_init(). + * + * @param arg + * The cb will use that as param. + * + * @param type + * The type of rte_init registered. + */ + +void rte_init_register(rte_init_cb_t cb, const void *arg, + enum rte_init_type type); + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_INIT_H_ */ diff --git a/lib/librte_eal/linux/Makefile b/lib/librte_eal/linux/Makefile index e5f4495..918d94b 100644 --- a/lib/librte_eal/linux/Makefile +++ b/lib/librte_eal/linux/Makefile @@ -67,6 +67,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_thread.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_proc.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_fbarray.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_uuid.c +SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_common_init.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_malloc.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += hotplug_mp.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += malloc_elem.c diff --git a/lib/librte_eal/linux/eal.c b/lib/librte_eal/linux/eal.c index 9530ee5..dd0c258 100644 --- a/lib/librte_eal/linux/eal.c +++ b/lib/librte_eal/linux/eal.c @@ -1203,6 +1203,12 @@ static void rte_eal_init_alert(const char *msg) eal_check_mem_on_local_socket(); + if (eal_rte_init_run() < 0) { + rte_eal_init_alert("Cannot init objects in rte-init queue"); + rte_errno = EFAULT; + return -1; + } + eal_thread_init_master(rte_config.master_lcore); ret = eal_thread_dump_affinity(cpuset, sizeof(cpuset)); -- 1.8.3.1

