diff mbox

[RFCv2] ddf: example: build module with dpdk support

Message ID 1498745377-2501-2-git-send-email-bogdan.pricope@linaro.org
State New
Headers show

Commit Message

Bogdan Pricope June 29, 2017, 2:09 p.m. UTC
Signed-off-by: Bogdan Pricope <bogdan.pricope@linaro.org>

---
 example/ddf_app/odp_ddf_app.c        |  14 +++-
 example/ddf_ifs/Makefile.am          |   9 ++-
 example/ddf_ifs/ddf_ifs_enumr_dpdk.c | 126 ++++++++++++++++++++++++++++++++++-
 example/m4/configure.m4              |   2 +
 example/m4/example_dpdk.m4           |  43 ++++++++++++
 scripts/build-example-ddf-dpdk       |  33 +++++++++
 6 files changed, 223 insertions(+), 4 deletions(-)
 create mode 100644 example/m4/example_dpdk.m4
 create mode 100755 scripts/build-example-ddf-dpdk

-- 
1.9.1
diff mbox

Patch

diff --git a/example/ddf_app/odp_ddf_app.c b/example/ddf_app/odp_ddf_app.c
index af864ee..18c6994 100644
--- a/example/ddf_app/odp_ddf_app.c
+++ b/example/ddf_app/odp_ddf_app.c
@@ -20,9 +20,12 @@ 
 int main(int argc, char *argv[])
 {
 	odp_instance_t instance;
+	odp_pktio_t pktio = ODP_PKTIO_INVALID;
 
-	(void)argc;
-	(void)argv;
+	if (argc == 1 || argc > 2) {
+		printf("Error: invalid parameter.\nUsage:\n\t%s <interface>\n", argv[0]);
+		exit(0);
+	}
 
 	EXAMPLE_DBG("Start DDF Application...\n");
 
@@ -40,6 +43,13 @@  int main(int argc, char *argv[])
 	/* Print ddf objects*/
 	odpdrv_print_all();
 
+	/* Open pktio*/
+	/*odp_pktio_open();*/
+
+	/* Close pktio*/
+	if (odp_pktio_close(pktio))
+		EXAMPLE_ERR("Error: Failed to close pktio \"%s\".\n", argv[1]);
+
 	/* Terminate ODP */
 	odp_term_local();
 	odp_term_global(instance);
diff --git a/example/ddf_ifs/Makefile.am b/example/ddf_ifs/Makefile.am
index aa892ac..77e56e6 100644
--- a/example/ddf_ifs/Makefile.am
+++ b/example/ddf_ifs/Makefile.am
@@ -3,7 +3,14 @@  LIB   = $(top_builddir)/lib
 AM_CPPFLAGS +=  -I$(srcdir) \
 		-I$(top_srcdir)/include \
 		-I$(top_srcdir)/platform/@with_platform@/include \
-		-I$(top_srcdir)/platform/@with_platform@/arch/@ARCH_DIR@
+		-I$(top_srcdir)/platform/@with_platform@/arch/@ARCH_DIR@ \
+		-I$(top_srcdir)/include/odp/arch/@ARCH_ABI@ \
+		-I$(top_builddir)/include
+
+if EXAMPLE_DPDK_SUPPORT 
+AM_CPPFLAGS += @EXAMPLE_DPDK_CPPFLAGS@
+AM_LDFLAGS += @EXAMPLE_DPDK_LDFLAGS@
+endif
 
 lib_LTLIBRARIES = $(LIB)/libddf_ifs.la
 
diff --git a/example/ddf_ifs/ddf_ifs_enumr_dpdk.c b/example/ddf_ifs/ddf_ifs_enumr_dpdk.c
index 782f7b7..25585dc 100644
--- a/example/ddf_ifs/ddf_ifs_enumr_dpdk.c
+++ b/example/ddf_ifs/ddf_ifs_enumr_dpdk.c
@@ -4,12 +4,27 @@ 
  * SPDX-License-Identifier:     BSD-3-Clause
  */
 
+#include <odp_posix_extensions.h>
+
 #include <stdio.h>
+#include <sched.h>
+#include <ctype.h>
+#include <unistd.h>
+
 #include "odp_drv.h"
 #include "ddf_ifs_api.h"
 #include "ddf_ifs_enumr_dpdk.h"
 #include "ddf_ifs_dev_dpdk.h"
 
+/*#include <odp_debug_internal.h>*/
+
+#include <protocols/eth.h>
+
+#include <rte_config.h>
+#include <rte_mbuf.h>
+#include <rte_ethdev.h>
+#include <rte_string_fns.h>
+
 static odpdrv_enumr_t dpdk_enumr;
 
 #define TEST_DPDK_DEV_CNT 3
@@ -17,6 +32,106 @@  static odpdrv_enumr_t dpdk_enumr;
 
 static odpdrv_device_t dpdk_dev[DDF_DPDK_DEV_MAX];
 static int dpdk_dev_cnt;
+
+#define DPDK_MEMORY_MB 512
+static int dpdk_pktio_init(void)
+{
+	int dpdk_argc;
+	int i;
+	odp_cpumask_t mask;
+	char mask_str[ODP_CPUMASK_STR_SIZE];
+	const char *cmdline;
+	int32_t masklen;
+	int mem_str_len;
+	int cmd_len;
+	cpu_set_t original_cpuset;
+	struct rte_config *cfg;
+
+	/**
+	 * DPDK init changes the affinity of the calling thread, so after it
+	 * returns the original affinity is restored. Only the first active
+	 * core is passed to rte_eal_init(), as the rest would be used for
+	 * DPDK's special lcore threads, which are only available through
+	 * rte_eal_[mp_]remote_launch(), but not through ODP API's.
+	 * Nevertheless, odp_local_init() makes sure for the rest of
+	 * the DPDK libraries ODP threads look like proper DPDK threads.
+	 */
+	CPU_ZERO(&original_cpuset);
+	i = pthread_getaffinity_np(pthread_self(),
+				   sizeof(original_cpuset), &original_cpuset);
+	if (i != 0) {
+		printf("Failed to read thread affinity: %d\n", i);
+		return -1;
+	}
+
+	odp_cpumask_zero(&mask);
+	for (i = 0; i < CPU_SETSIZE; i++) {
+		if (CPU_ISSET(i, &original_cpuset)) {
+			odp_cpumask_set(&mask, i);
+			break;
+		}
+	}
+	masklen = odp_cpumask_to_str(&mask, mask_str, ODP_CPUMASK_STR_SIZE);
+
+	if (masklen < 0) {
+		printf("CPU mask error: %d\n", masklen);
+		return -1;
+	}
+
+	mem_str_len = snprintf(NULL, 0, "%d", DPDK_MEMORY_MB);
+
+	cmdline = getenv("ODP_PKTIO_DPDK_PARAMS");
+	if (cmdline == NULL)
+		cmdline = "";
+
+	/* masklen includes the terminating null as well */
+	cmd_len = strlen("ddfdpdk -c -m ") + masklen + mem_str_len +
+			strlen(cmdline) + strlen("  ");
+
+	char full_cmd[cmd_len];
+
+	/* first argument is facility log, simply bind it to odpdpdk for now.*/
+	cmd_len = snprintf(full_cmd, cmd_len, "ddfdpdk -c %s -m %d %s",
+			   mask_str, DPDK_MEMORY_MB, cmdline);
+
+	for (i = 0, dpdk_argc = 1; i < cmd_len; ++i) {
+		if (isspace(full_cmd[i]))
+			++dpdk_argc;
+	}
+
+	char *dpdk_argv[dpdk_argc];
+
+	dpdk_argc = rte_strsplit(full_cmd, strlen(full_cmd), dpdk_argv,
+				 dpdk_argc, ' ');
+	for (i = 0; i < dpdk_argc; ++i)
+		printf("arg[%d]: %s\n", i, dpdk_argv[i]);
+
+	i = rte_eal_init(dpdk_argc, dpdk_argv);
+
+	if (i < 0) {
+		printf("Cannot init the Intel DPDK EAL!\n");
+		return -1;
+	} else if (i + 1 != dpdk_argc) {
+		printf("Some DPDK args were not processed!\n");
+		printf("Passed: %d Consumed %d\n", dpdk_argc, i + 1);
+	}
+	printf("rte_eal_init OK\n");
+
+	rte_set_log_level(RTE_LOG_WARNING);
+
+	i = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t),
+				   &original_cpuset);
+	if (i)
+		printf("Failed to reset thread affinity: %d\n", i);
+
+	cfg = rte_eal_get_configuration();
+	for (i = 0; i < RTE_MAX_LCORE; i++)
+		cfg->lcore_role[i] = ROLE_RTE;
+
+	return 0;
+}
+
+
 static int dpdk_enumr_probe(void)
 {
 	int dpdk_dev_cnt_detected = TEST_DPDK_DEV_CNT; /* detected with
@@ -24,7 +139,16 @@  static int dpdk_enumr_probe(void)
 	char dev_addr[ODPDRV_NAME_ADDR_SZ];
 	int i;
 
-	printf("%s() - %d devices found\n", __func__, dpdk_dev_cnt_detected);
+	printf("%s()\n", __func__);
+
+	if (dpdk_pktio_init()) {
+		printf("Failed to initialize dpdk\n");
+		return -1;
+	}
+
+	printf("(Real) Detected DPDK devices: %d\n", rte_eth_dev_count());
+
+	printf("%d devices found\n", dpdk_dev_cnt_detected);
 
 	if (dpdk_dev_cnt_detected > DDF_DPDK_DEV_MAX) {
 		dpdk_dev_cnt_detected = DDF_DPDK_DEV_MAX;
diff --git a/example/m4/configure.m4 b/example/m4/configure.m4
index 270aa89..bb2eb43 100644
--- a/example/m4/configure.m4
+++ b/example/m4/configure.m4
@@ -10,6 +10,8 @@  AC_ARG_ENABLE([test-example],
         test_example=no
     fi])
 
+m4_include([example/m4/example_dpdk.m4])
+
 AC_CONFIG_FILES([example/classifier/Makefile
 		 example/generator/Makefile
 		 example/hello/Makefile
diff --git a/example/m4/example_dpdk.m4 b/example/m4/example_dpdk.m4
new file mode 100644
index 0000000..1a12187
--- /dev/null
+++ b/example/m4/example_dpdk.m4
@@ -0,0 +1,43 @@ 
+##########################################################################
+# Enable DPDK support
+##########################################################################
+example_dpdk_support=no
+AC_ARG_WITH([example-dpdk-path],
+AC_HELP_STRING([--with-example-dpdk-path=DIR   path to dpdk build directory]),
+    [DPDK_PATH=$withval
+    example_dpdk_support=yes],[])
+
+##########################################################################
+# Save and set temporary compilation flags
+##########################################################################
+OLD_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$AM_CPPFLAGS $CPPFLAGS"
+
+##########################################################################
+# Check for DPDK availability
+#
+# DPDK pmd drivers are not linked unless the --whole-archive option is
+# used. No spaces are allowed between the --whole-arhive flags.
+##########################################################################
+if test x$example_dpdk_support = xyes
+then
+    EXAMPLE_DPDK_CPPFLAGS="-msse4.2 -isystem $DPDK_PATH/include"
+
+    CPPFLAGS="$EXAMPLE_DPDK_CPPFLAGS $CPPFLAGS"
+    AC_CHECK_HEADERS([rte_config.h], [],
+        [AC_MSG_FAILURE(["can't find DPDK header"])])
+
+    EXAMPLE_DPDK_LDFLAGS="-L$DPDK_PATH/lib -Wl,--no-as-needed,-ldpdk,--as-needed -ldl -lm -lpcap"
+else
+    example_dpdk_support=no
+    EXAMPLE_DPDK_CPPFLAGS=""
+    EXAMPLE_DPDK_LDFLAGS=""
+fi
+
+AM_CONDITIONAL([EXAMPLE_DPDK_SUPPORT], [test x$example_dpdk_support = xyes ])
+AC_SUBST(EXAMPLE_DPDK_CPPFLAGS)
+AC_SUBST(EXAMPLE_DPDK_LDFLAGS)
+##########################################################################
+# Restore old saved variables
+##########################################################################
+CPPFLAGS=$OLD_CPPFLAGS
diff --git a/scripts/build-example-ddf-dpdk b/scripts/build-example-ddf-dpdk
new file mode 100755
index 0000000..dbcd49a
--- /dev/null
+++ b/scripts/build-example-ddf-dpdk
@@ -0,0 +1,33 @@ 
+#!/bin/bash
+
+TARGET=${TARGET:-"x86_64-native-linuxapp-gcc"}
+
+export ROOT_DIR=$(readlink -e $(dirname $0) | sed 's|/scripts||')
+pushd ${ROOT_DIR}
+
+echo '#include "pcap.h"' | cpp -H -o /dev/null 2>&1
+if [ "$?" != "0" ]; then
+	echo "Error: pcap is not installed. You may need to install libpcap-dev"
+fi
+
+git -c advice.detachedHead=false clone -q --depth=1 --single-branch --branch=v17.02 http://dpdk.org/git/dpdk dpdk
+pushd dpdk
+git log --oneline --decorate
+
+#Make and edit DPDK configuration
+make config T=${TARGET} O=${TARGET}
+pushd ${TARGET}
+#To use I/O without DPDK supported NIC's enable pcap pmd:
+sed -ri 's,(CONFIG_RTE_LIBRTE_PMD_PCAP=).*,\1y,' .config
+sed -ri 's,(CONFIG_RTE_BUILD_SHARED_LIB=).*,\1y,' .config
+popd
+
+#Build DPDK
+make install T=${TARGET} EXTRA_CFLAGS="-fPIC"
+popd
+
+#Build ODP
+./bootstrap;
+./configure  --enable-debug --enable-debug-print \
+	     --with-example-dpdk-path=`pwd`/dpdk/${TARGET}
+make