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

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