* Re: [dpdk-dev] [PATCH v5 3/3] app/testpmd: add parse options from JSON cfg file
@ 2018-05-16 14:07 Iremonger, Bernard
0 siblings, 0 replies; 2+ messages in thread
From: Iremonger, Bernard @ 2018-05-16 14:07 UTC (permalink / raw)
To: dev, kubax.kozak; +Cc: Iremonger, Bernard
Hi Kuba,
This patch does not apply to the dpdk_18_05_rc4 master branch and needs to be rebased.
Regards,
Bernard.
^ permalink raw reply [flat|nested] 2+ messages in thread
* [dpdk-dev] [PATCH v4 1/3] eal: add functions parsing EAL arguments
@ 2017-07-10 12:51 Kuba Kozak
2017-07-13 10:07 ` [dpdk-dev] [PATCH v5 0/3] EAL change for using a config file for DPDK Kuba Kozak
0 siblings, 1 reply; 2+ messages in thread
From: Kuba Kozak @ 2017-07-10 12:51 UTC (permalink / raw)
To: dev
Cc: deepak.k.jain, bruce.richardson, michalx.k.jastrzebski,
jacekx.piasecki, Kuba Kozak
added function rte_eal_configure which configure
Environment Abstraction Layer (EAL) using
configuration structure.
Signed-off-by: Kuba Kozak <kubax.kozak@intel.com>
Suggested-by: Bruce Richardson <bruce.richardson@intel.com>
---
lib/Makefile | 3 +
lib/librte_eal/bsdapp/eal/Makefile | 4 +
lib/librte_eal/bsdapp/eal/eal.c | 165 +++++++++++----
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 +
lib/librte_eal/common/eal_common_lcore.c | 7 +
lib/librte_eal/common/eal_common_options.c | 106 ++++++++++
lib/librte_eal/common/eal_options.h | 3 +
lib/librte_eal/common/include/rte_eal.h | 20 ++
lib/librte_eal/linuxapp/eal/Makefile | 3 +
lib/librte_eal/linuxapp/eal/eal.c | 265 ++++++++++++++++--------
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 +
mk/rte.app.mk | 2 +-
12 files changed, 452 insertions(+), 128 deletions(-)
diff --git a/lib/Makefile b/lib/Makefile
index 1080a95..2c6c380 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -34,6 +34,9 @@ include $(RTE_SDK)/mk/rte.vars.mk
DIRS-y += librte_compat
DIRS-$(CONFIG_RTE_LIBRTE_CFGFILE) += librte_cfgfile
DIRS-$(CONFIG_RTE_LIBRTE_EAL) += librte_eal
+ifeq ($(CONFIG_RTE_LIBRTE_CFGFILE),y)
+DEPDIRS-librte_eal := librte_cfgfile
+endif
DIRS-$(CONFIG_RTE_LIBRTE_RING) += librte_ring
DEPDIRS-librte_ring := librte_eal
DIRS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += librte_mempool
diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index a0f9950..d70eefb 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -50,6 +50,10 @@ EXPORT_MAP := rte_eal_version.map
LIBABIVER := 4
+ifeq ($(CONFIG_RTE_LIBRTE_CFGFILE),y)
+LDLIBS += -lrte_cfgfile
+endif
+
# specific to bsdapp exec-env
SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) := eal.c
SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_memory.c
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 05f0c1f..4a0c221 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -73,6 +73,7 @@
#include <rte_version.h>
#include <rte_atomic.h>
#include <malloc_heap.h>
+#include <rte_cfgfile.h>
#include "eal_private.h"
#include "eal_thread.h"
@@ -99,6 +100,8 @@ static struct flock wr_lock = {
.l_len = sizeof(early_mem_config.memseg),
};
+static int run_once_reset_internal_config;
+
/* Address of global and public configuration */
static struct rte_config rte_config = {
.mem_config = &early_mem_config,
@@ -347,6 +350,58 @@ eal_log_level_parse(int argc, char **argv)
optarg = old_optarg;
}
+/* Parse single argument */
+static int
+eal_parse_option(int opt, char *optarg, int option_index, char *prgname)
+{
+ int ret;
+
+ /* getopt is not happy, stop right now */
+ if (opt == '?') {
+ eal_usage(prgname);
+ ret = -1;
+ goto out;
+ }
+
+ ret = eal_parse_common_option(opt, optarg, &internal_config);
+ /* common parser is not happy */
+ if (ret < 0) {
+ eal_usage(prgname);
+ ret = -1;
+ goto out;
+ }
+ /* common parser handled this option */
+ if (ret == 0)
+ return 0;
+
+ switch (opt) {
+ case 'h':
+ eal_usage(prgname);
+ exit(EXIT_SUCCESS);
+ break;
+
+ default:
+ if (opt < OPT_LONG_MIN_NUM && isprint(opt)) {
+ RTE_LOG(ERR, EAL, "Option %c is not supported "
+ "on FreeBSD\n", opt);
+ } else if (opt >= OPT_LONG_MIN_NUM &&
+ opt < OPT_LONG_MAX_NUM) {
+ RTE_LOG(ERR, EAL, "Option %s is not supported "
+ "on FreeBSD\n",
+ eal_long_options[option_index].name);
+ } else {
+ RTE_LOG(ERR, EAL, "Option %d is not supported "
+ "on FreeBSD\n", opt);
+ }
+ eal_usage(prgname);
+ ret = -1;
+ goto out;
+ }
+ return 0;
+out:
+ return ret;
+}
+
/* Parse the argument given in the command line of the application */
static int
eal_parse_args(int argc, char **argv)
@@ -367,45 +422,9 @@ eal_parse_args(int argc, char **argv)
while ((opt = getopt_long(argc, argvopt, eal_short_options,
eal_long_options, &option_index)) != EOF) {
- /* getopt is not happy, stop right now */
- if (opt == '?') {
- eal_usage(prgname);
- ret = -1;
- goto out;
- }
-
- ret = eal_parse_common_option(opt, optarg, &internal_config);
- /* common parser is not happy */
- if (ret < 0) {
- eal_usage(prgname);
- ret = -1;
- goto out;
- }
- /* common parser handled this option */
- if (ret == 0)
- continue;
-
- switch (opt) {
- case 'h':
- eal_usage(prgname);
- exit(EXIT_SUCCESS);
- default:
- if (opt < OPT_LONG_MIN_NUM && isprint(opt)) {
- RTE_LOG(ERR, EAL, "Option %c is not supported "
- "on FreeBSD\n", opt);
- } else if (opt >= OPT_LONG_MIN_NUM &&
- opt < OPT_LONG_MAX_NUM) {
- RTE_LOG(ERR, EAL, "Option %s is not supported "
- "on FreeBSD\n",
- eal_long_options[option_index].name);
- } else {
- RTE_LOG(ERR, EAL, "Option %d is not supported "
- "on FreeBSD\n", opt);
- }
- eal_usage(prgname);
- ret = -1;
+ ret = eal_parse_option(opt, optarg, option_index, prgname);
+ if (ret < 0)
goto out;
- }
}
if (eal_adjust_config(&internal_config) != 0) {
@@ -517,7 +536,10 @@ rte_eal_init(int argc, char **argv)
thread_id = pthread_self();
- eal_reset_internal_config(&internal_config);
+ if (!run_once_reset_internal_config) {
+ eal_reset_internal_config(&internal_config);
+ run_once_reset_internal_config = 1;
+ }
/* set log level as early as possible */
eal_log_level_parse(argc, argv);
@@ -677,3 +699,68 @@ rte_eal_process_type(void)
{
return rte_config.process_type;
}
+
+#ifdef RTE_LIBRTE_CFGFILE
+int
+rte_eal_configure(struct rte_cfgfile *cfg, char *prgname)
+{
+ int n_entries;
+ int i;
+ int opt;
+ int option_index;
+
+ if (cfg == NULL) {
+ rte_errno = -EINVAL;
+ return -1;
+ }
+
+ n_entries = rte_cfgfile_section_num_entries(cfg, "DPDK");
+
+ if (n_entries < 1) {
+ printf("No DPDK section entries in cfgfile object\n");
+ return 0;
+ }
+
+ struct rte_cfgfile_entry entries[n_entries];
+
+ if (n_entries !=
+ rte_cfgfile_section_entries(cfg, "DPDK", entries,
+ n_entries)) {
+ rte_eal_init_alert("Unexpected fault.");
+ rte_errno = EFAULT;
+ return -1;
+ }
+
+ if (!run_once_reset_internal_config) {
+ eal_reset_internal_config(&internal_config);
+ run_once_reset_internal_config = 1;
+ }
+
+ /* set log level as early as possible */
+ eal_log_level_cfg(cfg);
+
+ if (rte_eal_cpu_init() < 0) {
+ rte_eal_init_alert("Cannot detect lcores.");
+ rte_errno = ENOTSUP;
+ return -1;
+ }
+
+ for (i = 0; i < n_entries; i++) {
+ eal_getopt(entries[i].name, &opt, &option_index);
+
+ if (eal_parse_option(opt, entries[i].value,
+ option_index, prgname) != 0) {
+ rte_eal_init_alert("Invalid config file arguments.");
+ rte_errno = EINVAL;
+ return -1;
+ }
+ }
+
+ if (parse_vdev_devices(cfg) < 0) {
+ rte_eal_init_alert("Couldn't parse vdevs");
+ rte_errno = ENOMEM;
+ return -1;
+ }
+ return 0;
+}
+#endif
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 381f895..932f990 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -200,6 +200,7 @@ DPDK_17.08 {
rte_bus_find;
rte_bus_find_by_device;
rte_bus_find_by_name;
+ rte_eal_configure;
} DPDK_17.05;
diff --git a/lib/librte_eal/common/eal_common_lcore.c b/lib/librte_eal/common/eal_common_lcore.c
index 84fa0cb..d0f4c6f 100644
--- a/lib/librte_eal/common/eal_common_lcore.c
+++ b/lib/librte_eal/common/eal_common_lcore.c
@@ -53,11 +53,18 @@
int
rte_eal_cpu_init(void)
{
+ static int run_once;
+ static int ret;
/* pointer to global configuration */
struct rte_config *config = rte_eal_get_configuration();
unsigned lcore_id;
unsigned count = 0;
+ /* No need to calculate this function again if we know the result */
+ if (run_once)
+ return ret;
+ run_once = 1;
+
/*
* Parse the maximum set of logical cores, detect the subset of running
* ones and enable them by default.
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 075b0ea..b568f05 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -50,6 +50,10 @@
#include <rte_version.h>
#include <rte_devargs.h>
#include <rte_memcpy.h>
+#ifdef RTE_LIBRTE_CFGFILE
+#include <rte_cfgfile.h>
+#include <rte_errno.h>
+#endif
#include "eal_internal_cfg.h"
#include "eal_options.h"
@@ -1078,3 +1082,105 @@ eal_common_usage(void)
" --"OPT_NO_SHCONF" No shared config (mmap'd files)\n"
"\n", RTE_MAX_LCORE);
}
+
+#ifdef RTE_LIBRTE_CFGFILE
+/* Parse the arguments for --log-level only */
+void
+eal_log_level_cfg(struct rte_cfgfile *cfg)
+{
+ const char *entry;
+
+ entry = rte_cfgfile_get_entry(cfg, "DPDK", OPT_LOG_LEVEL);
+ if (entry)
+ eal_parse_common_option(OPT_LOG_LEVEL_NUM, entry,
+ &internal_config);
+}
+#endif
+
+#ifdef RTE_LIBRTE_CFGFILE
+static void rte_eal_init_alert(const char *msg)
+{
+ fprintf(stderr, "EAL: FATAL: %s\n", msg);
+ RTE_LOG(ERR, EAL, "%s\n", msg);
+}
+
+#define vdev_buff_size 200
+#define sectionname_size 20
+int
+parse_vdev_devices(struct rte_cfgfile *cfg)
+{
+ char sectionname[sectionname_size] = "DPDK.vdev0";
+ char buffer[vdev_buff_size];
+ int vdev_nb = 0;
+ int n_entries;
+ int buf_len;
+ char *buf_ptr;
+ int i;
+ int ret;
+
+ /* ----------- parsing VDEVS */
+ for (vdev_nb = 1; rte_cfgfile_has_section(cfg, sectionname);
+ vdev_nb++) {
+ n_entries = rte_cfgfile_section_num_entries(cfg, sectionname);
+
+ struct rte_cfgfile_entry entries[n_entries];
+
+ if (n_entries != rte_cfgfile_section_entries(cfg, sectionname,
+ entries, n_entries)) {
+ rte_eal_init_alert("Unexpected fault.");
+ rte_errno = EFAULT;
+ return -1;
+ }
+
+ buffer[0] = '\0';
+ buf_ptr = buffer;
+ buf_len = vdev_buff_size;
+ for (i = 0; i < n_entries; i++) {
+ ret = snprintf(buf_ptr, buf_len, "%s%s%s%s",
+ entries[i].name,
+ (entries[i].value[0] != '\0') ?
+ "=" : "",
+ entries[i].value,
+ (i < (n_entries - 1)) ? "," : "");
+ if (ret >= buf_len) {
+ printf("parse_vdev_devices(): buffer[] size is "
+ "to small\n");
+ return -1;
+ }
+ buf_len -= ret;
+ buf_ptr += ret;
+ }
+
+ /* parsing vdev */
+ if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL,
+ buffer) < 0) {
+ return -1;
+ }
+ snprintf(sectionname, sectionname_size, "DPDK.vdev%d", vdev_nb);
+ }
+ /* ----------- parsing VDEVS */
+ return 0;
+}
+
+void
+eal_getopt(const char *str, int *opt, int *option_index)
+{
+ int i;
+
+ *opt = '?';
+ *option_index = 0;
+
+ if (strlen(str) == 1) {
+ *opt = *str;
+ return;
+ }
+
+ for (i = 0; eal_long_options[i].name != NULL; i++) {
+ if (strcmp(str, eal_long_options[i].name) == 0) {
+ *opt = eal_long_options[i].val;
+ *option_index = i;
+ break;
+ }
+ }
+}
+#endif
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index a881c62..0fce11c 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -96,5 +96,8 @@ int eal_check_common_options(struct internal_config *internal_cfg);
void eal_common_usage(void);
enum rte_proc_type_t eal_proc_type_detect(void);
int eal_plugins_init(void);
+void eal_log_level_cfg(struct rte_cfgfile *cfg);
+int parse_vdev_devices(struct rte_cfgfile *cfg);
+void eal_getopt(const char *str, int *opt, int *option_index);
#endif /* EAL_OPTIONS_H */
diff --git a/lib/librte_eal/common/include/rte_eal.h b/lib/librte_eal/common/include/rte_eal.h
index 6b7c5ca..a1c78c0 100644
--- a/lib/librte_eal/common/include/rte_eal.h
+++ b/lib/librte_eal/common/include/rte_eal.h
@@ -46,6 +46,8 @@
#include <rte_per_lcore.h>
#include <rte_config.h>
+struct rte_cfgfile; /* forward declaration of struct */
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -188,6 +190,24 @@ int rte_eal_iopl_init(void);
*/
int rte_eal_init(int argc, char **argv);
+#ifdef RTE_LIBRTE_CFGFILE
+/**
+ * Initialize the Environment Abstraction Layer (EAL) using
+ * configuration structure
+ *
+ * @param cfg
+ * pointer to config file structure.
+ * @param prgname
+ * pointer to string with execution path
+ *
+ * @return
+ * - On success, return 0
+ * - On failure, returns -1.
+ */
+int
+rte_eal_configure(struct rte_cfgfile *cfg, char *prgname);
+#endif
+
/**
* Check if a primary process is currently alive
*
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 8651e27..7c1c559 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -53,6 +53,9 @@ LDLIBS += -lrt
ifeq ($(CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES),y)
LDLIBS += -lnuma
endif
+ifeq ($(CONFIG_RTE_LIBRTE_CFGFILE),y)
+LDLIBS += -lrte_cfgfile
+endif
# specific to linuxapp exec-env
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) := eal.c
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 7c78f2d..f09aeff 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -78,6 +78,9 @@
#include <rte_version.h>
#include <rte_atomic.h>
#include <malloc_heap.h>
+#ifdef RTE_LIBRTE_CFGFILE
+#include <rte_cfgfile.h>
+#endif
#include "eal_private.h"
#include "eal_thread.h"
@@ -101,6 +104,8 @@ static struct rte_mem_config early_mem_config;
* duration of the program, as we hold a write lock on it in the primary proc */
static int mem_cfg_fd = -1;
+static int run_once_reset_internal_config;
+
static struct flock wr_lock = {
.l_type = F_WRLCK,
.l_whence = SEEK_SET,
@@ -515,119 +520,135 @@ eal_log_level_parse(int argc, char **argv)
optarg = old_optarg;
}
-/* Parse the argument given in the command line of the application */
+/* Parse single argument */
static int
-eal_parse_args(int argc, char **argv)
+eal_parse_option(int opt, char *optarg, int option_index, char *prgname)
{
- int opt, ret;
- char **argvopt;
- int option_index;
- char *prgname = argv[0];
- const int old_optind = optind;
- const int old_optopt = optopt;
- char * const old_optarg = optarg;
+ int ret;
- argvopt = argv;
- optind = 1;
+ /* getopt is not happy, stop right now */
+ if (opt == '?') {
+ eal_usage(prgname);
+ ret = -1;
+ goto out;
+ }
- while ((opt = getopt_long(argc, argvopt, eal_short_options,
- eal_long_options, &option_index)) != EOF) {
+ ret = eal_parse_common_option(opt, optarg, &internal_config);
+ /* common parser is not happy */
+ if (ret < 0) {
+ eal_usage(prgname);
+ ret = -1;
+ goto out;
+ }
+ /* common parser handled this option */
+ if (ret == 0)
+ return 0;
- /* getopt is not happy, stop right now */
- if (opt == '?') {
+ switch (opt) {
+ case 'h':
+ eal_usage(prgname);
+ exit(EXIT_SUCCESS);
+ break;
+
+ /* long options */
+ case OPT_XEN_DOM0_NUM:
+#ifdef RTE_LIBRTE_XEN_DOM0
+ internal_config.xen_dom0_support = 1;
+ break;
+#else
+ RTE_LOG(ERR, EAL, "Can't support DPDK app "
+ "running on Dom0, please configure"
+ " RTE_LIBRTE_XEN_DOM0=y\n");
+ ret = -1;
+ goto out;
+#endif
+
+ case OPT_HUGE_DIR_NUM:
+ internal_config.hugepage_dir = optarg;
+ break;
+
+ case OPT_FILE_PREFIX_NUM:
+ internal_config.hugefile_prefix = optarg;
+ break;
+
+ case OPT_SOCKET_MEM_NUM:
+ if (eal_parse_socket_mem(optarg) < 0) {
+ RTE_LOG(ERR, EAL, "invalid parameters for --"
+ OPT_SOCKET_MEM "\n");
eal_usage(prgname);
ret = -1;
goto out;
}
+ break;
- ret = eal_parse_common_option(opt, optarg, &internal_config);
- /* common parser is not happy */
- if (ret < 0) {
+ case OPT_BASE_VIRTADDR_NUM:
+ if (eal_parse_base_virtaddr(optarg) < 0) {
+ RTE_LOG(ERR, EAL, "invalid parameter for --"
+ OPT_BASE_VIRTADDR "\n");
eal_usage(prgname);
ret = -1;
goto out;
}
- /* common parser handled this option */
- if (ret == 0)
- continue;
+ break;
- switch (opt) {
- case 'h':
+ case OPT_VFIO_INTR_NUM:
+ if (eal_parse_vfio_intr(optarg) < 0) {
+ RTE_LOG(ERR, EAL, "invalid parameters for --"
+ OPT_VFIO_INTR "\n");
eal_usage(prgname);
- exit(EXIT_SUCCESS);
-
- /* long options */
- case OPT_XEN_DOM0_NUM:
-#ifdef RTE_LIBRTE_XEN_DOM0
- internal_config.xen_dom0_support = 1;
-#else
- RTE_LOG(ERR, EAL, "Can't support DPDK app "
- "running on Dom0, please configure"
- " RTE_LIBRTE_XEN_DOM0=y\n");
ret = -1;
goto out;
-#endif
- break;
+ }
+ break;
- case OPT_HUGE_DIR_NUM:
- internal_config.hugepage_dir = optarg;
- break;
+ case OPT_CREATE_UIO_DEV_NUM:
+ internal_config.create_uio_dev = 1;
+ break;
- case OPT_FILE_PREFIX_NUM:
- internal_config.hugefile_prefix = optarg;
- break;
+ default:
+ if (opt < OPT_LONG_MIN_NUM && isprint(opt)) {
+ RTE_LOG(ERR, EAL, "Option %c is not supported "
+ "on Linux\n", opt);
+ } else if (opt >= OPT_LONG_MIN_NUM &&
+ opt < OPT_LONG_MAX_NUM) {
+ RTE_LOG(ERR, EAL, "Option %s is not supported "
+ "on Linux\n",
+ eal_long_options[option_index].name);
+ } else {
+ RTE_LOG(ERR, EAL, "Option %d is not supported "
+ "on Linux\n", opt);
+ }
+ eal_usage(prgname);
+ ret = -1;
+ goto out;
+ }
- case OPT_SOCKET_MEM_NUM:
- if (eal_parse_socket_mem(optarg) < 0) {
- RTE_LOG(ERR, EAL, "invalid parameters for --"
- OPT_SOCKET_MEM "\n");
- eal_usage(prgname);
- ret = -1;
- goto out;
- }
- break;
+ return 0;
+out:
+ return ret;
+}
- case OPT_BASE_VIRTADDR_NUM:
- if (eal_parse_base_virtaddr(optarg) < 0) {
- RTE_LOG(ERR, EAL, "invalid parameter for --"
- OPT_BASE_VIRTADDR "\n");
- eal_usage(prgname);
- ret = -1;
- goto out;
- }
- break;
+/* Parse the argument given in the command line of the application */
+static int
+eal_parse_args(int argc, char **argv)
+{
+ int opt, ret;
+ char **argvopt;
+ int option_index;
+ char *prgname = argv[0];
+ const int old_optind = optind;
+ const int old_optopt = optopt;
+ char * const old_optarg = optarg;
- case OPT_VFIO_INTR_NUM:
- if (eal_parse_vfio_intr(optarg) < 0) {
- RTE_LOG(ERR, EAL, "invalid parameters for --"
- OPT_VFIO_INTR "\n");
- eal_usage(prgname);
- ret = -1;
- goto out;
- }
- break;
+ argvopt = argv;
+ optind = 1;
- case OPT_CREATE_UIO_DEV_NUM:
- internal_config.create_uio_dev = 1;
- break;
+ while ((opt = getopt_long(argc, argvopt, eal_short_options,
+ eal_long_options, &option_index)) != EOF) {
- default:
- if (opt < OPT_LONG_MIN_NUM && isprint(opt)) {
- RTE_LOG(ERR, EAL, "Option %c is not supported "
- "on Linux\n", opt);
- } else if (opt >= OPT_LONG_MIN_NUM &&
- opt < OPT_LONG_MAX_NUM) {
- RTE_LOG(ERR, EAL, "Option %s is not supported "
- "on Linux\n",
- eal_long_options[option_index].name);
- } else {
- RTE_LOG(ERR, EAL, "Option %d is not supported "
- "on Linux\n", opt);
- }
- eal_usage(prgname);
- ret = -1;
+ ret = eal_parse_option(opt, optarg, option_index, prgname);
+ if (ret < 0)
goto out;
- }
}
if (eal_adjust_config(&internal_config) != 0) {
@@ -774,7 +795,10 @@ rte_eal_init(int argc, char **argv)
thread_id = pthread_self();
- eal_reset_internal_config(&internal_config);
+ if (!run_once_reset_internal_config) {
+ eal_reset_internal_config(&internal_config);
+ run_once_reset_internal_config = 1;
+ }
/* set log level as early as possible */
eal_log_level_parse(argc, argv);
@@ -995,3 +1019,68 @@ rte_eal_check_module(const char *module_name)
/* Module has been found */
return 1;
}
+
+#ifdef RTE_LIBRTE_CFGFILE
+int
+rte_eal_configure(struct rte_cfgfile *cfg, char *prgname)
+{
+ int n_entries;
+ int i;
+ int opt;
+ int option_index;
+
+ if (cfg == NULL) {
+ rte_errno = -EINVAL;
+ return -1;
+ }
+
+ n_entries = rte_cfgfile_section_num_entries(cfg, "DPDK");
+
+ if (n_entries < 1) {
+ printf("No DPDK section entries in cfgfile object\n");
+ return 0;
+ }
+
+ struct rte_cfgfile_entry entries[n_entries];
+
+ if (n_entries !=
+ rte_cfgfile_section_entries(cfg, "DPDK", entries,
+ n_entries)) {
+ rte_eal_init_alert("Unexpected fault.");
+ rte_errno = EFAULT;
+ return -1;
+ }
+
+ if (!run_once_reset_internal_config) {
+ eal_reset_internal_config(&internal_config);
+ run_once_reset_internal_config = 1;
+ }
+
+ /* set log level as early as possible */
+ eal_log_level_cfg(cfg);
+
+ if (rte_eal_cpu_init() < 0) {
+ rte_eal_init_alert("Cannot detect lcores.");
+ rte_errno = ENOTSUP;
+ return -1;
+ }
+
+ for (i = 0; i < n_entries; i++) {
+ eal_getopt(entries[i].name, &opt, &option_index);
+
+ if (eal_parse_option(opt, entries[i].value,
+ option_index, prgname) != 0) {
+ rte_eal_init_alert("Invalid config file arguments.");
+ rte_errno = EINVAL;
+ return -1;
+ }
+ }
+
+ if (parse_vdev_devices(cfg) < 0) {
+ rte_eal_init_alert("Couldn't parse vdevs");
+ rte_errno = ENOMEM;
+ return -1;
+ }
+ return 0;
+}
+#endif
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 0f9e009..d206fd3 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -205,6 +205,7 @@ DPDK_17.08 {
rte_bus_find;
rte_bus_find_by_device;
rte_bus_find_by_name;
+ rte_eal_configure;
} DPDK_17.05;
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index e239581..6c1b508 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -81,7 +81,6 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_POWER) += -lrte_power
_LDLIBS-$(CONFIG_RTE_LIBRTE_TIMER) += -lrte_timer
_LDLIBS-$(CONFIG_RTE_LIBRTE_EFD) += -lrte_efd
-_LDLIBS-$(CONFIG_RTE_LIBRTE_CFGFILE) += -lrte_cfgfile
_LDLIBS-y += --whole-archive
@@ -97,6 +96,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += -lrte_mempool
_LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING) += -lrte_mempool_ring
_LDLIBS-$(CONFIG_RTE_LIBRTE_RING) += -lrte_ring
_LDLIBS-$(CONFIG_RTE_LIBRTE_EAL) += -lrte_eal
+_LDLIBS-$(CONFIG_RTE_LIBRTE_CFGFILE) += -lrte_cfgfile
_LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE) += -lrte_cmdline
_LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER) += -lrte_reorder
--
2.7.4
^ permalink raw reply [flat|nested] 2+ messages in thread
* [dpdk-dev] [PATCH v5 0/3] EAL change for using a config file for DPDK
2017-07-10 12:51 [dpdk-dev] [PATCH v4 1/3] eal: add functions parsing EAL arguments Kuba Kozak
@ 2017-07-13 10:07 ` Kuba Kozak
2017-07-13 10:07 ` [dpdk-dev] [PATCH v5 3/3] app/testpmd: add parse options from JSON cfg file Kuba Kozak
0 siblings, 1 reply; 2+ messages in thread
From: Kuba Kozak @ 2017-07-13 10:07 UTC (permalink / raw)
To: dev
Cc: deepak.k.jain, bruce.richardson, michalx.k.jastrzebski,
jacekx.piasecki, Kuba Kozak
This patchset introduce a mechanism for running dpdk application with
parameters provided by configuration file.
A new API for EAL takes a config file data type - either loaded from
file, or built up programmatically in the application - and extracts
DPDK parameters from it to be used when eal init is called.
This allows apps to have an alternative method to configure EAL,
other than via command-line parameters.
Reworked applications are used to demonstrate the new eal API.
If a --cfgfile-path <path> option is passed into command line non
EAL section, then the file is loaded and used by app. If a file
called config.ini is present in current working directory, and
no --cfgfile-path option is passed in, config.ini file will be
loaded and used by app.
Patch "app/testpmd: add parse options from JSON cfg file"
demonstrates the usage of JSON instead of INI file format.
JSON file can be called the same way as above,
through --cfgfile-path <path> argument.
---
this patch depends on:
"Rework cfgfile API to enable apps config file support"
v5:
changed define "RTE_DEVTYPE_VIRTUAL" to "RTE_DEVTYPE_UNDEFINED"
due to compilation errors (changes on current master).
v4:
Code optimalisation in parse_vdev_devices() function.
Moved some functions from librte_eal/bsdapp and librte_eal/linuxapp
to the librte_eal/common.
Bug fixes.
v3:
split one patchset into two distinct patchsets:
1. cfgfile library and TEST app changes
2. EAL changes and examples (this patchset depends on cfgfile)
v2:
lib eal:
Rework of rte_eal_configure(struct rte_cfgfile *cfg, char *prgname).
Now this function load data from cfg structure and did initial
initialization of EAL arguments. Vdev argument are stored in different
subsections eg. DPDK.vdev0, DPDK.vdev1 etc. After execution of this
function it is necessary to call rte_eal_init to complete EAL
initialization. There is no more merging arguments from different
sources (cfg file and command line).
Added non_eal_configure to testpmd application.
Function maintain the same functionality as rte_eal_configure but
for non-eal arguments.
Added config JSON feature to testpmd last patch from patchset contain
example showing use of .json configuration files.
lib cfgfile:
Rework of add_section(), add_entry() new implementation
New members allocated_entries/sections, free_entries/sections
in rte_cfgfile structure, change in array of pointers
**sections, **entries instead of *sections[], *entries[]
Add set_entry() to update/overwrite already existing entry in cfgfile
struct
Add save() function to save on disc cfgfile structure in INI format
Rework of existing load() function simplifying the code
Add unit test realloc_sections() in TEST app for testing realloc/malloc
of new API functions, add test for save() function
Kuba Kozak (3):
eal: add functions parsing EAL arguments
app/testpmd: add parse options from cfg file
app/testpmd: add parse options from JSON cfg file
app/test-pmd/Makefile | 6 +
app/test-pmd/config.ini | 24 +
app/test-pmd/config.json | 33 +
app/test-pmd/parameters.c | 1181 +++++++++++++----------
app/test-pmd/testpmd.c | 159 ++-
app/test-pmd/testpmd.h | 3 +-
config/common_base | 5 +
lib/Makefile | 3 +
lib/librte_eal/bsdapp/eal/Makefile | 4 +
lib/librte_eal/bsdapp/eal/eal.c | 165 +++-
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 +
lib/librte_eal/common/eal_common_lcore.c | 7 +
lib/librte_eal/common/eal_common_options.c | 106 ++
lib/librte_eal/common/eal_options.h | 3 +
lib/librte_eal/common/include/rte_eal.h | 20 +
lib/librte_eal/linuxapp/eal/Makefile | 3 +
lib/librte_eal/linuxapp/eal/eal.c | 265 +++--
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 +
mk/rte.app.mk | 2 +-
19 files changed, 1349 insertions(+), 642 deletions(-)
create mode 100644 app/test-pmd/config.ini
create mode 100644 app/test-pmd/config.json
--
2.7.4
^ permalink raw reply [flat|nested] 2+ messages in thread
* [dpdk-dev] [PATCH v5 3/3] app/testpmd: add parse options from JSON cfg file
2017-07-13 10:07 ` [dpdk-dev] [PATCH v5 0/3] EAL change for using a config file for DPDK Kuba Kozak
@ 2017-07-13 10:07 ` Kuba Kozak
0 siblings, 0 replies; 2+ messages in thread
From: Kuba Kozak @ 2017-07-13 10:07 UTC (permalink / raw)
To: dev
Cc: deepak.k.jain, bruce.richardson, michalx.k.jastrzebski,
jacekx.piasecki, Kuba Kozak
This patch shows usage of Jansson library to parse
application arguments from JSON config file.
https://github.com/akheron/jansson
If a --cfgfile-path <path> option is passed into commandline
non EAL section, then the disired JSON file is loaded and used
by app. In case when JSON doesn't exist an INI file is loaded.
The INI file can be passed also from --cfgfile-path option.
If a file called config.ini is present in current working
directory, and no --cfgfile-path option is passed in, config.ini
file will be loaded and used by app.
Signed-off-by: Kuba Kozak <kubax.kozak@intel.com>
Suggested-by: Bruce Richardson <bruce.richardson@intel.com>
---
app/test-pmd/Makefile | 6 ++++
app/test-pmd/config.json | 33 +++++++++++++++++
app/test-pmd/testpmd.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++-
config/common_base | 5 +++
4 files changed, 137 insertions(+), 1 deletion(-)
create mode 100644 app/test-pmd/config.json
diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
index c36be19..a1c84cc 100644
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -83,6 +83,12 @@ endif
endif
+ifeq ($(CONFIG_RTE_JSON_SUPPORT),y)
+ifeq ($(CONFIG_RTE_LIBRTE_CFGFILE),y)
+LDLIBS += -ljansson
+endif
+endif
+
CFLAGS_cmdline.o := -D_GNU_SOURCE
include $(RTE_SDK)/mk/rte.app.mk
diff --git a/app/test-pmd/config.json b/app/test-pmd/config.json
new file mode 100644
index 0000000..4589dbc
--- /dev/null
+++ b/app/test-pmd/config.json
@@ -0,0 +1,33 @@
+{
+ "DPDK":
+ {
+ "v": "",
+ "l": "0-4",
+ "n": "4",
+ "master-lcore": "0",
+ "proc-type": "primary"
+ },
+ "TEST-PMD":
+ {
+ "i": "",
+ "portmask": "0xff",
+ "nb-cores": "4",
+ "port-topology": "paired"
+ },
+ "DPDK.vdev0":
+ {
+ "net_ring0": ""
+ },
+ "DPDK.vdev1":
+ {
+ "net_ring1": ""
+ },
+ "DPDK.vdev2":
+ {
+ "net_ring2": ""
+ },
+ "DPDK.vdev3":
+ {
+ "net_ring3": ""
+ }
+}
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 7b82976..014bb46 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -46,6 +46,10 @@
#include <stdint.h>
#include <unistd.h>
+
+#ifdef RTE_JSON_SUPPORT
+#include <jansson.h>
+#endif
#include <inttypes.h>
#include <rte_common.h>
@@ -2290,6 +2294,87 @@ cfgfile_load_path(int argc, char **argv)
}
return NULL;
}
+
+#ifdef RTE_JSON_SUPPORT
+/*
+ * Decoding JSON structure to rte_cfgfile structure.
+ * Returns handler to cfgfile object, NULL if error.
+ */
+static struct
+rte_cfgfile *l3fwd_json_to_cfg(json_t *json, int flags)
+{
+ if (!json) {
+ printf("Error: JSON structure is NULL, nothing to parse\n");
+ return NULL;
+ }
+ /* create an empty instance of cfgfile structure */
+ struct rte_cfgfile *cfgfile = rte_cfgfile_create(flags);
+
+ if (!cfgfile)
+ return NULL;
+
+ const char *section;
+ json_t *entry;
+
+ /* set pointer to first section */
+ void *iter_section = json_object_iter(json);
+
+ while (iter_section) {
+
+ section = json_object_iter_key(iter_section);
+ entry = json_object_iter_value(iter_section);
+
+ /* add parsed section name of current section to cfgfile */
+ rte_cfgfile_add_section(cfgfile, section);
+
+ /* set pointer to first entry */
+ void *iter_entry = json_object_iter(entry);
+
+ while (iter_entry) {
+
+ const char *key;
+ const char *value;
+
+ key = json_object_iter_key(iter_entry);
+ value = json_string_value(
+ json_object_iter_value(iter_entry));
+
+ /* add parsed key and value of current entry */
+ /* to cfgfile */
+ rte_cfgfile_add_entry(cfgfile, section, key, value);
+
+ /* pointer to next entry */
+ iter_entry = json_object_iter_next(entry, iter_entry);
+ }
+ /* pointer to next section */
+ iter_section = json_object_iter_next(json, iter_section);
+ }
+ return cfgfile;
+}
+
+/*
+ * Check presence and load JSON file to rte_cfgfile structure.
+ * Returns handler to cfgfile object, NULL if error.
+ */
+static struct
+rte_cfgfile *l3fwd_load_json_to_cfg(const char *path)
+{
+ struct rte_cfgfile *cfgfile = NULL;
+ /* check if config file exist */
+ if (access(path, F_OK) != -1) {
+ /* parse JSON file */
+ json_error_t error;
+ json_t *json = json_load_file(path, 0, &error);
+
+ if (json)
+ cfgfile = l3fwd_json_to_cfg(json, 0);
+ else
+ fprintf(stderr, "JSON error on line %d: %s\n",
+ error.line, error.text);
+ }
+ return cfgfile;
+}
+#endif
#endif
#define APP_NAME "TEST-PMD"
@@ -2318,9 +2403,16 @@ main(int argc, char** argv)
"in default directory)\n");
config_file = strdup("config.ini");
}
-
+#ifndef RTE_JSON_SUPPORT
cfg = rte_cfgfile_load(config_file, CFG_FLAG_EMPTY_VALUES);
+#endif
+#ifdef RTE_JSON_SUPPORT
+ if (strstr(config_file, ".ini"))
+ cfg = rte_cfgfile_load(config_file, CFG_FLAG_EMPTY_VALUES);
+ else if (strstr(config_file, ".json"))
+ cfg = l3fwd_load_json_to_cfg(config_file);
+#endif
if (cfg == NULL) {
printf("Info: Valid cfgfile not found\n");
} else {
diff --git a/config/common_base b/config/common_base
index 8ae6e92..98e8fa2 100644
--- a/config/common_base
+++ b/config/common_base
@@ -744,3 +744,8 @@ CONFIG_RTE_APP_CRYPTO_PERF=y
# Compile the eventdev application
#
CONFIG_RTE_APP_EVENTDEV=y
+
+#
+# Compile JSON support
+#
+CONFIG_RTE_JSON_SUPPORT=n
\ No newline at end of file
--
2.7.4
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2018-05-16 14:07 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-16 14:07 [dpdk-dev] [PATCH v5 3/3] app/testpmd: add parse options from JSON cfg file Iremonger, Bernard
-- strict thread matches above, loose matches on Subject: below --
2017-07-10 12:51 [dpdk-dev] [PATCH v4 1/3] eal: add functions parsing EAL arguments Kuba Kozak
2017-07-13 10:07 ` [dpdk-dev] [PATCH v5 0/3] EAL change for using a config file for DPDK Kuba Kozak
2017-07-13 10:07 ` [dpdk-dev] [PATCH v5 3/3] app/testpmd: add parse options from JSON cfg file Kuba Kozak
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).