Blame SOURCES/mlnx-dpdk-0004-net-mlx5-spawn-rdma-core-dependency-plug-in.patch

a6040a
From bf3bf80e901e5d47803c5ffc53f00077a7c72ac6 Mon Sep 17 00:00:00 2001
a6040a
From: Adrien Mazarguil <adrien.mazarguil@6wind.com>
a6040a
Date: Tue, 30 Jan 2018 16:34:58 +0100
a6040a
Subject: [PATCH 4/9] net/mlx5: spawn rdma-core dependency plug-in
a6040a
a6040a
When mlx5 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 libmlx5 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 fdf5165b0c44d0b7fd33c78d7a5b8ead6cca6329)
a6040a
---
a6040a
 config/common_base        |  1 +
a6040a
 doc/guides/nics/mlx5.rst  | 13 +++++++++++++
a6040a
 drivers/net/mlx5/Makefile | 31 +++++++++++++++++++++++++++++-
a6040a
 drivers/net/mlx5/mlx5.c   | 48 +++++++++++++++++++++++++++++++++++++++++++++++
a6040a
 mk/rte.app.mk             |  4 ++++
a6040a
 5 files changed, 96 insertions(+), 1 deletion(-)
a6040a
a6040a
diff --git a/config/common_base b/config/common_base
a6040a
index 71a764c..9da57bd 100644
a6040a
--- a/config/common_base
a6040a
+++ b/config/common_base
a6040a
@@ -239,6 +239,7 @@ CONFIG_RTE_LIBRTE_MLX4_TX_MP_CACHE=8
a6040a
 #
a6040a
 CONFIG_RTE_LIBRTE_MLX5_PMD=n
a6040a
 CONFIG_RTE_LIBRTE_MLX5_DEBUG=n
a6040a
+CONFIG_RTE_LIBRTE_MLX5_DLOPEN_DEPS=n
a6040a
 CONFIG_RTE_LIBRTE_MLX5_TX_MP_CACHE=8
a6040a
 
a6040a
 #
a6040a
diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
a6040a
index f9558da..6ee4a47 100644
a6040a
--- a/doc/guides/nics/mlx5.rst
a6040a
+++ b/doc/guides/nics/mlx5.rst
a6040a
@@ -146,6 +146,19 @@ These options can be modified in the ``.config`` file.
a6040a
 
a6040a
   Toggle compilation of librte_pmd_mlx5 itself.
a6040a
 
a6040a
+- ``CONFIG_RTE_LIBRTE_MLX5_DLOPEN_DEPS`` (default **n**)
a6040a
+
a6040a
+  Build PMD with additional code to make it loadable without hard
a6040a
+  dependencies on **libibverbs** nor **libmlx5**, 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_MLX5_DEBUG`` (default **n**)
a6040a
 
a6040a
   Toggle debugging code and stricter compilation flags. Enabling this option
a6040a
diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile
a6040a
index bdec306..4b20d71 100644
a6040a
--- a/drivers/net/mlx5/Makefile
a6040a
+++ b/drivers/net/mlx5/Makefile
a6040a
@@ -33,9 +33,13 @@ include $(RTE_SDK)/mk/rte.vars.mk
a6040a
 
a6040a
 # Library name.
a6040a
 LIB = librte_pmd_mlx5.a
a6040a
+LIB_GLUE = librte_pmd_mlx5_glue.so
a6040a
 
a6040a
 # Sources.
a6040a
 SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5.c
a6040a
+ifneq ($(CONFIG_RTE_LIBRTE_MLX5_DLOPEN_DEPS),y)
a6040a
+SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_glue.c
a6040a
+endif
a6040a
 SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_rxq.c
a6040a
 SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_txq.c
a6040a
 SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_rxtx.c
a6040a
@@ -53,7 +57,10 @@ SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_rss.c
a6040a
 SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_mr.c
a6040a
 SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_flow.c
a6040a
 SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_socket.c
a6040a
-SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_glue.c
a6040a
+
a6040a
+ifeq ($(CONFIG_RTE_LIBRTE_MLX5_DLOPEN_DEPS),y)
a6040a
+INSTALL-$(CONFIG_RTE_LIBRTE_MLX5_PMD)-lib += $(LIB_GLUE)
a6040a
+endif
a6040a
 
a6040a
 # Basic CFLAGS.
a6040a
 CFLAGS += -O3
a6040a
@@ -65,7 +72,13 @@ CFLAGS += -D_DEFAULT_SOURCE
a6040a
 CFLAGS += -D_XOPEN_SOURCE=600
a6040a
 CFLAGS += $(WERROR_FLAGS)
a6040a
 CFLAGS += -Wno-strict-prototypes
