Signed-off-by: Bogdan Pricope <bogdan.pric...@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
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 -- 1.9.1