Blame SOURCES/mlnx-dpdk-0002-net-mlx4-spawn-rdma-core-dependency-plug-in.patch

a6040a
From 1e6ab669d81e73ae7f4dead275d03e7f77ad76f7 Mon Sep 17 00:00:00 2001
a6040a
From: Adrien Mazarguil <adrien.mazarguil@6wind.com>
a6040a
Date: Tue, 30 Jan 2018 16:34:54 +0100
a6040a
Subject: [PATCH 2/9] net/mlx4: spawn rdma-core dependency plug-in
a6040a
a6040a
When mlx4 is not compiled directly as an independent shared object (e.g.
a6040a
CONFIG_RTE_BUILD_SHARED_LIB not enabled for performance reasons), DPDK
a6040a
applications inherit its dependencies on libibverbs and libmlx4 through
a6040a
rte.app.mk.
a6040a
a6040a
This is an issue both when DPDK is delivered as a binary package (Linux
a6040a
distributions) and for end users because rdma-core then propagates as a
a6040a
mandatory dependency for everything.
a6040a
a6040a
Application writers relying on binary DPDK packages are not necessarily
a6040a
aware of this fact and may end up delivering packages with broken
a6040a
dependencies.
a6040a
a6040a
This patch therefore introduces an intermediate internal plug-in
a6040a
hard-linked with rdma-core (to preserve symbol versioning) loaded by the
a6040a
PMD through dlopen(), so that a missing rdma-core does not cause unresolved
a6040a
symbols, allowing applications to start normally.
a6040a
a6040a
Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
a6040a
(cherry picked from commit 9e3391b98b6374e2796e0ae38dcce314efdc4f37)
a6040a
---
a6040a
 config/common_base        |  1 +
a6040a
 doc/guides/nics/mlx4.rst  | 13 +++++++++++++
a6040a
 drivers/net/mlx4/Makefile | 29 ++++++++++++++++++++++++++++
a6040a
 drivers/net/mlx4/mlx4.c   | 49 +++++++++++++++++++++++++++++++++++++++++++++++
a6040a
 mk/rte.app.mk             |  4 ++++
a6040a
 5 files changed, 96 insertions(+)
a6040a
a6040a
diff --git a/config/common_base b/config/common_base
a6040a
index e74febe..71a764c 100644
a6040a
--- a/config/common_base
a6040a
+++ b/config/common_base
a6040a
@@ -231,6 +231,7 @@ CONFIG_RTE_LIBRTE_FM10K_INC_VECTOR=y
a6040a
 CONFIG_RTE_LIBRTE_MLX4_PMD=n
a6040a
 CONFIG_RTE_LIBRTE_MLX4_DEBUG=n
a6040a
 CONFIG_RTE_LIBRTE_MLX4_DEBUG_BROKEN_VERBS=n
a6040a
+CONFIG_RTE_LIBRTE_MLX4_DLOPEN_DEPS=n
a6040a
 CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE=8
a6040a
 
a6040a
 #
a6040a
diff --git a/doc/guides/nics/mlx4.rst b/doc/guides/nics/mlx4.rst
a6040a
index 22341b9..5912722 100644
a6040a
--- a/doc/guides/nics/mlx4.rst
a6040a
+++ b/doc/guides/nics/mlx4.rst
a6040a
@@ -86,6 +86,19 @@ These options can be modified in the ``.config`` file.
a6040a
 
a6040a
   Toggle compilation of librte_pmd_mlx4 itself.
a6040a
 
a6040a
+- ``CONFIG_RTE_LIBRTE_MLX4_DLOPEN_DEPS`` (default **n**)
a6040a
+
a6040a
+  Build PMD with additional code to make it loadable without hard
a6040a
+  dependencies on **libibverbs** nor **libmlx4**, which may not be installed
a6040a
+  on the target system.
a6040a
+
a6040a
+  In this mode, their presence is still required for it to run properly,
a6040a
+  however their absence won't prevent a DPDK application from starting (with
a6040a
+  ``CONFIG_RTE_BUILD_SHARED_LIB`` disabled) and they won't show up as
a6040a
+  missing with ``ldd(1)``.
a6040a
+
a6040a
+  This option has no performance impact.
a6040a
+
a6040a
 - ``CONFIG_RTE_LIBRTE_MLX4_DEBUG`` (default **n**)
a6040a
 
a6040a
   Toggle debugging code and stricter compilation flags. Enabling this option
