[API-NEXT,PATCHv7,5/5] linux-gen: drv_drivers: loading modules from config file

Message ID 1483088953-30333-6-git-send-email-christophe.milard@linaro.org
State New
Headers show

Commit Message

Christophe Milard Dec. 30, 2016, 9:09 a.m.
The shared objects listed in the ODP configuration files are
loaded at init time. The odp configuration file list the
shared objects to be loaded as shown in the following example:
module = {
        modules = ["enumerator1.so", "driver1.so"];
};

Signed-off-by: Christophe Milard <christophe.milard@linaro.org>

---
 configure.ac                                  |  4 +--
 platform/linux-generic/drv_driver.c           | 41 +++++++++++++++++++++++++++
 platform/linux-generic/include/odp_internal.h |  3 ++
 platform/linux-generic/m4/configure.m4        |  1 +
 platform/linux-generic/m4/odp_drivers.m4      | 11 +++++++
 platform/linux-generic/odp_init.c             |  7 +++++
 6 files changed, 65 insertions(+), 2 deletions(-)
 create mode 100644 platform/linux-generic/m4/odp_drivers.m4

-- 
2.7.4

Comments

Anders Roxell Dec. 30, 2016, 10:35 a.m. | #1
On 2016-12-30 10:09, Christophe Milard wrote:
> The shared objects listed in the ODP configuration files are

> loaded at init time. The odp configuration file list the

> shared objects to be loaded as shown in the following example:

> module = {

>         modules = ["enumerator1.so", "driver1.so"];

> };

> 

> Signed-off-by: Christophe Milard <christophe.milard@linaro.org>

> ---

>  configure.ac                                  |  4 +--

>  platform/linux-generic/drv_driver.c           | 41 +++++++++++++++++++++++++++

>  platform/linux-generic/include/odp_internal.h |  3 ++

>  platform/linux-generic/m4/configure.m4        |  1 +

>  platform/linux-generic/m4/odp_drivers.m4      | 11 +++++++

>  platform/linux-generic/odp_init.c             |  7 +++++

>  6 files changed, 65 insertions(+), 2 deletions(-)

>  create mode 100644 platform/linux-generic/m4/odp_drivers.m4

> 

> diff --git a/configure.ac b/configure.ac

> index 3a20959..e2b4f9d 100644

> --- a/configure.ac

> +++ b/configure.ac

> @@ -55,7 +55,7 @@ AC_PROG_MAKE_SET

>  

>  AM_PROG_AR

>  #Use libtool

> -LT_INIT([])

> +LT_INIT([dlopen])

>  AC_SUBST([LIBTOOL_DEPS])

>  AM_PROG_LIBTOOL

>  

> @@ -66,7 +66,7 @@ AC_CHECK_FUNCS([bzero clock_gettime gethostbyname getpagesize gettimeofday memse

>  

>  # Checks for header files.

>  AC_HEADER_RESOLV

> -AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h limits.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h sys/ioctl.h sys/socket.h sys/time.h unistd.h])

> +AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h limits.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h sys/ioctl.h sys/socket.h sys/time.h unistd.h dlfcn.h])


Alphabetic order

>  

>  # Checks for typedefs, structures, and compiler characteristics.

>  AC_HEADER_STDBOOL

> diff --git a/platform/linux-generic/drv_driver.c b/platform/linux-generic/drv_driver.c

> index b3ec5af..29d9c47 100644

> --- a/platform/linux-generic/drv_driver.c

> +++ b/platform/linux-generic/drv_driver.c

> @@ -9,6 +9,8 @@

>  #include <odp/api/debug.h>

>  #include <odp_debug_internal.h>

>  #include <odp/drv/driver.h>

> +#include <libconfig.h>

> +#include <dlfcn.h>


Alphabetic order?

>  

>  int odpdrv_enumr_class_register(odpdrv_enumr_class_t *enumr_class)

>  {

> @@ -41,3 +43,42 @@ int odpdrv_driver_register(odpdrv_driver_t *driver)

>  

>  	return 0;

>  }

> +

 +static int load_modules(void)

load_modules vs. load_drivers?

If we want to load other modules except the "driver" module maybe we
need to move this code to a generic file?

> +{

> +	const config_setting_t *modules_section;

> +	const char *drv_name;


and change this to module_name

> +	int i;

> +	config_t *cf;

> +	int drv_count;


and module_count


Cheers,
Anders

Patch

diff --git a/configure.ac b/configure.ac
index 3a20959..e2b4f9d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -55,7 +55,7 @@  AC_PROG_MAKE_SET
 
 AM_PROG_AR
 #Use libtool
-LT_INIT([])
+LT_INIT([dlopen])
 AC_SUBST([LIBTOOL_DEPS])
 AM_PROG_LIBTOOL
 
@@ -66,7 +66,7 @@  AC_CHECK_FUNCS([bzero clock_gettime gethostbyname getpagesize gettimeofday memse
 
 # Checks for header files.
 AC_HEADER_RESOLV
-AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h limits.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h sys/ioctl.h sys/socket.h sys/time.h unistd.h])
+AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h limits.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h sys/ioctl.h sys/socket.h sys/time.h unistd.h dlfcn.h])
 
 # Checks for typedefs, structures, and compiler characteristics.
 AC_HEADER_STDBOOL
