From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by dpdk.org (Postfix) with ESMTP id CBF961B126 for ; Tue, 16 Oct 2018 17:57:43 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 16 Oct 2018 08:57:43 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,389,1534834800"; d="scan'208";a="92465329" Received: from silpixa00397517.ir.intel.com (HELO silpixa00397517.ger.corp.intel.com) ([10.237.222.54]) by orsmga003.jf.intel.com with ESMTP; 16 Oct 2018 08:57:41 -0700 From: Kevin Laatz To: dev@dpdk.org Cc: harry.van.haaren@intel.com, stephen@networkplumber.org, gaetan.rivet@6wind.com, shreyansh.jain@nxp.com, thomas@monjalon.net, mattias.ronnblom@ericsson.com, bruce.richardson@intel.com, Kevin Laatz Date: Tue, 16 Oct 2018 16:57:50 +0100 Message-Id: <20181016155802.2067-2-kevin.laatz@intel.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20181016155802.2067-1-kevin.laatz@intel.com> References: <20181011165837.81030-1-kevin.laatz@intel.com> <20181016155802.2067-1-kevin.laatz@intel.com> Subject: [dpdk-dev] [PATCH v5 01/13] eal: add param register infrastructure X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Oct 2018 15:57:44 -0000 This commit adds infrastructure to EAL that allows an application to register it's init function with EAL. This allows libraries to be initialized at the end of EAL init. This infrastructure allows libraries that depend on EAL to be initialized as part of EAL init, removing circular dependency issues. Signed-off-by: Kevin Laatz Acked-by: Harry van Haaren --- lib/librte_eal/bsdapp/eal/Makefile | 1 + lib/librte_eal/bsdapp/eal/eal.c | 18 +++++- lib/librte_eal/common/Makefile | 1 + lib/librte_eal/common/include/rte_param.h | 91 +++++++++++++++++++++++++++++++ lib/librte_eal/common/meson.build | 2 + lib/librte_eal/common/rte_param.c | 47 ++++++++++++++++ lib/librte_eal/linuxapp/eal/Makefile | 1 + lib/librte_eal/linuxapp/eal/eal.c | 18 +++++- lib/librte_eal/rte_eal_version.map | 1 + 9 files changed, 178 insertions(+), 2 deletions(-) create mode 100644 lib/librte_eal/common/include/rte_param.h create mode 100644 lib/librte_eal/common/rte_param.c diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile index d27da3d..7f4fa7e 100644 --- a/lib/librte_eal/bsdapp/eal/Makefile +++ b/lib/librte_eal/bsdapp/eal/Makefile @@ -66,6 +66,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += malloc_elem.c SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += malloc_heap.c SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += malloc_mp.c SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += rte_keepalive.c +SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += rte_param.c SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += rte_service.c SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += rte_reciprocal.c diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c index d7ae9d6..27b7afc 100644 --- a/lib/librte_eal/bsdapp/eal/eal.c +++ b/lib/librte_eal/bsdapp/eal/eal.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -414,12 +415,20 @@ eal_parse_args(int argc, char **argv) argvopt = argv; optind = 1; optreset = 1; + opterr = 0; while ((opt = getopt_long(argc, argvopt, eal_short_options, eal_long_options, &option_index)) != EOF) { - /* getopt is not happy, stop right now */ + /* + * getopt didn't recognise the option, lets parse the + * registered options to see if the flag is valid + */ if (opt == '?') { + ret = rte_param_parse(argv[optind-1]); + if (ret == 0) + continue; + eal_usage(prgname); ret = -1; goto out; @@ -788,6 +797,13 @@ rte_eal_init(int argc, char **argv) rte_eal_mcfg_complete(); + /* Call each registered callback, if enabled */ + ret = rte_param_init(); + if (ret < 0) { + rte_eal_init_alert("Callback failed\n"); + return -1; + } + return fctret; } diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile index cca6882..8def95a 100644 --- a/lib/librte_eal/common/Makefile +++ b/lib/librte_eal/common/Makefile @@ -12,6 +12,7 @@ INC += rte_tailq.h rte_interrupts.h rte_alarm.h INC += rte_string_fns.h rte_version.h INC += rte_eal_memconfig.h rte_malloc_heap.h INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h rte_class.h +INC += rte_param.h INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h INC += rte_malloc.h rte_keepalive.h rte_time.h INC += rte_service.h rte_service_component.h diff --git a/lib/librte_eal/common/include/rte_param.h b/lib/librte_eal/common/include/rte_param.h new file mode 100644 index 0000000..a0635f7 --- /dev/null +++ b/lib/librte_eal/common/include/rte_param.h @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation. + */ + +#ifndef __INCLUDE_RTE_PARAM_H__ +#define __INCLUDE_RTE_PARAM_H__ + +/** + * @file + * + * This API introduces the ability to register callbacks with EAL. When + * registering a callback, the application also provides an option as part + * of the struct used to register. If the option is passed to EAL when + * running a DPDK application, the relevant callback will be called at the + * end of EAL init. For example, passing --telemetry will make the + * telemetry init be called at the end of EAL init. + * + * The register API can be used to resolve circular dependency issues + * between EAL and the library. The library uses EAL but is also initialized by + * EAL. Hence, EAL depends on the init function of the library. The API + * introduced in rte_param allows us to register the library init with EAL + * (passing a function pointer) and avoid the circular dependency. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int (*rte_param_cb)(void); + +/* + * Structure containing parameters relating to the function being registered + * with EAL. + */ +struct rte_param { + TAILQ_ENTRY(rte_param) next; /** The next entry in the TAILQ*/ + char *eal_option; /** The EAL option */ + rte_param_cb cb; /** Function pointer of the callback */ + + /** + * Enabled flag, should be 0 by default. This is set when the option + * for the callback is passed to EAL and determines if the callback is + * called or not. + */ + int enabled; +}; + +/** + * @internal Check if the passed option is valid + * + * @param option + * The option to be parsed + * + * @return + * 0 on success + * @return + * -1 on fail + */ +int +rte_param_parse(char *option); + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * Register a function with EAL. Registering the function will enable the + * function to be called at the end of EAL init. + * + * @param reg_param + * Structure containing various params used to register the function. + */ +void __rte_experimental +rte_param_register(struct rte_param *reg_param); + +/** + * @internal Iterate through the registered params and call the callback for + * the enabled ones. + * + * @return + * 0 on success + * @return + * -1 on fail + */ +int +rte_param_init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build index b7fc984..4069e49 100644 --- a/lib/librte_eal/common/meson.build +++ b/lib/librte_eal/common/meson.build @@ -33,6 +33,7 @@ common_sources = files( 'malloc_mp.c', 'rte_keepalive.c', 'rte_malloc.c', + 'rte_param.c', 'rte_reciprocal.c', 'rte_service.c' ) @@ -70,6 +71,7 @@ common_headers = files( 'include/rte_malloc_heap.h', 'include/rte_memory.h', 'include/rte_memzone.h', + 'include/rte_param.h', 'include/rte_pci_dev_feature_defs.h', 'include/rte_pci_dev_features.h', 'include/rte_per_lcore.h', diff --git a/lib/librte_eal/common/rte_param.c b/lib/librte_eal/common/rte_param.c new file mode 100644 index 0000000..317e371 --- /dev/null +++ b/lib/librte_eal/common/rte_param.c @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation. + */ + +#include +#include + +#include +#include + +TAILQ_HEAD(rte_param_list, rte_param); + +struct rte_param_list rte_param_list = + TAILQ_HEAD_INITIALIZER(rte_param_list); + +static struct rte_param *param; + +int +rte_param_parse(char *option) +{ + /* Check if the option is in the registered inits */ + TAILQ_FOREACH(param, &rte_param_list, next) { + if (strcmp(option, param->eal_option) == 0) { + param->enabled = 1; + return 0; + } + } + + return -1; +} + +void __rte_experimental +rte_param_register(struct rte_param *reg_param) +{ + TAILQ_INSERT_HEAD(&rte_param_list, reg_param, next); +} + +int +rte_param_init(void) +{ + TAILQ_FOREACH(param, &rte_param_list, next) { + if (param->enabled) + param->cb(); + } + + return 0; +} diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile index 5c16bc4..2bf8b24 100644 --- a/lib/librte_eal/linuxapp/eal/Makefile +++ b/lib/librte_eal/linuxapp/eal/Makefile @@ -74,6 +74,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += malloc_elem.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += malloc_heap.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += malloc_mp.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += rte_keepalive.c +SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += rte_param.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += rte_service.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += rte_reciprocal.c diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c index 4a55d3b..e28562b 100644 --- a/lib/librte_eal/linuxapp/eal/eal.c +++ b/lib/librte_eal/linuxapp/eal/eal.c @@ -48,6 +48,7 @@ #include #include #include +#include #include "eal_private.h" #include "eal_thread.h" @@ -600,12 +601,20 @@ eal_parse_args(int argc, char **argv) argvopt = argv; optind = 1; + opterr = 0; while ((opt = getopt_long(argc, argvopt, eal_short_options, eal_long_options, &option_index)) != EOF) { - /* getopt is not happy, stop right now */ + /* + * getopt didn't recognise the option, lets parse the + * registered options to see if the flag is valid + */ if (opt == '?') { + ret = rte_param_parse(argv[optind-1]); + if (ret == 0) + continue; + eal_usage(prgname); ret = -1; goto out; @@ -1071,6 +1080,13 @@ rte_eal_init(int argc, char **argv) rte_eal_mcfg_complete(); + /* Call each registered callback, if enabled */ + ret = rte_param_init(); + if (ret < 0) { + rte_eal_init_alert("Callback failed\n"); + return -1; + } + return fctret; } diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map index 73282bb..ccfb8a2 100644 --- a/lib/librte_eal/rte_eal_version.map +++ b/lib/librte_eal/rte_eal_version.map @@ -341,6 +341,7 @@ EXPERIMENTAL { rte_mp_request_sync; rte_mp_request_async; rte_mp_sendmsg; + rte_param_register; rte_service_lcore_attr_get; rte_service_lcore_attr_reset_all; rte_service_may_be_active; -- 2.9.5