a6040a
diff --git a/drivers/net/mlx4/Makefile b/drivers/net/mlx4/Makefile
a6040a
index 7ba304b..60ee120 100644
a6040a
--- a/drivers/net/mlx4/Makefile
a6040a
+++ b/drivers/net/mlx4/Makefile
a6040a
@@ -33,12 +33,15 @@ include $(RTE_SDK)/mk/rte.vars.mk
a6040a
 
a6040a
 # Library name.
a6040a
 LIB = librte_pmd_mlx4.a
a6040a
+LIB_GLUE = librte_pmd_mlx4_glue.so
a6040a
 
a6040a
 # Sources.
a6040a
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4.c
a6040a
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_ethdev.c
a6040a
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_flow.c
a6040a
+ifneq ($(CONFIG_RTE_LIBRTE_MLX4_DLOPEN_DEPS),y)
a6040a
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_glue.c
a6040a
+endif
a6040a
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_intr.c
a6040a
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_mr.c
a6040a
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_rxq.c
a6040a
@@ -46,6 +49,10 @@ SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_rxtx.c
a6040a
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_txq.c
a6040a
 SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4_utils.c
a6040a
 
a6040a
+ifeq ($(CONFIG_RTE_LIBRTE_MLX4_DLOPEN_DEPS),y)
a6040a
+INSTALL-$(CONFIG_RTE_LIBRTE_MLX4_PMD)-lib += $(LIB_GLUE)
a6040a
+endif
a6040a
+
a6040a
 # Basic CFLAGS.
a6040a
 CFLAGS += -O3
a6040a
 CFLAGS += -std=c11 -Wall -Wextra
a6040a
@@ -55,7 +62,13 @@ CFLAGS += -D_BSD_SOURCE
a6040a
 CFLAGS += -D_DEFAULT_SOURCE
a6040a
 CFLAGS += -D_XOPEN_SOURCE=600
a6040a
 CFLAGS += $(WERROR_FLAGS)
a6040a
+ifeq ($(CONFIG_RTE_LIBRTE_MLX4_DLOPEN_DEPS),y)
a6040a
+CFLAGS += -DMLX4_GLUE='"$(LIB_GLUE)"'
a6040a
+CFLAGS_mlx4_glue.o += -fPIC
a6040a
+LDLIBS += -ldl
a6040a
+else
a6040a
 LDLIBS += -libverbs -lmlx4
a6040a
+endif
a6040a
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
a6040a
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
a6040a
 LDLIBS += -lrte_bus_pci
a6040a
@@ -113,7 +126,23 @@ mlx4_autoconf.h: mlx4_autoconf.h.new
a6040a
 
a6040a
 $(SRCS-$(CONFIG_RTE_LIBRTE_MLX4_PMD):.c=.o): mlx4_autoconf.h
a6040a
 
a6040a
+# Generate dependency plug-in for rdma-core when the PMD must not be linked
a6040a
+# directly, so that applications do not inherit this dependency.
a6040a
+
a6040a
+ifeq ($(CONFIG_RTE_LIBRTE_MLX4_DLOPEN_DEPS),y)
a6040a
+
a6040a
+$(LIB): $(LIB_GLUE)
a6040a
+
a6040a
+$(LIB_GLUE): mlx4_glue.o
a6040a
+	$Q $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) \
a6040a
+		-s -shared -o $@ $< -libverbs -lmlx4
a6040a
+
a6040a
+mlx4_glue.o: mlx4_autoconf.h
a6040a
+
a6040a
+endif
a6040a
+
a6040a
 clean_mlx4: FORCE
a6040a
 	$Q rm -f -- mlx4_autoconf.h mlx4_autoconf.h.new
a6040a
+	$Q rm -f -- mlx4_glue.o $(LIB_GLUE)
a6040a
 
a6040a
 clean: clean_mlx4
a6040a
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
a6040a
index 7f58e26..d12b00c 100644
a6040a
--- a/drivers/net/mlx4/mlx4.c
a6040a
+++ b/drivers/net/mlx4/mlx4.c
a6040a
@@ -37,6 +37,7 @@
a6040a
  */
a6040a
 
a6040a
 #include <assert.h>
a6040a
+#include <dlfcn.h>
a6040a
 #include <errno.h>
a6040a
 #include <inttypes.h>
a6040a
 #include <stddef.h>
a6040a
@@ -44,6 +45,7 @@
a6040a
 #include <stdio.h>
a6040a
 #include <stdlib.h>
a6040a
 #include <string.h>
a6040a
+#include <unistd.h>
a6040a
 