diff --git a/platform/linux-generic/drv_driver.c b/platform/linux-generic/drv_driver.c
index b3ec5af..29d9c47 100644
--- a/platform/linux-generic/drv_driver.c
+++ b/platform/linux-generic/drv_driver.c
@@ -9,6 +9,8 @@ 
 #include <odp/api/debug.h>
 #include <odp_debug_internal.h>
 #include <odp/drv/driver.h>
+#include <libconfig.h>
+#include <dlfcn.h>
 
 int odpdrv_enumr_class_register(odpdrv_enumr_class_t *enumr_class)
 {
@@ -41,3 +43,42 @@  int odpdrv_driver_register(odpdrv_driver_t *driver)
 
 	return 0;
 }
+
+static int load_modules(void)
+{
+	const config_setting_t *modules_section;
+	const char *drv_name;
+	int i;
+	config_t *cf;
+	int drv_count;
+
+	cf = &odp_global_data.configuration;
+	modules_section = config_lookup(cf, "module.modules");
+	if (!modules_section)
+		return 0;
+
+	drv_count = config_setting_length(modules_section);
+	if (!drv_count)
+		return 0;
+
+	for (i = 0; i < drv_count; i++) {
+		drv_name = config_setting_get_string_elem(modules_section, i);
+		if (dlopen(drv_name, RTLD_NOW) == NULL) {
+			ODP_ERR("dlopen failed for %s: %s\n",
+				drv_name, dlerror());
+			return -1;
+		}
+		ODP_DBG("module %s loaded.\n", drv_name);
+	}
+
+	return 0;
+}
+
+int _odpdrv_driver_init_global(void)
+{
+	/* load modules (enumerator and drivers...) */
+	if (load_modules())
+		return -1;
+
+	return 0;
+}
diff --git a/platform/linux-generic/include/odp_internal.h b/platform/linux-generic/include/odp_internal.h
index 9d1fc58..9d12ff8 100644
--- a/platform/linux-generic/include/odp_internal.h
+++ b/platform/linux-generic/include/odp_internal.h
@@ -71,6 +71,7 @@  enum init_stage {
 	CLASSIFICATION_INIT,
 	TRAFFIC_MNGR_INIT,
 	NAME_TABLE_INIT,
+	DRIVER_INIT,
 	ALL_INIT      /* All init stages completed */
 };
 
@@ -129,6 +130,8 @@  int _odp_ishm_init_local(void);
 int _odp_ishm_term_global(void);
 int _odp_ishm_term_local(void);
 
+int _odpdrv_driver_init_global(void);
+
 int cpuinfo_parser(FILE *file, system_info_t *sysinfo);
 uint64_t odp_cpu_hz_current(int id);
 
diff --git a/platform/linux-generic/m4/configure.m4 b/platform/linux-generic/m4/configure.m4
index 5fab0cc..96bec46 100644
--- a/platform/linux-generic/m4/configure.m4
+++ b/platform/linux-generic/m4/configure.m4
@@ -46,6 +46,7 @@  m4_include([platform/linux-generic/m4/odp_netmap.m4])
 m4_include([platform/linux-generic/m4/odp_dpdk.m4])
 m4_include([platform/linux-generic/m4/odp_ipc.m4])
 m4_include([platform/linux-generic/m4/odp_schedule.m4])
+m4_include([platform/linux-generic/m4/odp_drivers.m4])
 
 AC_CONFIG_FILES([platform/linux-generic/Makefile
                  platform/linux-generic/include/odp/api/plat/static_inline.h])
diff --git a/platform/linux-generic/m4/odp_drivers.m4 b/platform/linux-generic/m4/odp_drivers.m4
new file mode 100644
index 0000000..03f61f8
--- /dev/null
+++ b/platform/linux-generic/m4/odp_drivers.m4
@@ -0,0 +1,11 @@ 
+##########################################################################
+# Check for dlopen and lt equivalent availability
+##########################################################################
+
+AC_SEARCH_LIBS([dlopen], [dl dld],
+    [
+       AM_LDFLAGS="$AM_LDFLAGS -ldl"
+    ],
+    [
+       AC_MSG_ERROR([Error! dlopen not available!])
+    ])
diff --git a/platform/linux-generic/odp_init.c b/platform/linux-generic/odp_init.c
index bd43af1..9af4181 100644
--- a/platform/linux-generic/odp_init.c
+++ b/platform/linux-generic/odp_init.c
@@ -248,6 +248,12 @@  int odp_init_global(odp_instance_t *instance,
 		ODP_ERR("ODP name table init failed\n");
 		goto init_failed;
 	}
+	stage = NAME_TABLE_INIT;
+
+	if (_odpdrv_driver_init_global()) {
+		ODP_ERR("ODP drivers init failed\n");
+		goto init_failed;
+	}
 
 	*instance = (odp_instance_t)odp_global_data.main_pid;
 
@@ -273,6 +279,7 @@  int _odp_term_global(enum init_stage stage)
 
 	switch (stage) {
 	case ALL_INIT:
+	case DRIVER_INIT:
 	case NAME_TABLE_INIT:
 		if (_odp_int_name_tbl_term_global()) {
 			ODP_ERR("Name table term failed.\n");