a6040a
+ifeq ($(CONFIG_RTE_LIBRTE_MLX5_DLOPEN_DEPS),y)
a6040a
+CFLAGS += -DMLX5_GLUE='"$(LIB_GLUE)"'
a6040a
+CFLAGS_mlx5_glue.o += -fPIC
a6040a
+LDLIBS += -ldl
a6040a
+else
a6040a
 LDLIBS += -libverbs -lmlx5
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
@@ -158,7 +171,23 @@ mlx5_autoconf.h: mlx5_autoconf.h.new
a6040a
 
a6040a
 $(SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD):.c=.o): mlx5_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_MLX5_DLOPEN_DEPS),y)
a6040a
+
a6040a
+$(LIB): $(LIB_GLUE)
a6040a
+
a6040a
+$(LIB_GLUE): mlx5_glue.o
a6040a
+	$Q $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) \
a6040a
+		-s -shared -o $@ $< -libverbs -lmlx5
a6040a
+
a6040a
+mlx5_glue.o: mlx5_autoconf.h
a6040a
+
a6040a
+endif
a6040a
+
a6040a
 clean_mlx5: FORCE
a6040a
 	$Q rm -f -- mlx5_autoconf.h mlx5_autoconf.h.new
a6040a
+	$Q rm -f -- mlx5_glue.o $(LIB_GLUE)
a6040a
 
a6040a
 clean: clean_mlx5
a6040a
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
a6040a
index f77bdda..71ebdce 100644
a6040a
--- a/drivers/net/mlx5/mlx5.c
a6040a
+++ b/drivers/net/mlx5/mlx5.c
a6040a
@@ -35,6 +35,7 @@
a6040a
 #include <unistd.h>
a6040a
 #include <string.h>
a6040a
 #include <assert.h>
a6040a
+#include <dlfcn.h>
a6040a
 #include <stdint.h>
a6040a
 #include <stdlib.h>
a6040a
 #include <errno.h>
a6040a
@@ -56,6 +57,7 @@
a6040a
 #include <rte_pci.h>
a6040a
 #include <rte_bus_pci.h>
a6040a
 #include <rte_common.h>
a6040a
+#include <rte_config.h>
a6040a
 #include <rte_kvargs.h>
a6040a
 
a6040a
 #include "mlx5.h"
a6040a
@@ -1023,6 +1025,47 @@ struct mlx5_args {
a6040a
 	.drv_flags = RTE_PCI_DRV_INTR_LSC | RTE_PCI_DRV_INTR_RMV,
a6040a
 };
a6040a
 
a6040a
+#ifdef RTE_LIBRTE_MLX5_DLOPEN_DEPS
a6040a
+
a6040a
+/**
a6040a
+ * Initialization routine for run-time dependency on rdma-core.
a6040a
+ */
a6040a
+static int
a6040a
+mlx5_glue_init(void)
a6040a
+{
a6040a
+	void *handle = NULL;
a6040a
+	void **sym;
a6040a
+	const char *dlmsg;
a6040a
+
a6040a
+	handle = dlopen(MLX5_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, "mlx5_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
+	mlx5_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
+	     " libmlx5)");
a6040a
+	return -rte_errno;
a6040a
+}
a6040a
+
a6040a
+#endif
a6040a
+
a6040a
 /**
a6040a
  * Driver initialization routine.
a6040a
  */
a6040a
@@ -1042,6 +1085,11 @@ struct mlx5_args {
a6040a
 	/* Match the size of Rx completion entry to the size of a cacheline. */
a6040a
 	if (RTE_CACHE_LINE_SIZE == 128)
a6040a
 		setenv("MLX5_CQE_SIZE", "128", 0);
a6040a
+#ifdef RTE_LIBRTE_MLX5_DLOPEN_DEPS
a6040a
+	if (mlx5_glue_init())
a6040a
+		return;
a6040a
+	assert(mlx5_glue);
a6040a
+#endif
a6040a
 	mlx5_glue->fork_init();
a6040a
 	rte_pci_register(&mlx5_driver);
a6040a
 }
a6040a
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
a6040a
index 6ececfe..200fa40 100644
a6040a
--- a/mk/rte.app.mk
a6040a
+++ b/mk/rte.app.mk
a6040a
@@ -146,7 +146,11 @@ _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
+ifeq ($(CONFIG_RTE_LIBRTE_MLX5_DLOPEN_DEPS),y)
a6040a
+_LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD)       += -lrte_pmd_mlx5 -ldl
a6040a
+else
a6040a
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD)       += -lrte_pmd_mlx5 -libverbs -lmlx5
a6040a
+endif
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
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL)       += -lrte_pmd_null
a6040a
-- 
a6040a
1.8.3.1
a6040a