a6040a
 /* Verbs headers do not support -pedantic. */
a6040a
 #ifdef PEDANTIC
a6040a
@@ -55,6 +57,7 @@
a6040a
 #endif
a6040a
 
a6040a
 #include <rte_common.h>
a6040a
+#include <rte_config.h>
a6040a
 #include <rte_dev.h>
a6040a
 #include <rte_errno.h>
a6040a
 #include <rte_ethdev.h>
a6040a
@@ -701,6 +704,47 @@ struct mlx4_conf {
a6040a
 		     RTE_PCI_DRV_INTR_RMV,
a6040a
 };
a6040a
 
a6040a
+#ifdef RTE_LIBRTE_MLX4_DLOPEN_DEPS
a6040a
+
a6040a
+/**
a6040a
+ * Initialization routine for run-time dependency on rdma-core.
a6040a
+ */
a6040a
+static int
a6040a
+mlx4_glue_init(void)
a6040a
+{
a6040a
+	void *handle = NULL;
a6040a
+	void **sym;
a6040a
+	const char *dlmsg;
a6040a
+
a6040a
+	handle = dlopen(MLX4_GLUE, RTLD_LAZY);
a6040a
+	if (!handle) {
a6040a
+		rte_errno = EINVAL;
a6040a
+		dlmsg = dlerror();
a6040a
+		if (dlmsg)
a6040a
+			WARN("cannot load glue library: %s", dlmsg);
a6040a
+		goto glue_error;
a6040a
+	}
a6040a
+	sym = dlsym(handle, "mlx4_glue");
a6040a
+	if (!sym || !*sym) {
a6040a
+		rte_errno = EINVAL;
a6040a
+		dlmsg = dlerror();
a6040a
+		if (dlmsg)
a6040a
+			ERROR("cannot resolve glue symbol: %s", dlmsg);
a6040a
+		goto glue_error;
a6040a
+	}
a6040a
+	mlx4_glue = *sym;
a6040a
+	return 0;
a6040a
+glue_error:
a6040a
+	if (handle)
a6040a
+		dlclose(handle);
a6040a
+	WARN("cannot initialize PMD due to missing run-time"
a6040a
+	     " dependency on rdma-core libraries (libibverbs,"
a6040a
+	     " libmlx4)");
a6040a
+	return -rte_errno;
a6040a
+}
a6040a
+
a6040a
+#endif
a6040a
+
a6040a
 /**
a6040a
  * Driver initialization routine.
a6040a
  */
a6040a
@@ -715,6 +759,11 @@ struct mlx4_conf {
a6040a
 	 * using this PMD, which is not supported in forked processes.
a6040a
 	 */
a6040a
 	setenv("RDMAV_HUGEPAGES_SAFE", "1", 1);
a6040a
+#ifdef RTE_LIBRTE_MLX4_DLOPEN_DEPS
a6040a
+	if (mlx4_glue_init())
a6040a
+		return;
a6040a
+	assert(mlx4_glue);
a6040a
+#endif
a6040a
 	mlx4_glue->fork_init();
a6040a
 	rte_pci_register(&mlx4_driver);
a6040a
 }
a6040a
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
a6040a
index 6a6a745..6ececfe 100644
a6040a
--- a/mk/rte.app.mk
a6040a
+++ b/mk/rte.app.mk
a6040a
@@ -141,7 +141,11 @@ ifeq ($(CONFIG_RTE_LIBRTE_KNI),y)
a6040a
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_KNI)        += -lrte_pmd_kni
a6040a
 endif
a6040a
 _LDLIBS-$(CONFIG_RTE_LIBRTE_LIO_PMD)        += -lrte_pmd_lio
a6040a
+ifeq ($(CONFIG_RTE_LIBRTE_MLX4_DLOPEN_DEPS),y)
a6040a
+_LDLIBS-$(CONFIG_RTE_LIBRTE_MLX4_PMD)       += -lrte_pmd_mlx4 -ldl
a6040a
+else
a6040a
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX4_PMD)       += -lrte_pmd_mlx4 -libverbs -lmlx4
a6040a
+endif
a6040a
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD)       += -lrte_pmd_mlx5 -libverbs -lmlx5
a6040a
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MRVL_PMD)       += -lrte_pmd_mrvl -L$(LIBMUSDK_PATH)/lib -lmusdk
a6040a
 _LDLIBS-$(CONFIG_RTE_LIBRTE_NFP_PMD)        += -lrte_pmd_nfp
a6040a
-- 
a6040a
1.8.3.1
a6040a