aboutsummaryrefslogtreecommitdiff
path: root/platform/linux-generic
diff options
context:
space:
mode:
authorMatias Elo <matias.elo@nokia.com>2018-02-21 17:19:12 +0200
committerMaxim Uvarov <maxim.uvarov@linaro.org>2018-03-06 19:31:28 +0300
commit534667daec58ce8b2e417709e788934bea6f8f09 (patch)
tree2bb72f5d120817e516e97cdac56c00e2d9729e49 /platform/linux-generic
parentf3cf9c3583364af7625679d0021c4d55c3414994 (diff)
linux-gen: add runtime configuration file
Enables changing ODP runtime configuration options by using an optional configuration file (libconfig). Path to the conf file is passed using environment variable ODP_CONF_FILE. If ODP_CONF_FILE or a particular option is not set, hardcoded default values are used instead. An template configuration file is provided in config/odp-linux.conf. Runtime configuration is initially used by DPDK pktio to set NIC options. Adds new dependency to libconfig library. Signed-off-by: Matias Elo <matias.elo@nokia.com> Reviewed-by: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org> Reviewed-by: Bill Fischofer <bill.fischofer@linaro.org> Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
Diffstat (limited to 'platform/linux-generic')
-rw-r--r--platform/linux-generic/.gitignore1
-rw-r--r--platform/linux-generic/Makefile.am13
-rw-r--r--platform/linux-generic/include/odp_internal.h5
-rw-r--r--platform/linux-generic/include/odp_libconfig_internal.h29
-rw-r--r--platform/linux-generic/include/odp_packet_dpdk.h10
-rw-r--r--platform/linux-generic/libodp-linux.pc.in1
-rw-r--r--platform/linux-generic/m4/configure.m41
-rw-r--r--platform/linux-generic/odp_init.c14
-rw-r--r--platform/linux-generic/odp_libconfig.c99
-rw-r--r--platform/linux-generic/pktio/dpdk.c73
-rw-r--r--platform/linux-generic/test/ring/Makefile.am2
11 files changed, 243 insertions, 5 deletions
diff --git a/platform/linux-generic/.gitignore b/platform/linux-generic/.gitignore
index fd5ade7e3..16e788a90 100644
--- a/platform/linux-generic/.gitignore
+++ b/platform/linux-generic/.gitignore
@@ -1 +1,2 @@
libodp-linux.pc
+odp_libconfig_config.h
diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am
index c35c0bfe3..7e57994d1 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -5,6 +5,7 @@ include $(top_srcdir)/platform/Makefile.inc
AM_CPPFLAGS = $(ODP_INCLUDES)
AM_CPPFLAGS += -I$(top_srcdir)/platform/$(with_platform)/include
+AM_CPPFLAGS += -I$(top_builddir)/platform/$(with_platform)/include
AM_CPPFLAGS += -I$(top_srcdir)/platform/$(with_platform)/arch
AM_CPPFLAGS += -I$(top_srcdir)/platform/$(with_platform)/arch/@ARCH_DIR@
AM_CPPFLAGS += -I$(top_srcdir)/platform/$(with_platform)/arch/default
@@ -13,6 +14,12 @@ AM_CPPFLAGS += $(OPENSSL_CPPFLAGS)
AM_CPPFLAGS += $(DPDK_CPPFLAGS)
AM_CPPFLAGS += $(NETMAP_CPPFLAGS)
+AM_CFLAGS += $(LIBCONFIG_CFLAGS)
+
+DISTCLEANFILES = include/odp_libconfig_config.h
+include/odp_libconfig_config.h: $(top_srcdir)/config/odp-$(with_platform).conf $(top_builddir)/config.status
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+
if !ODP_ABI_COMPAT
odpapiplatincludedir= $(includedir)/odp/api/plat
odpapiplatinclude_HEADERS = \
@@ -94,6 +101,7 @@ noinst_HEADERS = \
include/odp_forward_typedefs_internal.h \
include/odp_internal.h \
include/odp_ipsec_internal.h \
+ include/odp_libconfig_internal.h \
include/odp_llqueue.h \
include/odp_macros_internal.h \
include/odp_name_table_internal.h \
@@ -131,6 +139,9 @@ noinst_HEADERS = \
include/protocols/thash.h \
include/protocols/udp.h
+nodist_noinst_HEADERS = \
+ include/odp_libconfig_config.h
+
__LIB__libodp_linux_la_SOURCES = \
_fdserver.c \
_ishm.c \
@@ -154,6 +165,7 @@ __LIB__libodp_linux_la_SOURCES = \
odp_ipsec.c \
odp_ipsec_events.c \
odp_ipsec_sad.c \
+ odp_libconfig.c \
odp_name_table.c \
odp_packet.c \
odp_packet_flags.c \
@@ -287,6 +299,7 @@ endif
__LIB__libodp_linux_la_LIBADD = $(ATOMIC_LIBS)
__LIB__libodp_linux_la_LIBADD += $(OPENSSL_LIBS)
+__LIB__libodp_linux_la_LIBADD += $(LIBCONFIG_LIBS)
__LIB__libodp_linux_la_LIBADD += $(DPDK_LIBS_LIBODP)
__LIB__libodp_linux_la_LIBADD += $(PTHREAD_LIBS)
__LIB__libodp_linux_la_LIBADD += $(TIMER_LIBS)
diff --git a/platform/linux-generic/include/odp_internal.h b/platform/linux-generic/include/odp_internal.h
index ff8e4176f..153c787e3 100644
--- a/platform/linux-generic/include/odp_internal.h
+++ b/platform/linux-generic/include/odp_internal.h
@@ -23,6 +23,7 @@ extern "C" {
#include <odp_errno_define.h>
#include <stdio.h>
#include <sys/types.h>
+#include <libconfig.h>
#define MAX_CPU_NUMBER 128
#define UID_MAXLEN 30
@@ -55,10 +56,14 @@ struct odp_global_data_s {
odp_cpumask_t control_cpus;
odp_cpumask_t worker_cpus;
int num_cpus_installed;
+ config_t libconfig_default;
+ config_t libconfig_runtime;
+
};
enum init_stage {
NO_INIT = 0, /* No init stages completed */
+ LIBCONFIG_INIT,
CPUMASK_INIT,
TIME_INIT,
SYSINFO_INIT,
diff --git a/platform/linux-generic/include/odp_libconfig_internal.h b/platform/linux-generic/include/odp_libconfig_internal.h
new file mode 100644
index 000000000..042917755
--- /dev/null
+++ b/platform/linux-generic/include/odp_libconfig_internal.h
@@ -0,0 +1,29 @@
+/* Copyright (c) 2018, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * Common libconfig functions
+ */
+
+#ifndef ODP_LIBCONFIG_INTERNAL_H_
+#define ODP_LIBCONFIG_INTERNAL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int _odp_libconfig_init_global(void);
+int _odp_libconfig_term_global(void);
+
+int _odp_libconfig_lookup_int(const char *path, int *value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/include/odp_packet_dpdk.h b/platform/linux-generic/include/odp_packet_dpdk.h
index 94fe376a8..7600b57e7 100644
--- a/platform/linux-generic/include/odp_packet_dpdk.h
+++ b/platform/linux-generic/include/odp_packet_dpdk.h
@@ -21,8 +21,6 @@
#define DPDK_NB_MBUF 16384
#define DPDK_MBUF_BUF_SIZE RTE_MBUF_DEFAULT_BUF_SIZE
#define DPDK_MEMPOOL_CACHE_SIZE 64
-#define DPDK_NM_RX_DESC 128
-#define DPDK_NM_TX_DESC 512
ODP_STATIC_ASSERT((DPDK_NB_MBUF % DPDK_MEMPOOL_CACHE_SIZE == 0) &&
(DPDK_MEMPOOL_CACHE_SIZE <= RTE_MEMPOOL_CACHE_MAX_SIZE) &&
@@ -33,6 +31,13 @@ ODP_STATIC_ASSERT((DPDK_NB_MBUF % DPDK_MEMPOOL_CACHE_SIZE == 0) &&
/* Minimum RX burst size */
#define DPDK_MIN_RX_BURST 4
+/** DPDK runtime configuration options */
+typedef struct {
+ int num_rx_desc;
+ int num_tx_desc;
+ int rx_drop_en;
+} dpdk_opt_t;
+
/** Cache for storing packets */
struct pkt_cache_t {
/** array for storing extra RX packets */
@@ -64,6 +69,7 @@ typedef struct ODP_ALIGNED_CACHE {
odp_ticketlock_t tx_lock[PKTIO_MAX_QUEUES]; /**< TX queue locks */
/** cache for storing extra RX packets */
pkt_cache_t rx_cache[PKTIO_MAX_QUEUES];
+ dpdk_opt_t opt;
} pkt_dpdk_t;
#endif
diff --git a/platform/linux-generic/libodp-linux.pc.in b/platform/linux-generic/libodp-linux.pc.in
index 5125f83ad..66ac78f0b 100644
--- a/platform/linux-generic/libodp-linux.pc.in
+++ b/platform/linux-generic/libodp-linux.pc.in
@@ -6,6 +6,7 @@ includedir=@includedir@
Name: libodp-linux
Description: The ODP packet processing engine
Version: @PKGCONFIG_VERSION@
+Requires.private: libconfig
Libs: -L${libdir} -lodp-linux
Libs.private: @OPENSSL_STATIC_LIBS@ @DPDK_LIBS@ @PCAP_LIBS@ @PTHREAD_LIBS@ @TIMER_LIBS@ -lpthread @ATOMIC_LIBS@
Cflags: -I${includedir}
diff --git a/platform/linux-generic/m4/configure.m4 b/platform/linux-generic/m4/configure.m4
index 7fa3652e2..d2ddd495e 100644
--- a/platform/linux-generic/m4/configure.m4
+++ b/platform/linux-generic/m4/configure.m4
@@ -6,6 +6,7 @@ ODP_ATOMIC
ODP_PTHREAD
ODP_TIMER
ODP_OPENSSL
+ODP_LIBCONFIG
m4_include([platform/linux-generic/m4/odp_pcap.m4])
m4_include([platform/linux-generic/m4/odp_netmap.m4])
m4_include([platform/linux-generic/m4/odp_dpdk.m4])
diff --git a/platform/linux-generic/odp_init.c b/platform/linux-generic/odp_init.c
index 19003b6a2..0cd66ca3d 100644
--- a/platform/linux-generic/odp_init.c
+++ b/platform/linux-generic/odp_init.c
@@ -12,6 +12,7 @@
#include <unistd.h>
#include <odp_internal.h>
#include <odp_schedule_if.h>
+#include <odp_libconfig_internal.h>
#include <string.h>
#include <stdio.h>
#include <linux/limits.h>
@@ -48,6 +49,12 @@ int odp_init_global(odp_instance_t *instance,
odp_global_data.abort_fn = params->abort_fn;
}
+ if (_odp_libconfig_init_global()) {
+ ODP_ERR("ODP runtime config init failed.\n");
+ goto init_failed;
+ }
+ stage = LIBCONFIG_INIT;
+
if (odp_cpumask_init_global(params)) {
ODP_ERR("ODP cpumask init failed.\n");
goto init_failed;
@@ -306,6 +313,13 @@ int _odp_term_global(enum init_stage stage)
}
/* Fall through */
+ case LIBCONFIG_INIT:
+ if (_odp_libconfig_term_global()) {
+ ODP_ERR("ODP runtime config term failed.\n");
+ rc = -1;
+ }
+ /* Fall through */
+
case NO_INIT:
;
}
diff --git a/platform/linux-generic/odp_libconfig.c b/platform/linux-generic/odp_libconfig.c
new file mode 100644
index 000000000..3b3b31703
--- /dev/null
+++ b/platform/linux-generic/odp_libconfig.c
@@ -0,0 +1,99 @@
+/* Copyright (c) 2018, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <libconfig.h>
+
+#include <odp/api/version.h>
+#include <odp_internal.h>
+#include <odp_debug_internal.h>
+#include <odp_libconfig_internal.h>
+#include <odp_libconfig_config.h>
+
+#define CONF_STR_NAME ((const char *)odp_linux_generic_conf)
+
+extern struct odp_global_data_s odp_global_data;
+
+int _odp_libconfig_init_global(void)
+{
+ const char *filename;
+ const char *vers;
+ const char *vers_rt;
+ const char *ipml;
+ const char *ipml_rt;
+ config_t *config = &odp_global_data.libconfig_default;
+ config_t *config_rt = &odp_global_data.libconfig_runtime;
+
+ config_init(config);
+ config_init(config_rt);
+
+ if (!config_read_string(config, CONF_STR_NAME)) {
+ ODP_ERR("Failed to read default config: %s(%d): %s\n",
+ config_error_file(config), config_error_line(config),
+ config_error_text(config));
+ goto fail;
+ }
+
+ filename = getenv("ODP_CONFIG_FILE");
+ if (filename == NULL)
+ return 0;
+
+ if (!config_read_file(config_rt, filename)) {
+ ODP_ERR("Failed to read config file: %s(%d): %s\n",
+ config_error_file(config_rt),
+ config_error_line(config_rt),
+ config_error_text(config_rt));
+ goto fail;
+ }
+
+ /* Check runtime configuration's implementation name and version */
+ if (!config_lookup_string(config, "odp_implementation", &ipml) ||
+ !config_lookup_string(config_rt, "odp_implementation", &ipml_rt)) {
+ ODP_ERR("Configuration missing 'odp_implementation' field\n");
+ goto fail;
+ }
+ if (!config_lookup_string(config, "config_file_version", &vers) ||
+ !config_lookup_string(config_rt, "config_file_version", &vers_rt)) {
+ ODP_ERR("Configuration missing 'config_file_version' field\n");
+ goto fail;
+ }
+ if (strcmp(vers, vers_rt) || strcmp(ipml, ipml_rt)) {
+ ODP_ERR("Runtime configuration mismatch\n");
+ goto fail;
+ }
+
+ return 0;
+fail:
+ config_destroy(config);
+ config_destroy(config_rt);
+ return -1;
+}
+
+int _odp_libconfig_term_global(void)
+{
+ config_destroy(&odp_global_data.libconfig_default);
+ config_destroy(&odp_global_data.libconfig_runtime);
+
+ return 0;
+}
+
+int _odp_libconfig_lookup_int(const char *path, int *value)
+{
+ int ret_def = CONFIG_FALSE;
+ int ret_rt = CONFIG_FALSE;
+
+ ret_def = config_lookup_int(&odp_global_data.libconfig_default, path,
+ value);
+
+ /* Runtime option overrides default value */
+ ret_rt = config_lookup_int(&odp_global_data.libconfig_runtime, path,
+ value);
+
+ return (ret_def == CONFIG_TRUE || ret_rt == CONFIG_TRUE) ? 1 : 0;
+}
diff --git a/platform/linux-generic/pktio/dpdk.c b/platform/linux-generic/pktio/dpdk.c
index a31b0dbbc..7b9fed72d 100644
--- a/platform/linux-generic/pktio/dpdk.c
+++ b/platform/linux-generic/pktio/dpdk.c
@@ -24,6 +24,7 @@
#include <odp_classification_internal.h>
#include <odp_packet_dpdk.h>
#include <odp_debug_internal.h>
+#include <odp_libconfig_internal.h>
#include <protocols/eth.h>
@@ -93,6 +94,64 @@ void refer_constructors(void)
}
#endif
+static int lookup_opt(const char *path, const char *drv_name, int *val)
+{
+ const char *base = "pktio_dpdk";
+ char opt_path[256];
+ int ret = 0;
+
+ /* Default option */
+ snprintf(opt_path, sizeof(opt_path), "%s.%s", base, path);
+ ret += _odp_libconfig_lookup_int(opt_path, val);
+
+ /* Driver specific option overrides default option */
+ snprintf(opt_path, sizeof(opt_path), "%s.%s.%s", base, drv_name, path);
+ ret += _odp_libconfig_lookup_int(opt_path, val);
+
+ if (ret == 0)
+ ODP_ERR("Unable to find DPDK configuration option: %s\n", path);
+ return ret;
+}
+
+static int init_options(pktio_entry_t *pktio_entry,
+ const struct rte_eth_dev_info *dev_info)
+{
+ dpdk_opt_t *opt = &pktio_entry->s.pkt_dpdk.opt;
+
+ if (!lookup_opt("num_rx_desc", dev_info->driver_name,
+ &opt->num_rx_desc))
+ return -1;
+ if (opt->num_rx_desc < dev_info->rx_desc_lim.nb_min ||
+ opt->num_rx_desc > dev_info->rx_desc_lim.nb_max ||
+ opt->num_rx_desc % dev_info->rx_desc_lim.nb_align) {
+ ODP_ERR("Invalid number of RX descriptors\n");
+ return -1;
+ }
+
+ if (!lookup_opt("num_tx_desc", dev_info->driver_name,
+ &opt->num_tx_desc))
+ return -1;
+ if (opt->num_tx_desc < dev_info->tx_desc_lim.nb_min ||
+ opt->num_tx_desc > dev_info->tx_desc_lim.nb_max ||
+ opt->num_tx_desc % dev_info->tx_desc_lim.nb_align) {
+ ODP_ERR("Invalid number of TX descriptors\n");
+ return -1;
+ }
+
+ if (!lookup_opt("rx_drop_en", dev_info->driver_name,
+ &opt->rx_drop_en))
+ return -1;
+ opt->rx_drop_en = !!opt->rx_drop_en;
+
+ ODP_PRINT("DPDK interface (%s): %" PRIu16 "\n", dev_info->driver_name,
+ pktio_entry->s.pkt_dpdk.port_id);
+ ODP_PRINT(" num_rx_desc: %d\n", opt->num_rx_desc);
+ ODP_PRINT(" num_tx_desc: %d\n", opt->num_tx_desc);
+ ODP_PRINT(" rx_drop_en: %d\n", opt->rx_drop_en);
+
+ return 0;
+}
+
/**
* Calculate valid cache size for DPDK packet pool
*/
@@ -1337,6 +1396,12 @@ static int dpdk_open(odp_pktio_t id ODP_UNUSED,
dpdk_init_capability(pktio_entry, &dev_info);
+ /* Initialize runtime options */
+ if (init_options(pktio_entry, &dev_info)) {
+ ODP_ERR("Initializing runtime options failed\n");
+ return -1;
+ }
+
mtu = dpdk_mtu_get(pktio_entry);
if (mtu == 0) {
ODP_ERR("Failed to read interface MTU\n");
@@ -1464,7 +1529,8 @@ static int dpdk_start(pktio_entry_t *pktio_entry)
pktio_entry->s.chksum_insert_ena = 1;
}
- ret = rte_eth_tx_queue_setup(port_id, i, DPDK_NM_TX_DESC,
+ ret = rte_eth_tx_queue_setup(port_id, i,
+ pkt_dpdk->opt.num_tx_desc,
rte_eth_dev_socket_id(port_id),
txconf);
if (ret < 0) {
@@ -1476,9 +1542,10 @@ static int dpdk_start(pktio_entry_t *pktio_entry)
/* Init RX queues */
rte_eth_dev_info_get(port_id, &dev_info);
rxconf = &dev_info.default_rxconf;
- rxconf->rx_drop_en = 1;
+ rxconf->rx_drop_en = pkt_dpdk->opt.rx_drop_en;
for (i = 0; i < pktio_entry->s.num_in_queue; i++) {
- ret = rte_eth_rx_queue_setup(port_id, i, DPDK_NM_RX_DESC,
+ ret = rte_eth_rx_queue_setup(port_id, i,
+ pkt_dpdk->opt.num_rx_desc,
rte_eth_dev_socket_id(port_id),
rxconf, pkt_dpdk->pkt_pool);
if (ret < 0) {
diff --git a/platform/linux-generic/test/ring/Makefile.am b/platform/linux-generic/test/ring/Makefile.am
index 3f774342e..999beed4f 100644
--- a/platform/linux-generic/test/ring/Makefile.am
+++ b/platform/linux-generic/test/ring/Makefile.am
@@ -16,6 +16,8 @@ PRELDADD += $(LIBCUNIT_COMMON)
AM_CPPFLAGS += -I$(top_srcdir)/platform/linux-generic/include
+AM_CFLAGS += $(LIBCONFIG_CFLAGS)
+
TESTNAME = linux-generic-ring
TESTENV = tests-$(TESTNAME).env