summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Millescamps <damien.millescamps@6wind.com>2013-06-12 09:51:27 +0200
committerThomas Monjalon <thomas.monjalon@6wind.com>2013-09-17 14:16:11 +0200
commit02f061016768aa2d7d878f0ccb8de68c96b431f7 (patch)
treec91cad332fb42ee7517cc3ca648908b6ad5f3072
parent0dd1c9eb4769a20e834585926afed1eca05ececf (diff)
downloaddpdk-02f061016768aa2d7d878f0ccb8de68c96b431f7.zip
dpdk-02f061016768aa2d7d878f0ccb8de68c96b431f7.tar.gz
dpdk-02f061016768aa2d7d878f0ccb8de68c96b431f7.tar.xz
eal: add support for shared object drivers
Add an option to specify libraries to be loaded before probing the PCI. For instance, testpmd -d librte_pmd_xxx.so can be used to enable xxx driver support on testpmd without any recompilation of testpmd. Plugins are loaded before creating threads because we want the threads to inherit any property that could be set while loading a plugin, such as iopl(). Signed-off-by: Damien Millescamps <damien.millescamps@6wind.com> Signed-off-by: Jean-Mickael Guerin <jean-mickael.guerin@6wind.com> Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
-rw-r--r--lib/librte_eal/linuxapp/eal/eal.c53
-rw-r--r--mk/exec-env/linuxapp/rte.vars.mk7
2 files changed, 55 insertions, 5 deletions
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 9ba3d1d..7c14d87 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -2,6 +2,7 @@
* BSD LICENSE
*
* Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
+ * Copyright(c) 2012-2013 6WIND S.A.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,6 +43,8 @@
#include <syslog.h>
#include <getopt.h>
#include <sys/file.h>
+#include <fcntl.h>
+#include <dlfcn.h>
#include <stddef.h>
#include <errno.h>
#include <limits.h>
@@ -108,6 +111,21 @@
/* Allow the application to print its usage message too if set */
static rte_usage_hook_t rte_application_usage_hook = NULL;
+
+TAILQ_HEAD(shared_driver_list, shared_driver);
+
+/* Definition for shared object drivers. */
+struct shared_driver {
+ TAILQ_ENTRY(shared_driver) next;
+
+ char name[PATH_MAX];
+ void* lib_handle;
+};
+
+/* List of external loadable drivers */
+static struct shared_driver_list solib_list =
+TAILQ_HEAD_INITIALIZER(solib_list);
+
/* early configuration structure, when memory config is not mmapped */
static struct rte_mem_config early_mem_config;
@@ -321,6 +339,7 @@ eal_usage(const char *prgname)
" -c COREMASK : A hexadecimal bitmask of cores to run on\n"
" -n NUM : Number of memory channels\n"
" -v : Display version information on startup\n"
+ " -d LIB.so : add driver (can be used multiple times)\n"
" -b <domain:bus:devid.func>: to prevent EAL from using specified "
"PCI device\n"
" (multiple -b options are allowed)\n"
@@ -568,6 +587,7 @@ eal_parse_args(int argc, char **argv)
{OPT_SYSLOG, 1, NULL, 0},
{0, 0, 0, 0}
};
+ struct shared_driver *solib;
argvopt = argv;
@@ -593,7 +613,7 @@ eal_parse_args(int argc, char **argv)
internal_config.vmware_tsc_map = 0;
- while ((opt = getopt_long(argc, argvopt, "b:c:m:n:r:v",
+ while ((opt = getopt_long(argc, argvopt, "b:c:d:m:n:r:v",
lgopts, &option_index)) != EOF) {
switch (opt) {
@@ -614,6 +634,18 @@ eal_parse_args(int argc, char **argv)
}
coremask_ok = 1;
break;
+ /* force loading of external driver */
+ case 'd':
+ solib = malloc(sizeof(*solib));
+ if (solib == NULL) {
+ RTE_LOG(ERR, EAL, "malloc(solib) failed\n");
+ return -1;
+ }
+ memset(solib, 0, sizeof(*solib));
+ strncpy(solib->name, optarg, PATH_MAX-1);
+ solib->name[PATH_MAX-1] = 0;
+ TAILQ_INSERT_TAIL(&solib_list, solib, next);
+ break;
/* size of memory */
case 'm':
internal_config.memory = atoi(optarg);
@@ -794,6 +826,7 @@ rte_eal_init(int argc, char **argv)
int i, fctret, ret;
pthread_t thread_id;
static rte_atomic32_t run_once = RTE_ATOMIC32_INIT(0);
+ struct shared_driver *solib = NULL;
if (!rte_atomic32_test_and_set(&run_once))
return -1;
@@ -864,13 +897,25 @@ rte_eal_init(int argc, char **argv)
if (rte_eal_pci_init() < 0)
rte_panic("Cannot init PCI\n");
- RTE_LOG(DEBUG, EAL, "Master core %u is ready (tid=%x)\n",
- rte_config.master_lcore, (int)thread_id);
-
eal_check_mem_on_local_socket();
rte_eal_mcfg_complete();
+ TAILQ_FOREACH(solib, &solib_list, next) {
+ solib->lib_handle = dlopen(solib->name, RTLD_NOW);
+ if ((solib->lib_handle == NULL) && (solib->name[0] != '/')) {
+ /* relative path: try again with "./" prefix */
+ char sopath[PATH_MAX];
+ snprintf(sopath, sizeof(sopath), "./%s", solib->name);
+ solib->lib_handle = dlopen(sopath, RTLD_NOW);
+ }
+ if (solib->lib_handle == NULL)
+ RTE_LOG(WARNING, EAL, "%s\n", dlerror());
+ }
+
+ RTE_LOG(DEBUG, EAL, "Master core %u is ready (tid=%x)\n",
+ rte_config.master_lcore, (int)thread_id);
+
RTE_LCORE_FOREACH_SLAVE(i) {
/*
diff --git a/mk/exec-env/linuxapp/rte.vars.mk b/mk/exec-env/linuxapp/rte.vars.mk
index 92f30c0..311a21a 100644
--- a/mk/exec-env/linuxapp/rte.vars.mk
+++ b/mk/exec-env/linuxapp/rte.vars.mk
@@ -49,4 +49,9 @@ EXECENV_ASFLAGS =
# force applications to link with gcc/icc instead of using ld
LINK_USING_CC := 1
-export EXECENV_CFLAGS EXECENV_LDFLAGS EXECENV_ASFLAGS
+# For shared libraries
+EXECENV_LDFLAGS += -export-dynamic
+# Add library to the group to resolve symbols
+EXECENV_LDLIBS += -ldl
+
+export EXECENV_CFLAGS EXECENV_LDFLAGS EXECENV_ASFLAGS EXECENV_LDLIBS